Skip to content

Instantly share code, notes, and snippets.

@mkacena
Last active June 25, 2025 03:57
Show Gist options
  • Select an option

  • Save mkacena/3c023a229262260e41603b47daebc89a to your computer and use it in GitHub Desktop.

Select an option

Save mkacena/3c023a229262260e41603b47daebc89a to your computer and use it in GitHub Desktop.
This PowerShell script creates an app registration in Microsoft Entra ID with Write permissions to the specified SharePoint site.
###############################################
# Author: Miroslav Kačena
# Last Modification: 2025-06-25
###############################################
<#
.SYNOPSIS
Creates an app registration in Microsoft Entra ID with Write permissions to the specified SharePoint site.
.DESCRIPTION
This script registers a new app in Microsoft Entra ID,
creates a new self-signed certificate to use with the application registration,
and sets the Write permissions to the specified SharePoint site.
.PARAMETER Tenant
The name of the tenant in the format "contoso.onmicrosoft.com".
.PARAMETER Site
Absolute URL of the SharePoint site.
.PARAMETER ClientId
The client ID of the app registration used for running PnP PowerShell commands.
.PARAMETER ApplicationName
The name of the app registration.
.EXAMPLE
.\Register-EntraIDAppForSharePointSite.ps1 -Tenant "contoso.onmicrosoft.com" -Site "https://contoso.sharepoint.com/sites/mysite" -ClientId "00000000-0000-0000-0000-000000000000" -ApplicationName "MyApp"
.NOTES
To use this script, an app registration with AllSites.FullControl permission is required for PnP.PowerShell module. If you do not have any, you can register it with this command:
- Register-PnPEntraIDAppForInteractiveLogin -ApplicationName "PnP PowerShell" -Tenant contoso.onmicrosoft.com
- More info: https://pnp.github.io/powershell/articles/registerapplication.html
#>
[CmdletBinding()]
param (
[Parameter(Mandatory = $true, HelpMessage = "The name of the tenant in the format 'contoso.onmicrosoft.com'.")]
[string]$Tenant,
[Parameter(Mandatory = $true, HelpMessage = "Absolute URL of the SharePoint site.")]
[string]$Site,
[Parameter(Mandatory = $true, HelpMessage = "The client ID of the app registration used for running PnP PowerShell commands.")]
[string]$ClientId,
[Parameter(Mandatory = $true, HelpMessage = "The name of the app registration.")]
[string]$ApplicationName
)
$ErrorActionPreference = 'Stop'
[SecureString]$CertificatePassword = Read-Host -Prompt "Enter certificate password" -AsSecureString
Write-Host "Registering new app in Entra ID..."
$app = Register-PnPAzureADApp -ApplicationName $ApplicationName -Tenant $Tenant -CertificatePassword $CertificatePassword -SharePointApplicationPermissions "Sites.Selected" -GraphApplicationPermissions "Sites.Selected"
Write-Host "App registered successfully."
Write-Host "Connecting to the SharePoint site: $Site"
Connect-PnPOnline -Url $Site -Interactive -ClientId $ClientId
Write-Host "Successfully connected to the SharePoint site."
Write-Host "Granting permissions to the SharePoint site..."
Grant-PnPAzureADAppSitePermission -AppId $app.'AzureAppId/ClientId' -DisplayName $ApplicationName -Site $Site -Permissions Write
Write-Host "Permissions granted successfully."
Write-Host "Disconnecting from the SharePoint site..."
Disconnect-PnPOnline
Write-Host "Disconnected."
@vitusq
Copy link

vitusq commented Feb 21, 2025

How does one verify or check that the permissions are correctly in place?

@mkacena
Copy link
Author

mkacena commented Feb 21, 2025

How does one verify or check that the permissions are correctly in place?

Hello @vitusq , you can use the Get-PnPAzureADAppSitePermission command to get details of permissions set for a site: https://pnp.github.io/powershell/cmdlets/Get-PnPAzureADAppSitePermission.html

@vitusq
Copy link

vitusq commented Feb 21, 2025

How does one verify or check that the permissions are correctly in place?

Hello @vitusq , you can use the Get-PnPAzureADAppSitePermission command to get details of permissions set for a site: https://pnp.github.io/powershell/cmdlets/Get-PnPAzureADAppSitePermission.html

Perfect! Thank you for the reference and this great script! works flawlessly.

@vitusq
Copy link

vitusq commented Feb 21, 2025

Regarding the Self-Signed certificate which is created, it gets created with a validity of 10 years - rather can a start and end date be specified and how?

Also, the certificate (when checked through the installed certificate mmc console, it is created with the "Intended Purpose" reflecting as "Server Authentication" (the grey highlighted one indicates)

image

How can the intended purpose be specified to both Server and Client or only one of the two ?

@vitusq
Copy link

vitusq commented Feb 21, 2025

After granting the App Registration access to a specific Sharepoint site, is there a possibility to "lockdown" it down. So that if any other attempt is made to grant it access to another Sharepoint site, then it requires a password to get configure further.
I think of this approach as a Security mechanism as well as when audits are conducted or ask to ensure that the app cannot access or be granted access to any other site than the intended one.

@mkacena
Copy link
Author

mkacena commented Feb 21, 2025

Regarding the Self-Signed certificate which is created, it gets created with a validity of 10 years - rather can a start and end date be specified and how?

Also, the certificate (when checked through the installed certificate mmc console, it is created with the "Intended Purpose" reflecting as "Server Authentication" (the grey highlighted one indicates)
image

How can the intended purpose be specified to both Server and Client or only one of the two ?

I don't think you can do all of that with Register-PnPAzureADApp command. From the things you mentioned, I found that only validity length can be adjusted using the -ValidYears parameter. If you want different start/end date or intended purpose, you need to use other method to create the certificate and then use the existing certificate in Register-PnPAzureADApp command by providing the -CertificatePath parameter.

Please see the documentation to the Register-PnPAzureADApp command: https://pnp.github.io/powershell/cmdlets/Register-PnPAzureADApp.html

@mkacena
Copy link
Author

mkacena commented Feb 21, 2025

After granting the App Registration access to a specific Sharepoint site, is there a possibility to "lockdown" it down. So that if any other attempt is made to grant it access to another Sharepoint site, then it requires a password to get configure further. I think of this approach as a Security mechanism as well as when audits are conducted or ask to ensure that the app cannot access or be granted access to any other site than the intended one.

I haven't heard of such possibility. The setup with Sites.Selected permission requires a different approach to security. The permission does not grant you any real end-user permissions per se, it only grants you (as a site admin) permission to grant this app permissions in your site. You have 2 sides of the story here - the Entra ID admin and a site admin. If I understand correctly, you, as an Entra ID admin, want to control which sites the app has access to (push model). But the permission is not designed like that. You only provide the app to site admins so that they can enable it in their sites (pull model). I am not aware of a standard API permission feature which would enable you to restrict the sites where this permission is applied. Maybe you could use some advanced Entra ID features, like Conditional Access, to restrict the access, but I don't know.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment