Field notes · Entra ID · PIM
How to find standing Global Admins in Entra ID
Entra IDPIMPowerShell
Before you design a single PIM group, I recommend you find out how far standing access has already spread. Start with the role that matters most: Global Administrator.
Why "standing" is the number to watch
An active assignment with no end date means the account holds Global Administrator every minute of every day. If that account is phished at 2 a.m., the attacker holds it too. An eligible assignment only becomes active when the admin asks for it, with MFA and a justification, and expires on its own.
In most tenants I review, the permanent list is longer than anyone expects. Count it first, so you can show the improvement later.
Option 1: the admin center (two minutes)
- Sign in to the Microsoft Entra admin center as at least a Global Reader.
- Go to Identity governance → Privileged Identity Management → Microsoft Entra roles → Assignments.
- Open the Active assignments tab and filter on Global Administrator.
- Every row whose end time reads Permanent is standing access.
Option 2: one PowerShell script (repeatable)
The admin center is fine once. For a number you track monthly, use Microsoft Graph PowerShell:
# Lists every permanent (non-expiring) active Global Administrator assignment.
# Needs: Microsoft.Graph PowerShell SDK, Entra ID P2 (PIM), and a Global Reader
# or Privileged Role Administrator account.
Connect-MgGraph -Scopes "RoleAssignmentSchedule.Read.Directory","Directory.Read.All"
$globalAdmin = "62e90394-69f5-4237-9190-012177145e10" # Global Administrator role template ID
Get-MgRoleManagementDirectoryRoleAssignmentScheduleInstance -All |
Where-Object {
$_.RoleDefinitionId -eq $globalAdmin -and
$_.AssignmentType -eq "Assigned" -and # assigned, not just activated
-not $_.EndDateTime # no end date = permanent
} |
ForEach-Object {
$p = Get-MgDirectoryObject -DirectoryObjectId $_.PrincipalId
[pscustomobject]@{
Name = $p.AdditionalProperties.displayName
Account = $p.AdditionalProperties.userPrincipalName
Type = $p.AdditionalProperties.'@odata.type' -replace '#microsoft.graph.',''
Membership = $_.MemberType # Direct, or Group if inherited
Since = $_.StartDateTime
}
} | Sort-Object Name | Format-Table -AutoSize
Read-only: it changes nothing. Test it in your own tenant first; the PIM APIs need Entra ID P2.
What a healthy result looks like
- Two permanent Global Admins: your break-glass (emergency access) accounts: cloud-only, protected with phishing-resistant credentials, and alerting on every sign-in.
- Everyone else eligible, activating only when the work needs it.
- No inherited surprises: any row showing Group membership means a group is granting Global Admin. Check who can change that group's members.
What to do with the list
Write today's number down. It is your baseline, and the first thing your leadership will ask about later.
Then resist the urge to convert everyone to eligible overnight; that is how PIM rollouts get rolled back. Admins hold permanent access because activating it is painful, so fix the pain first. That is what job-based PIM groups do: one activation for every role the job needs.
Run the script again next month. If the number is going down, it is working.