Revoke Entra ID App Permissions from SharePoint Sites Using PnP PowerShell
Managing Entra ID (formerly Azure AD) app permissions across SharePoint sites is crucial for maintaining proper security governance. This guide demonstrates how to audit and revoke app permissions using PnP PowerShell, ensuring your SharePoint environment remains secure and compliant.
Table of Contents
- Problem Statement
- Understanding the Challenge
- Prerequisites
- The Solution
- Script Breakdown
- Important Considerations
- References
Problem Statement
When managing Entra ID applications with SharePoint access (especially those using Sites.Selected permissions), you may need to:
- Audit app permissions across all SharePoint sites in your tenant
- Revoke specific app permissions from sites where they’re no longer needed
- Generate reports for compliance and security reviews
- Automate cleanup of orphaned or unnecessary app permissions
Understanding the Challenge
Key Issues to Be Aware Of
Silent Failures: The
Revoke-PnPEntraIDAppSitePermissioncmdlet does not throw an error if the specified permission ID doesn’t exist. This can lead to false confidence that permissions were successfully revoked. View Revoke-PnPAzureADAppSitePermission - Not WorkingPermission Verification: Always verify that privileges have been properly revoked by re-checking granted permissions after running revocation commands.
Correct Parameter Usage: Ensure you’re passing the
PermissionIdparameter correctly to avoid silent failures.
Prerequisites
Before running the script, ensure you have:
PnP PowerShell module installed:
Install-Module -Name PnP.PowerShellSharePoint Administrator or Global Administrator permissions
Application (Client) ID of the Entra ID app whose permissions you want to revoke
The Solution
This PowerShell script performs the following actions:
- Connects to your SharePoint Admin Center
- Retrieves all SharePoint sites in your tenant
- Checks each site for permissions granted to the specified Entra ID app
- Exports permission details to a CSV report
- Revokes the app permissions from each site
Script Breakdown
Complete PowerShell Script
param (
[Parameter(Mandatory = $true)]
[string] $domain,
[Parameter(Mandatory = $true)]
[string] $app,
[Parameter(Mandatory = $false)]
[switch] $RevokePermissions
)
# Construct SharePoint URLs
$adminSiteURL = "https://$domain-admin.sharepoint.com"
$TenantURL = "https://$domain.sharepoint.com"
# Generate timestamped filename for the report
$dateTime = "_{0:MM_dd_yy}_{0:HH_mm_ss}" -f (Get-Date)
$invocation = (Get-Variable MyInvocation).Value
$directorypath = Split-Path $invocation.MyCommand.Path
$fileName = "entraid_site_permissions" + $dateTime + ".csv"
$outputPath = Join-Path $directorypath $fileName
# Create output file if it doesn't exist
if (-not (Test-Path $outputPath)) {
New-Item -ItemType File -Path $outputPath | Out-Null
}
# Connect to SharePoint Admin Center
Connect-PnPOnline -Url $adminSiteURL -Interactive -WarningAction SilentlyContinue
Write-Host "Scanning sites for Entra ID app permissions..." -ForegroundColor Yellow
# Process each site in the tenant
$report = Get-PnPTenantSite -Filter "Url -like '$TenantURL'" |
Where-Object { $_.Template -ne 'RedirectSite#0' } |
ForEach-Object {
$siteUrl = $_.Url
Write-Host "Processing site: $siteUrl" -ForegroundColor Cyan
# Connect to the specific site
Connect-PnPOnline -Url $siteUrl -Interactive -WarningAction SilentlyContinue
# Get app permissions for the specified app
Get-PnPAzureADAppSitePermission -AppIdentity $app | ForEach-Object {
# Create report object
$permissionData = [PSCustomObject]@{
PermissionId = $_.Id
SiteUrl = $siteUrl
Roles = $_.Roles -join ","
Apps = $_.Apps -join ","
DisplayName = $_.DisplayName
RevokedDate = if ($RevokePermissions) { Get-Date -Format "yyyy-MM-dd HH:mm:ss" } else { "Not Revoked" }
}
# Revoke the permission only if the switch is enabled
if ($RevokePermissions) {
try {
Write-Host " Revoking permission ID: $($_.Id)" -ForegroundColor Yellow
Revoke-PnPEntraIDAppSitePermission -PermissionId $_.Id -Site $siteUrl -Force
Write-Host " Successfully revoked permission" -ForegroundColor Green
}
catch {
Write-Host " Error revoking permission: $($_.Exception.Message)" -ForegroundColor Red
}
# Verify the permission was revoked
Start-Sleep -Seconds 2
$remainingPerms = Get-PnPAzureADAppSitePermission -AppIdentity $app -ErrorAction SilentlyContinue
if ($remainingPerms | Where-Object { $_.Id -eq $_.Id }) {
Write-Host " WARNING: Permission may still exist. Verify manually!" -ForegroundColor Red
}
}
else {
Write-Host " Found permission ID: $($_.Id) (not revoking - report only mode)" -ForegroundColor Cyan
}
# Return the permission data for the report
$permissionData
}
}
# Export report to CSV
$report | Export-Csv $outputPath -NoTypeInformation -Append
Write-Host "`nReport saved to: $outputPath" -ForegroundColor Green
if ($RevokePermissions) {
Write-Host "Permissions have been revoked. Please verify that permissions were successfully revoked." -ForegroundColor Yellow
}
else {
Write-Host "Report-only mode: No permissions were revoked. Use -RevokePermissions switch to revoke." -ForegroundColor Yellow
}
Run output
If RevokePermissions is used the permissions will be revoked from all sites within a tenant.

Script Components Explained
Parameters
$domain: Your SharePoint tenant domain (e.g.,contoso)$app: The Application (Client) ID or Display Name of the Entra ID app$RevokePermissions: Only use of permissions need to be revoked
Usage Example
.\Revoke-EntraIDAppPermissions.ps1 -domain "contoso" -app "p-m365" -RevokePermissions
What the Script Does
- Connects to Admin Center: Establishes connection to your SharePoint Admin site
- Retrieves Sites: Gets all SharePoint sites (excluding redirect sites)
- Scans Permissions: Checks each site for permissions granted to the specified app
- Creates Report: Generates a timestamped CSV with permission details
- Revokes Permissions: Removes app permissions from each site if RevokePermissions parameter is passed
- Verifies Results: Checks if permissions were successfully revoked
Important Considerations
Critical Points to Remember
⚠️ Silent Failures: The Revoke-PnPEntraIDAppSitePermission cmdlet will not throw an error if the permission ID doesn’t exist. Always verify the results.
⚠️ Verification Required: After running the script, manually verify that permissions have been properly revoked, especially for critical sites.
⚠️ Parameter Accuracy: Ensure the PermissionId parameter is correctly passed. Incorrect values result in silent failures.
References
- Limiting access to SharePoint for custom app access using Sites.Selected
- Revoke-PnPEntraIDAppSitePermission Documentation
- Get-PnPAzureADAppSitePermission Documentation
- SharePoint Sites.Selected Permission Scope