top of page

Developing Azure Functions using PnP PowerShell in VS Code

  • Writer: Kasper Larsen
    Kasper Larsen
  • Jun 8
  • 2 min read

I have been using Azure Functions to extend various Site/Group/Teams provisioning engines for years, and have picked up a few useful habits:



Use Managed Identities!

Ever since Managed Identities became an option with Azure Functions and Azure Automation Runbooks then that has been the preferred option in most cases. Optimal security and no certs that will expire the day after you leave for a two months' vacation in the most remote region on Earth.


As these Azure Functions are being used in a number of provisioning engines, I must support both System Assigned and User Assigned Managed Identities.


Did you know that you can develop and debug your Azure Functions within VS Code? Yes, locally on your PC, not in the Portal.


However, you cannot connect using a Managed Identity when you are not in Azure, so you will have to use a certificate for the local development.


I am sure that some of the smart people out there have figured out a very clever way to Auth in each of the cases, but someone might find mine useful too.


In each Azure Function I include this function:


function Get-PnPConnection 
{
    [CmdletBinding()]
    param(
        [Parameter(Mandatory = $true)]
        [string]$siteUrl
    )
    try
    {
        $ClientId = $env:ClientId
        $thumbprint = $env:thumbprint   
        $userAssignedManagedIdentityClientId = $env:UserAssignedManagedIdentityClientId

        if($ClientId -and $ClientId -ne "")
        {
            $body += "Using ClientId and Thumbprint"
            return Connect-PnPOnline -Url $siteUrl -ClientId $ClientId -Thumbprint $thumbprint -Tenant "tcwlv.onmicrosoft.com" -ReturnConnection -ErrorAction Stop
        }
        else
        {
            if($null -eq $userAssignedManagedIdentityClientId)
            {
                $body += "Using System Assigned Managed Identity"
                return Connect-PnPOnline -Url $siteUrl -ManagedIdentity -ReturnConnection -ErrorAction Stop
            }
            else
            {
                $body += "Using Managed Identity and UserAssignedManagedIdentityClientId $userAssignedManagedIdentityClientId"
                return Connect-PnPOnline -Url $siteUrl -ManagedIdentity -UserAssignedManagedIdentityClientId $userAssignedManagedIdentityClientId -ReturnConnection -ErrorAction Stop
            }
        }
    }
    catch
    {
        $body += "Exception $($_.Exception.Message)"
        throw
    }
}

It is pretty simple, just the way I like it.

I am relying on getting a number of property values from the Azure Function Settings.

If the property ClientId contains a value than we should Auth using ClientId and Thumbprint

If not, then check if the UserAssignedManagedIdentityClientId contains a value. If that is the case, then we are connecting to a User Assigned Managed Identity.

If not, then that last option is to connect using a System Assigned Managed Identity



This enables me to get a connection to a specific site and do whatever the Function is expected to do without thinking about which Auth method I am using, just call Get-PnPConnection and specify the site URL and I will get a connection :-). Here adding some Site scoped feature:

$localConn = Get-PnPConnection -siteUrl $siteUrl
$feature = "3bae86a2-776d-499d-9db8-fa4cdc7884f8"
enable-pnpfeature -Scope Site -Identity $feature -connection $localConn 

PS, I guess I could extract Get-PnPConnection into a new module and just reference that module in the Function, rather than having the function in each Function. I might look into that someday.

 
 
 

Comments


30103817

  • Twitter
  • LinkedIn

©2023 by M365thinking. Proudly created with Wix.com

bottom of page