Skip to main content
Microsoft Entra ID · PowerShell 7.6

Application permissions granted to apps (Microsoft Graph by default)

Which apps have been granted application permissions (app roles) on Microsoft Graph, such as Mail.Read or User.Read.All, that work without a signed-in user?

Script

#Requires -Modules Microsoft.Graph.Authentication, Microsoft.Graph.Applications
# Application permissions (app roles) granted to apps on one API, Microsoft Graph by default. Read-only.
param(
    [string]$ResourceAppId = '00000003-0000-0000-c000-000000000000'
)

Connect-MgGraph -Scopes 'Application.Read.All' -NoWelcome

$resource = Get-MgServicePrincipal -Filter "appId eq '$ResourceAppId'" -Property 'id', 'displayName', 'appRoles' | Select-Object -First 1
if (-not $resource) { throw "No service principal with appId $ResourceAppId in this tenant." }

$roleNames = @{}
foreach ($role in $resource.AppRoles) { $roleNames[$role.Id] = $role.Value }

Get-MgServicePrincipalAppRoleAssignedTo -ServicePrincipalId $resource.Id -All |
    Where-Object { $_.PrincipalType -eq 'ServicePrincipal' } |
    ForEach-Object {
        [pscustomobject]@{
            Application = $_.PrincipalDisplayName
            Permission  = $roleNames[$_.AppRoleId]
            Api         = $resource.DisplayName
            GrantedOn   = $_.CreatedDateTime
            AppRoleId   = $_.AppRoleId
            PrincipalId = $_.PrincipalId
        }
    } |
    Sort-Object Application, Permission

Checked automatically against Microsoft's published cmdlet reference. KBY hasn't run it in your tenant; run it in a test environment first.

Reading the output

  • Lists app role assignments made to service principals on one resource API. By default that is Microsoft Graph (appId 00000003-0000-0000-c000-000000000000); pass -ResourceAppId to check another API.
  • Application permissions apply tenant-wide with no user present, so entries such as Mail.Read, Files.Read.All or Directory.ReadWrite.All deserve a named owner and a reason.
  • Delegated permissions (an app acting as a signed-in user) are a different object; the delegated permission grants script covers those.
  • Permission is the app role's value. If an assignment refers to a role the API no longer exposes, Permission is empty and the AppRoleId tells you which one it was.

Sources

The Microsoft reference page for every cmdlet the script calls, plus the API and product pages behind each permission and caveat.

All scripts