๐ก๏ธ Recipe ยท Security & Compliance
Audit Privileged Admin Roles for MFA, Stale Accounts, and Least Privilege
Identify Global Admins and other privileged role holders, verify MFA coverage, detect stale accounts, and produce a least-privilege cleanup plan.
Complexity
Intermediate
Impact
security + compliance + identity + governance + audit
Context
Why This Matters
Why this audit matters
Privileged roles such as Global Administrator, Application Administrator, and Privileged Role Administrator grant tenant-wide control over identity, apps, and role assignments. A single compromised or stale privileged account is one of the most common paths to a full tenant breach.
Microsoft's Secure Score and the CISA SCuBA baseline both recommend:
- No more than 2โ4 permanent Global Administrators
- 100% MFA coverage on all privileged accounts, ideally phishing-resistant
- No stale (inactive > 90 days) privileged accounts
- Just-in-time activation via Privileged Identity Management (PIM) rather than permanent role assignments
When to run this recipe
- Quarterly as part of an access review cadence
- Before and after any M&A / org change
- When preparing for a security audit (SOC 2, ISO 27001, HIPAA)
- After any suspected admin compromise
Expected Outcomes
What you'll have after running this recipe
- A complete inventory of every user holding
Global Administrator,Application Administrator, orPrivileged Role Administrator - MFA status and registered authentication methods for each privileged user
- Last interactive and non-interactive sign-in timestamps
- Staleness flag (accounts inactive > 90 days)
- Risk rating (Critical / High / Medium / Low) per account
- A downloadable CSV report suitable for audit evidence
- A prioritized least-privilege cleanup plan
Risks & Considerations
Warnings and gotchas
- Do NOT remove your own Global Admin role without first confirming at least one other enabled, MFA-protected Global Admin exists โ you can lock yourself out of the tenant.
- Maintain two break-glass (emergency access) accounts with permanent Global Admin and strong passwords stored offline. These accounts will legitimately appear stale; exclude them from cleanup.
signInActivityrequires an Entra ID P1 or P2 license and theAuditLog.Read.Allpermission.- The
roleAssignmentsendpoint only returns active (permanent) assignments. If you use PIM, also queryroleEligibilitySchedulesfor eligible-but-not-active assignments. - Service principals and groups can also hold privileged roles โ don't assume every principal is a user.
- Never bulk-disable privileged accounts without a change window and stakeholder sign-off.
Required Permissions
| Permission | Why It's Needed |
|---|---|
| RoleManagement.Read.Directory | Read directory role definitions and active role assignments |
| Directory.Read.All | Resolve user objects from principal IDs |
| User.Read.All | Read user properties including accountEnabled and signInActivity |
| AuditLog.Read.All | Read signInActivity (last sign-in timestamps) on user objects |
| UserAuthenticationMethod.Read.All | Enumerate registered MFA authentication methods per user |
The fastest way to get this done: just ask Dex. Copy the prompt below and paste it into your Dex conversation.
For IT Admins
Paste into Dex Pro
Audit privileged roles via the Entra admin center
Step 1 โ Open the Roles and administrators blade
- Sign in to entra.microsoft.com as a Global Reader or higher.
- Navigate to .
Step 2 โ Inspect each privileged role
- Open Global Administrator. Review the Assignments tab for both Active assignments and Eligible assignments (PIM).
- Repeat for Application Administrator and Privileged Role Administrator.
- For each member, click the name to open the user profile and note:
- Account enabled status
- Sign-in activity (visible on the Overview tab)
Step 3 โ Check MFA / authentication methods
- From each user's profile, go to .
- Confirm at least one strong method is registered (Microsoft Authenticator, FIDO2, or Windows Hello for Business). Phone/SMS alone is not considered phishing-resistant.
Step 4 โ Review sign-in activity
- Go to .
- Filter by each privileged UPN. Flag any account with no interactive sign-ins in the past 90 days as stale.
Step 5 โ Build the cleanup plan
- Any privileged user without MFA โ remediate immediately (register method or remove role).
- Any stale privileged user โ confirm with manager, then remove role or disable account.
- Permanent Global Admins > 2 โ migrate excess assignments to PIM Eligible.
Manual time estimate: ~30 minutes for a small tenant; significantly longer at scale. Prefer the Graph API or PowerShell approach below.
Audit privileged roles with Microsoft Graph
The audit is a three-stage workflow: (1) enumerate target role definitions, (2) list assignments per role, (3) enrich each principal with user, sign-in, and MFA data.
1. Find role definition IDs
GET https://graph.microsoft.com/v1.0/roleManagement/directory/roleDefinitions?$filter=displayName in ('Global Administrator','Application Administrator','Privileged Role Administrator')&$select=id,displayName2. List active assignments for each role
GET https://graph.microsoft.com/v1.0/roleManagement/directory/roleAssignments?$filter=roleDefinitionId eq '{roleDefinitionId}'&$select=principalId,directoryScopeIdFor PIM-eligible (not yet activated) assignments:
GET https://graph.microsoft.com/v1.0/roleManagement/directory/roleEligibilitySchedules?$filter=roleDefinitionId eq '{roleDefinitionId}'3. Enrich each user with sign-in activity
GET https://graph.microsoft.com/v1.0/users/{id}?$select=id,displayName,userPrincipalName,accountEnabled,signInActivity,userTypeExample response excerpt:
{
"displayName": "Avi Kedmi",
"userPrincipalName": "avi.kedmi@contoso.com",
"accountEnabled": true,
"signInActivity": {
"lastSignInDateTime": "2025-02-14T22:54:03Z",
"lastNonInteractiveSignInDateTime": "2025-02-15T00:07:13Z"
}
}4. List registered authentication methods
GET https://graph.microsoft.com/v1.0/users/{id}/authentication/methodsAny method with @odata.type other than #microsoft.graph.passwordAuthenticationMethod counts as MFA. Strong (phishing-resistant) methods are fido2AuthenticationMethod and windowsHelloForBusinessAuthenticationMethod.
Computing staleness
Flag a user as stale when now - lastSignInDateTime > 90 days, or when signInActivity is null (never signed in). Exclude break-glass accounts by UPN.
Automated audit with PowerShell + Microsoft Graph
The script below uses the Microsoft.Graph PowerShell SDK to enumerate privileged users, check MFA, detect staleness, score risk, and export a CSV.
Prerequisites
- Install the SDK:
Install-Module Microsoft.Graph -Scope CurrentUser - Connect with the required scopes:
Connect-MgGraph -Scopes "RoleManagement.Read.Directory","Directory.Read.All","User.Read.All","AuditLog.Read.All","UserAuthenticationMethod.Read.All" - Tenant must have Entra ID P1/P2 for
signInActivity.
What the script does
- Resolves role definition IDs for the three target roles
- Fetches all active and PIM-eligible assignments
- Deduplicates principals and enriches each with user details, sign-in activity, and MFA methods
- Assigns a risk rating (Critical / High / Medium / Low)
- Exports
PrivilegedAccountsAudit.csvand prints a summary scorecard
Run it
.\Audit-PrivilegedRoles.ps1 -StaleDays 90 -OutputPath .\reports\Review the CSV, then use the recommendations at the bottom of the script output to plan your cleanup (demote excess Global Admins, convert permanent assignments to PIM-eligible, enforce FIDO2 for admins).
Next steps