Set up Enterprise App to use App-Only Sites.Selected permissions and wite to SharePoint with PnP Powershell
I wanted to run unattended scripts against SharePoint for various governance and content cleanup jobs and found the guidance for this to be a little confusing. I think it's a good idea to limit the access of any script, so I prefer to set up an App per script and use the Sites.Selected permission to limit the sites to which my app has access. Here's the process I used to get it to work:
You can register an app in the Azure portal UI, but there's a few steps that must be performed with PowerShell, so I figured just doing it all in Powershell made it consistent.
Step 0: Get the right version of PnP.Powershell
I also had to use the PnP.PowerShell 2.2.81 nightly build because there was a bug introduced in 2.2.0. If you need to get a specific version you can run Install-Module, but I prefer to use Save-Module with specific version so I can keep different version of PnP.PowerShell around to avoid having my old scripts affected by new modules and potential regression issues.
Once you have the right version, run the following line (or include in your script file):
Import-Module D:\psbin\PnP.PowerShell\2.2.81\PnP.PowerShell.psd1
Step 1: Register the App
Permissions Needed: Global Administrator/Azure AD Admin
Generate Certificate
$pw = "USEAGOODPASSWORD" #this is not a good password....
$commonName = 'EAUpload'
$certificateName = "EASharePointSiteUpload_TEST"
$certFile = "$certificateName.cer"
$certPfx = "$certificateName.pfx"
$certPass = (ConvertTo-SecureString -String $pw -AsPlainText -Force)
New-PnPAzureCertificate -CommonName $commonName -OutPfx "$certPfx" -OutCert "$certFile" -CertificatePassword $certPass
Register the App with a Certificate
# SETUP
$hostUrl = "https://YOURTENANT.sharepoint.com"
$hostRelativeUrl = "/sites/EAUploadTest" #change to whatever site you want the app to work with
$siteUrl = "$hostUrl$hostRelativeUrl"
$appName = "EAUploadTestApp_TEST"
$tenant = "YOURTENANT.onmicrosoft.com"
# END SETUP
Write-Host "Registering App on $siteUrl"
Connect-PnPOnline $siteUrl -Interactive
$reg = Register-PnPAzureADApp -ApplicationName $appName `
-Tenant $tenant `
-CertificatePath $certPfx `
-CertificatePassword $certPass `
-GraphApplicationPermissions "User.Read.All" `
-SharePointApplicationPermissions "Sites.Selected" `
-Interactive
Write-Host "Granting WRITE permissions to app on: $siteUrl"
$grant = Grant-PnPAzureADAppSitePermission -Permissions Write -Site $siteUrl -AppId "PUTAPPIDHERE" -DisplayName "MYAPP_SITESSELECTED_FULL"
$reset = Set-PnPAzureADAppSitePermission -PermissionId $grant.Id -Permissions FullControl
Disconnect-PnPOnline
Step 2: Allow NoScript on the SP Site
Permissions Needed: SP Admin
Write-Host "Setting NoScript to FALSE (so we can do file uploads)"
Set-PnPSite -NoScriptSite $false
Write-Host "Disconnecting from Admin (User) Credentials"
Disconnect-PnPOnline
Step 3: Test with App-Only Credentials
Here we connect with only App credentials (not user credentials).
Write-Host "Connecting with App Credentials"
Connect-PnPOnline -Url $siteUrl -ClientId $reg.'AzureAppId/ClientId' -Tenant $tenant -CertificatePath $certPfx -CertificatePassword $certPass #-ThumbPrint $reg.'Certificate Thumbprint'
Write-Host "--Saving File"
$testFile = 'testFile.txt'
Add-PnPFile -Path $testFile -Folder "$hostRelativeUrl/Shared Documents/"
Write-Host "--Disconnecting from App Credentials"
Disconnect-PnPOnline
Comments