How to use PnP PowerShell on Azure Functions with application permissions
Last updated on November 3, 2024
Whenever I’ve previously instructed other developers on how to use the PnP.PowerShell module on Azure function apps with application permissions, I’ve often found myself referencing a subsection of an article I’ve previously written with some modifications. After doing it a few times, I figured the instructions would be easier to follow if I included only the required steps in a separate article. So, here we are. In addition, the steps detailed in this article are more generalized instead of focusing on the original specific scenario.
In this article, I’ll present you two ways of authenticating to SharePoint Online with PnP PowerShell using application permissions:
- Using the Azure function system-managed identity (recommended)
- Using a self-signed certificate
Table of Contents
- Create an Azure Function App
- Add PnP.PowerShell to the required modules to load
- Enable the Function App’s Managed Identity
- Authenticating with the Azure Function managed identity
- Authenticating with a self-signed certificate
Create an Azure Function App
Let’s start by going to Azure Portal and creating a resource group and a function app. I’m assuming you have an Azure subscription set up at this point (hence I won’t give you instructions for creating one).
First, let’s create the resource group.
- Create a new resource group in your subscription with a descriptive name (adhere to your company’s naming conventions) and a region near you.
- You can optionally add tags. Otherwise, click Review + create.
After the resource group has been deployed, navigate to it and click the big blue Create a resource button.
- Search for Function App on the Marketplace. When you find it, click on Create.
- Ensure the correct subscription and the resource group you created earlier are selected.
- Give your function app a name (according to your organization’s naming conventions). This will also function as the URL prefix.
- Choose to publish your solution as Code.
- Select PowerShell Core as the runtime stack, and the latest version.
- Change the Region to the same one you chose when creating the resource group.
- Leave the Operating system to Windows and Plan type to Consumption.
- Go to the Hosting tab, click on Create new and rename the storage account according to your organization’s naming conventions.
- Go to the Monitoring tab, click on Create new and rename the application insights resource (and a new workspace) according to your organization’s naming conventions.
- You may optionally tag the resource. Otherwise, click Review + create.
Add PnP.PowerShell to the required modules to load
We’ll also be using the version 2 of PnP PowerShell Core which supports the managed identity authentication to SharePoint Online. If your script is still using version 1, I highly recommend updating your script to use the version 2 instead.
- Go to the Function App resource in Azure Portal.
- Open the App files blade.
- Select requirements.psd1 from the dropdown.
- Add a reference to the PnP.PowerShell module. The managed identity authentication requires version 2 of PnP.PowerShell while authentication with a certificate is also possible in version 1.
- Managed identity authentication also requires Azure modules, namely the Az.Accounts and Az.ManagedServiceIdentity modules. I recommend installing these two Azure PowerShell modules (and other possible Az modules required by your script) explicitly instead of installing the entire Az module collection because the latter takes a really long time and results in a lot of hassle when it comes to installing the dependencies for the first time (namely, the function timeouts on a consumption plan). The file should now look something like the one below.
- Remember to Save the changes.
If you are going to be authenticating with a certificate and do NOT need to use any Azure modules in your function script, you need to do the following; otherwise, your script will produce an error.
- Still on the App files blade, select profile.ps1 from the dropdown.
- Comment out the four lines of code. After that, there should not be executable code present in the file.
- Remember to Save the changes.
Enable the Function App’s Managed Identity
Now, we need to enable the function app’s system managed identity. We can either use this identity directly for authentication, or alternatively use it to fetch the certificate for authentication from an Azure Key Vault. Either way, the managed identity always needs to be enabled.
- Open the Identity blade
- Change the system assigned managed identity Status to On.
- Click on Save and Yes when prompted
- Copy the Object ID that appears upon saving to, e.g., Notepad. You’ll need this later.
Authenticating with the Azure Function managed identity
Today, PnP.PowerShell supports authenticating to SharePoint Online with Azure managed identities. I highly recommend you use this approach whenever possible instead of setting up a certificate. Configuring certificate authentication requires additional effort and the method is not as secure as using a managed identity because it is always possible that the certificate may get leaked.
Grant the managed identity permissions to SharePoint Online
Run the script below to assign the managed identity the minimum permissions required by the operation(s) you wish to execute on the SharePoint Online API. The user executing the script needs to have either Application administrator, Cloud application administrator or Global administrator role. Note: you may need to assign other permissions depending on what you want to do via PnP.PowerShell. This is just an example.
Add the script to the function app
After deploying the function app resource, click Go to resource and perform the following configurations.
- Open the Functions blade.
- Create a new function:
- Leave Development environment to its default value (Develop in portal).
- Select the type of trigger you want to use.
- Give your function a descriptive name.
- Configure the rest of the available settings (depending on the selected trigger type).
- Click on Create.
- Click on Code + test in the navigation.
- Finally, include the following lines in your PowerShell script to implement authentication using the certificate, and click on Save.
Authenticating with a self-signed certificate
As I mentioned at the beginning of this article, it is also possible to authenticate to PnP PowerShell with a certificate (which we will create in just a moment). We’ll store that certificate in an Azure Key Vault (which we will also create in just a second). Our function app will to fetch that certificate from the key vault with the previously enabled managed identity.
Create a self-signed certificate
We must generate a self-signed certificate for our PowerShell script to authenticate to SharePoint Online. This happens by executing the following script (after you’ve adjusted the $commonName
and $password
variable values). The certificate files will appear in the same directory where you execute the script.
Create and configure an Entra ID application registration
To be able to authenticate, we need to create a new application registration on Entra ID.
- On Azure Portal, click on Microsoft Entra ID on the left-hand side navigation. Then, select App registrations.
- Click on New registration
- Name the app registration after your function app. Otherwise, you can leave the settings to their default values and click on Register.
After creating the application registration, we must configure it with permissions and a certificate.
- In the application registration settings, as the first thing while you are still on the Overview blade, please copy the Application (client) ID to, e.g., Notepad. You’ll need it later!
- Then, go to the API permissions blade, and do the following. Note: you may need to assign other permissions depending on what you want to do via PnP.PowerShell. This is just an example.
- Click on Add a permission.
- Select SharePoint.
- Select Application permissions.
- Select Sites.FullControl.All.
- Click on Add permissions.
- Click on Grant admin consent for organization. You may need to ask your global admin to perform this step if you do not have the required permissions.
- Then, go to the Certificates & secrets blade.
- Open the Certificates tab.
- Click on Upload certificate.
- Select the .cer file we generated with the PowerShell script above. You may also optionally enter a description to explain what the certificate is for.
That’s it; all configurations for the application registration are now done!
Create and configure an Azure Key Vault
Azure Key Vault offers a secure place to store the certificate so that our function app can access it during runtime. On Azure Portal, go back to the root of the resource group. Then, click the button to create a new resource and search for Key Vault on the Marketplace. Then, create one with the following settings.
- Select the same subscription and resource group as before.
- Give the key vault a name according to your organization’s naming conventions.
- Select the same region as you’ve done before.
- Leave the pricing tier to Standard
- You may wish to enable purge protection.
- Open the Access policy tab and click on the Add access policy link.
- Select Get permission from the Secret dropdown.
- Click on the None selected link. In the search field, paste the function app managed identity GUID you copied into Notepad (or similar) earlier. Add the function app as the principal.
- Again, you may tag the resource. Otherwise, click on Review + create
Add the certificate to the vault
When the Key Vault resource has been provisioned, go to it.
- Navigate to the Certificates blade.
- Click on the Generate/Import button at the top.
- Select Import from the Method of Certificate Creation dropdown.
- Give a descriptive name for the vault certificate.
- Upload the .pfx certificate file you generated earlier.
- Provide the same password as what you used when generating the certificate.
To reference the certificate in your function app, you’ll need its URL.
- Click on the certificate you just added to the key vault.
- Similarly, also click on the current certificate version.
- Copy the Certificate Identifier (URL) to, e.g., Notepad. You can remove the version (GUID) from the end of the URL. This way, the latest version of the certificate will always be used. We’ll need this value in just a second!
Finalize the Function App configurations
Finally, go back to your function app in Azure Portal. Click on Configuration and add the following application settings.
Name | Value | Description |
---|---|---|
Tenant | yourtenant.onmicrosoft.com | The prefix is the same as in your SharePoint URL. This setting is needed for authentication. |
ClientId | Your Entra ID app/client ID | You copied this earlier from the app registration Overview blade. This setting is needed for authentication. |
Certificate | @Microsoft.KeyVault(SecretUri= https://yourvaultname.vault.azure.net /certificates/yourcertname) |
This is called a key vault reference. It allows our function app to retrieve the certificate from the vault using its managed identity. You must paste the certificate identifier URL we copied as the SecretUri value. This setting is needed for authentication. |
WEBSITE_LOAD_USER_PROFILE | 1 | This setting is required to ensure the function app can fetch the certificate from the key vault (needed for authentication). |
Add the script to the function app
After deploying the function app resource, click Go to resource and perform the following configurations.
- Open the Functions blade.
- Create a new function:
- Leave Development environment to its default value (Develop in portal).
- Select the type of trigger you want to use.
- Give your function a descriptive name.
- Configure the rest of the available settings (depending on the selected trigger type).
- Click on Create.
- Click on Code + test in the navigation.
- Finally, include the following lines in your PowerShell script to implement authentication using the certificate, and click on Save.
Afterword
I write these blog posts just as much for my benefit as yours. So now, I have an article I can easily link to my colleagues whenever they need to figure out how to implement certificate authentication for using PnP PowerShell on Azure Functions with application permissions.
I hope you, my dear reader, also found this article helpful and got your script working. Happy coding, and until next time!
Laura
GREAT article – thanks so much !
I had to adjust one part with the Azure AppRole – minor bug with the script/code :
# *** I changed to use ; instead of ,
>> $permissionsToAdd = “Sites.FullControl.All;TermStore.ReadWrite.All”
And then – the next line needed a SPLIT based on ;
>> foreach ($permission in $permissionsToAdd.Split(‘;’)) {
Otherwise – it was just ONE value – not an array. 🙂
Hi Chris,
You can also do it like this and it creates an array:
$permissionsToAdd = “Sites.FullControl.All”, “TermStore.ReadWrite.All”
Laura
Hi Laura, Great blog as always… I think the biggest challenge with using PnP.PowerShell in Azure Functions at the moment is finding a stable build that allows you to use some of the newer PnP.PowerShell modules.
Do you have a build that you can recommend?
Hi Alan,
I think the latest production version is working well at this moment, at least for the purposes I am using it for.
Laura
Laura, let me thank you for your post. I do appreciate that you shared your knowledge. Frankly I tried to make PowerShell Azure Function connected to SPO list, found tuns of resources out there but none of them really helped me .. but then I came across your one.
Hi Mirek, and thank you for your kind comment! Happy to hear you got your function working. 🙂
Laura