Back to script library
Entra / Microsoft 365 · Applications

Report managed identity permissions

Report the Graph and other permissions assigned to managed identities.

Connect & set up

Run these once per session. All scopes are read-only unless the script makes changes.

Connect-MgGraph -NoWelcome -Scopes Directory.Read.All

Run it

The main script. Copy it, or download the .ps1 and run it from your console.

Connect-MgGraph -NoWelcome -Scopes Directory.Read.All
$GraphApp = Get-MgServicePrincipal -Filter "AppId eq '00000003-0000-0000-c000-000000000000'"
$AppRoleTable = @{}
ForEach ($AppRole in $GraphApp.AppRoles) {
$AppRoleTable.Add($AppRole.Id,$AppRole.Value)
}
# Add the roles for Exchange Online. The one we're really interested in is Exchange.ManageAsApp
# Graph roles exist in many cases, so we try to add the role to the table and don't care if a failure occurs
# because the role alreadt exists
$ExoApp = Get-MgServicePrincipal -Filter "AppId eq '00000002-0000-0ff1-ce00-000000000000'"
ForEach ($AppRole in $ExoApp.AppRoles) {
try {
$RoleName = ("{0} [Exchange Online]" -f $AppRole.Value)
$AppRoleTable.Add($AppRole.Id,$RoleName)
}
catch {
Out-Null
}
}
# Do the same for Teams. In this case, we're interested in application_access
$TeamsApp = Get-MgServicePrincipal -Filter "AppId eq '48ac35b8-9aa8-4d74-927d-1f4a14a0b239'"
ForEach ($AppRole in $TeamsApp.AppRoles) {
try {
$RoleName = ("{0} [Teams]" -f $AppRole.Value)
$AppRoleTable.Add($AppRole.Id,$RoleName)
}
catch {
Out-Null
}
}
# And to be complete, do the same for SharePoint
$SPOApp = Get-MgServicePrincipal -Filter "AppId eq '00000003-0000-0ff1-ce00-000000000000'"
ForEach ($AppRole in $SPOApp.AppRoles) {
try {
$RoleName = ("{0} [SharePoint Online]" -f $AppRole.Value)
$AppRoleTable.Add($AppRole.Id,$RoleName)
}
catch {
Out-Null
}
}
# Find the set of managed identities in the tenant
[array]$ManagedIdentities = Get-MgServicePrincipal -Filter "servicePrincipalType eq 'ManagedIdentity'" | Sort-Object DisplayName
$Report = [System.Collections.Generic.List[Object]]::new()
# Process each managed identity and find the set of application roles assigned to it
ForEach ($ManagedIdentity in $ManagedIdentities) {
[array]$RoleNames = $null
[array]$AssignedRoles = Get-MgServicePrincipalAppRoleAssignment -ServicePrincipalId $ManagedIdentity.Id | `
Select-Object -ExpandProperty AppRoleId
ForEach ($Role in $AssignedRoles) {
$GraphRoleName = $AppRoleTable[$Role]
$RoleNames += $GraphRoleName
}
$RoleNames = $RoleNames | Sort-Object
$Reportline = [PsCustomObject]@{
ManagedIdentity = $ManagedIdentity.DisplayName
Id = $ManagedIdentity.id
Created = (Get-Date $ManagedIdentity.additionalProperties.createdDateTime -format 'dd-MMM-yyyy HH:mm')
Roles = ($RoleNames -join ", ")
}
$Report.Add($ReportLine)
}
$Report | Out-GridView
Attribution