Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Get a list of application and delegated permissions for a service principal, similar to what the Azure Portal shows
#requires -version 7
using namespace Microsoft.Graph.PowerShell.Models
using namespace System.Collections.Generic
function Get-MgServicePrincipalPermission {
param(
[Parameter(ParameterSetName='Id',ValueFromPipelineByPropertyName)][Alias('Id')][string]$ServicePrincipalId,
[Parameter(ParameterSetName='Object',ValueFromPipeline)][MicrosoftGraphServicePrincipal]$ServicePrincipal
)
begin {
#We use this to cache app info for permission lookups
[Dictionary[string,MicrosoftGraphServicePrincipal]]$spCache = @{}
}
process {
$ErrorActionPreference = 'Stop'
$ServicePrincipal ??= Get-MgServicePrincipal -ServicePrincipalId $ServicePrincipalId
$ServicePrincipalId ??= $ServicePrincipal.Id
$appPermissions = Get-MgServicePrincipalAppRoleAssignment -ServicePrincipalId $ServicePrincipalId
| Where-Object DeletedDateTime -eq $null
$delegatedPermissions = Get-MgServicePrincipalOauth2PermissionGrant -ServicePrincipalId $ServicePrincipalId
foreach ($app in $appPermissions) {
$spCache[$app.ResourceId] ??= Get-MgServicePrincipal -ServicePrincipalId $app.ResourceId
[MicrosoftGraphAppRole]$role = $spCache[$app.ResourceId].AppRoles
| Where-Object Id -eq $app.AppRoleId
if (-not $Role) {throw "No matching permission found for AppRoleID $($app.AppRoleId). This is a bug"}
[PSCustomObject]@{
ServicePrincipalName = $ServicePrincipal.DisplayName
Id = $app.Id
Type = 'Application'
User = $null
ResourceName = $app.ResourceDisplayName
Permission = $role.Value
PermissionDisplayName = $role.DisplayName
Description = $role.Description
CreatedDateTime = $app.CreatedDateTime
}
}
foreach ($permission in $delegatedPermissions) {
$spCache[$permission.ResourceId] ??= Get-MgServicePrincipal -ServicePrincipalId $permission.ResourceId
$resource = $spCache[$permission.ResourceId]
foreach ($scope in $permission.Scope.split(' ')) {
$role = $resource.AppRoles | Where-Object Value -eq $scope
[PSCustomObject]@{
ServicePrincipalName = $ServicePrincipal.DisplayName
Id = $app.Id
Type = 'Delegated'
User = $permission.ConsentType -eq 'AllPrincipals' ? 'All' : $permission.PrincipalId
ResourceName = $resource.DisplayName
Permission = $scope
PermissionDisplayName = $role.DisplayName
Description = $role.Description
CreatedDateTime = $null
}
}
}
}
}
@JustinGrote
Copy link
Author

image

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