To find apps users have consented to in Entra ID, list the delegated permission grants whose consent type is Principal: each is 1 person's consent for 1 app to act as them on 1 API. By default any user can consent to permissions that don't need an administrator, so these grants build up without anyone in IT approving them. A grant records no date.
| Method | Best fit |
|---|---|
| PowerShell | A CSV of every user consent, and a second with the people and permissions for each app. |
| Admin centre | Checking who agreed to 1 app and what they granted. |
| Altivane | Recommended for recurring reviews, with user and admin consent side by side and high-risk scopes marked. |
Before you start
Use an account in a role that can read grants, such as Global Reader, Directory Readers or Application Administrator. The PowerShell example requests Directory., the least privileged permission for listing delegated grants and enough for its other calls; your organisation may require administrator consent. The admin centre steps need Cloud Application Administrator or Application Administrator.
Know what a grant holds. It names the app, the person, the API and the permissions, called scopes, and nothing else. Changing the user consent settings affects future consents only: grants already given stay until someone revokes them. The examples read and export; they don't revoke any grant.
Option 1
Find user-consented apps with PowerShell
Install the modules once, then connect and export every grant a user gave for themselves. The consent type filter runs in Microsoft Graph, so admin consents don't come back.
# Install once, if the modules are not already installed.
$modules = 'Microsoft.Graph.Authentication', 'Microsoft.Graph.Identity.SignIns',
'Microsoft.Graph.Applications', 'Microsoft.Graph.Users'
Install-Module $modules -Scope CurrentUser$ErrorActionPreference = 'Stop'
Connect-MgGraph -Scopes 'Directory.Read.All' -NoWelcome
try {
$grants = @(Get-MgOauth2PermissionGrant -All -Filter "consentType eq 'Principal'")
$apps = @{}
Get-MgServicePrincipal -All -Property 'id', 'displayName' |
ForEach-Object { $apps[$_.Id] = $_.DisplayName }
$people = @{}
foreach ($id in @($grants | ForEach-Object { $_.PrincipalId } | Sort-Object -Unique)) {
try {
$people[$id] = (Get-MgUser -UserId $id -Property 'userPrincipalName').UserPrincipalName
} catch {
$people[$id] = $id
}
}
$report = @(foreach ($grant in $grants) {
[pscustomobject]@{
Application = $apps[$grant.ClientId]
User = $people[$grant.PrincipalId]
Resource = $apps[$grant.ResourceId]
Scopes = @($grant.Scope -split ' ' | Where-Object { $_ }) -join ', '
ClientId = $grant.ClientId
}
})
if ($report.Count -eq 0) {
Write-Output 'No user has consented to an app for themselves in this tenant.'
} else {
$report | Sort-Object Application, User |
Export-Csv -Path './user-consents.csv' -NoTypeInformation -Encoding utf8
$byApp = foreach ($group in $report | Group-Object Application) {
[pscustomobject]@{
Application = $group.Name
Users = @($group.Group.User | Sort-Object -Unique).Count
Scopes = @($group.Group.Scopes -split ', ' | Sort-Object -Unique) -join ', '
}
}
$byApp | Sort-Object Users -Descending |
Export-Csv -Path './user-consents-by-app.csv' -NoTypeInformation -Encoding utf8
Write-Output "$($report.Count) user consents across $(@($byApp).Count) apps."
}
} finally {
Disconnect-MgGraph | Out-Null
}The first file has 1 row per grant, with the person who agreed in User and the API, often Microsoft Graph, in Resource. A person the script can't look up shows as an object ID. The second file has 1 row per app, with how many people consented and every scope any of them granted, the widest reach first. An app many people agreed to, with scopes such as Mail., is the one to review first.
Option 2
Check user consent in the admin centre
- Sign in to the Microsoft Entra admin centre for the correct tenant.
- Go to Entra ID > Enterprise apps > All applications and select the application.
- Select Permissions.
- Open the User consent tab for the permissions granted by individual users.
- Select a permission to open the Permission Details pane. Leave Revoke permission alone: it removes the grant in the tenant.
This suits 1 application you already have in mind. The steps show 1 application at a time, so to see every app users have agreed to, use PowerShell or a report.
Option 3 ยท Recommended for recurring reviews
Report on user-consented apps with Altivane
- Open Altivane and choose the tenant.
- Build the tenant's documents with the Applications scorecard report in full, so the grants are listed as well as counted.
- Open the tenant's Excel workbook, find Delegated Permission Grants and filter its Consent Type column to User consent: each app a person agreed to, with the User by name, the API, the scopes, and High Risk where a scope is on Altivane's high-risk list.
- Read Application Summary for how many grants came from user consent and how many from admin consent.
Altivane lists user and admin consent in 1 table, so you can see an app that has both. Grants to Microsoft's own applications are left out unless you include them. Only admin consent counts towards High-Privilege Applications, so a risky scope a single user granted shows here rather than there. Where the grants can't be read, the table says it was not collected and the figures say Not read, rather than 0. The table goes to the workbook only to start; you can put it in the Word report too.
Contact usCommon questions
Can users still consent to apps today?
Unless someone has changed it, yes: by default any user can consent to permissions that don't need an administrator. Microsoft recommends allowing user consent only for apps from verified publishers. The setting is under Entra ID > Enterprise apps > Consent and permissions > User consent settings, and only a Global Administrator can save it in the admin centre.
Why does 1 app have so many rows?
Each grant is 1 person's consent for 1 app on 1 API. An app 50 people use has 50 rows, and an app that calls 2 APIs has twice as many. The second CSV puts them together by app.
What about apps an administrator consented to?
Those grants have the consent type AllPrincipals and apply to everyone, and apps can also hold application permissions with no user at all. For both, see how to review app permissions.
Microsoft references
Technical references checked on 7 November 2026. The example scripts have been reviewed and syntax checked; they have not been run against a live tenant.