Configuring Entra ID Access Reviews for Privileged Roles
A hands-on runbook for building recurring Entra ID access reviews on privileged roles, with auto-apply, alerting, rollback and audit evidence retention.

In this lesson
Table of Contents
Table of contents
Before you begin
- Entra ID Privileged Identity Management fundamentals
- Microsoft Graph PowerShell SDK authentication
- Basic understanding of Entra ID role assignments
Track this tutorial
Choose your current status and tick each safety check as you complete it. Sign in to sync progress between devices.
Current status
Tutorial stages
- Step 1 — Establish scope and document the review target
- Step 2 — Baseline current PIM assignments for the target role
- Step 3 — Create the access review definition
- Step 4 — Exclude break-glass accounts explicitly
- Step 5 — Pilot on a lower-risk role before touching Global Administrator
- Step 6 — Roll out to Global Administrator with dual reviewer sign-off
- Step 7 — Wire audit log alerting for auto-apply removals
0 of 7 stages complete
Before you apply the change
Confirm these production-safety controls during the tutorial.
#Operational requirement
You are inheriting a tenant where privileged role assignments never expire on their own. Somewhere in Entra ID there is a contractor still holding Privileged Role Administrator from a migration that finished last year, a former project lead who kept Global Administrator after a break-glass exercise, and a service desk lead who was promoted out of Exchange Administrator but never had the role pulled. None of that is hypothetical — it is the standing finding that shows up in every SOC 2 Type II or ISO 27001 surveillance audit, and it is the first thing an incident responder checks when a tenant is compromised. If you cannot produce evidence that privileged access was reviewed and recertified on a fixed cadence, the control fails. Worse, you will not actually know who holds Global Administrator right now without manually cross-referencing HR leaver data against role assignments by hand the night before the auditor arrives.
Your task is to build a recurring Entra ID Access Review against privileged directory roles, configure automatic removal of unconfirmed access, and produce the evidence trail the compliance team will ask for by name. This assumes Privileged Identity Management (PIM) is already running for eligible role assignment in this tenant. If PIM is not deployed yet, stop and raise that with me directly — access reviews layered on permanently active role assignments achieve very little, and PIM rollout is a separate prerequisite project that has to land first.
#Prerequisites and required permissions
- Entra ID Governance or Entra ID P2 licensing assigned to you as the configuring administrator and to every designated reviewer. Access reviews on role assignments will not create without this licence in place.
- Global Administrator or Identity Governance Administrator role to create and manage access review definitions.
- Microsoft Graph PowerShell SDK installed and authenticated with the scopes
AccessReview.ReadWrite.Membership,RoleManagement.Read.DirectoryandRoleAssignmentSchedule.Read.Directory. - PIM already managing eligible and active assignments for the target roles — Global Administrator, Privileged Role Administrator, Application Administrator, Exchange Administrator, or whichever set our risk register names for this cycle.
- An approved change record in the ITSM tool before any write operation runs against the production tenant. This is not optional. Automatic removal of Global Administrator access is a production-impacting change and needs a ticket number before you touch it.
- The known break-glass account identifiers, written down and confirmed, so they can be explicitly excluded from any review scope before auto-apply is switched on.
#Step 1 — Establish scope and document the review target
Decide precisely which roles this cycle covers and whether it targets PIM-eligible assignments, active assignments, or both. Do not try to cover every privileged role in the first iteration — pick one, write the scope decision down, and move on.
Expected result: a written scope decision, for example “Review 1 covers Exchange Administrator, active and eligible assignments, quarterly cadence, self-review disabled.”
Evidence to capture: the scope decision recorded in the change ticket, plus a snapshot of current membership.
1Connect-MgGraph -Scopes "RoleManagement.Read.Directory","AccessReview.ReadWrite.Membership"
2
3$role = Get-MgDirectoryRole -Filter "displayName eq 'Exchange Administrator'"
4Get-MgDirectoryRoleMember -DirectoryRoleId $role.Id |
5 Select-Object Id, AdditionalProperties |
6 Export-Csv -Path .exchange-admin-baseline.csv -NoTypeInformationCheckpoint: confirm the CSV lists every current holder before you build the review definition. If the CSV comes back empty, check that the role has active assignments rather than only PIM-eligible ones — Get-MgDirectoryRoleMember will not surface eligible-only assignments.
#Step 2 — Baseline current PIM assignments for the target role
Pull the PIM-eligible assignment schedule separately, because eligible assignments live in a different data structure to active directory
1Get-MgRoleManagementDirectoryRoleEligibilitySchedule -Filter "roleDefinitionId eq '$($role.RoleTemplateId)'" |
2 Select-Object PrincipalId, ScheduleInfo, Status |
3 Export-Csv -Path .exchange-admin-eligible-baseline.csv -NoTypeInformationExpected result: two CSVs — active members and eligible assignments — attached to the change ticket as the pre-change state.
Checkpoint: reconcile both exports against the HR leaver list yourself. Any principal already flagged as a leaver gets removed manually now. Do not wait for the review cycle to catch an obvious departure.
#Step 3 — Create the access review definition
Build the review using the Microsoft Graph identity governance API, scoped to the role, with a defined reviewer set, a recurrence pattern, and a defined decision-on-no-response behaviour.
1$body = @{
2 displayName = "Quarterly review - Exchange Administrator"
3 descriptionForAdmins = "Recertification of Exchange Administrator active and eligible assignments"
4 descriptionForReviewers = "Confirm this user still requires Exchange Administrator access"
5 scope = @{
6 "@odata.type" = "#microsoft.graph.accessReviewQueryScope"
7 query = "/roleManagement/directory/roleEligibilitySchedules?$filter=roleDefinitionId eq '$($role.RoleTemplateId)'"
8 queryType = "MicrosoftGraph"
9 }
10 reviewers = @(
11 @{ query = "/groups/{identity-governance-team-object-id}/members"; queryType = "MicrosoftGraph" }
12 )
13 settings = @{
14 mailNotificationsEnabled = $true
15 reminderNotificationsEnabled = $true
16 justificationRequiredOnApproval = $true
17 defaultDecisionEnabled = $true
18 defaultDecision = "Deny"
19 instanceDurationInDays = 14
20 autoApplyDecisionsEnabled = $true
21 recommendationsEnabled = $true
22 recurrence = @{
23 pattern = @{ type = "absoluteMonthly"; interval = 3 }
24 range = @{ type = "noEnd"; startDate = (Get-Date).AddDays(7).ToString("yyyy-MM-dd") }
25 }
26 }
27}
28New-MgIdentityGovernanceAccessReviewDefinition -BodyParameter $bodyExpected result: a review definition object returned with an Id. Write that Id down — you need it for verification and for rollback.

Evidence to capture: the returned JSON object, saved alongside the change ticket.
Checkpoint: confirm startDate is not defaulted to today if the change window has not opened, and confirm the reviewer group actually contains people carrying Entra ID P2 licensing, or the review instance will generate with nobody to notify.
#Step 4 — Exclude break-glass accounts explicitly
Modify the query scope, or use the exclusion capability in the Entra admin centre under Identity Governance, Access reviews, to remove the known break-glass account object IDs from the reviewable population before auto-apply is enabled.
Expected result: break-glass accounts do not appear in the reviewer’s decision list and cannot be auto-removed by a missed deadline.
Checkpoint: inspect the review instance membership once it generates. Break-glass identifiers must be absent — check this yourself, do not take it on trust.
#Step 5 — Pilot on a lower-risk role before touching Global Administrator
Run the first full cycle against Exchange Administrator or Application Administrator, never Global Administrator first. Let that review complete one full instance, including the auto-apply deny-by-default behaviour, before applying the same pattern to the highest-privilege roles in the tenant.
Expected result: a completed review instance with a known decision count, no unexpected mass removal, and reviewer feedback captured for the runbook.
Checkpoint: only proceed to Global Administrator and Privileged Role Administrator once the pilot has run to completion without incident and the pilot change record is formally closed.
#Step 6 — Roll out to Global Administrator with dual reviewer sign-off
For Global Administrator and Privileged Role Administrator, disable self-review and require at least two reviewers from the identity governance team, with defaultDecision still set to “Deny” but a shorter instanceDurationInDays and mandatory justification on every approval.
Expected result: no single reviewer can unilaterally approve continued Global Administrator access, and no assignment survives silently past the review window.

#Step 7 — Wire audit log alerting for auto-apply removals
Create a Log Analytics alert rule against the AuditLogs table, ingested via Entra ID diagnostic settings, filtering on the role removal operation with initiator equal to the access review service principal. This gets the service desk notified before a confused user calls in about lost access.
Expected result: an automated Teams or email alert fires within minutes of any auto-apply removal.
#Verification
1Get-MgIdentityGovernanceAccessReviewDefinition -AccessReviewScheduleDefinitionId $reviewId |
2 Select-Object DisplayName, Status
3
4Get-MgIdentityGovernanceAccessReviewDefinitionInstance -AccessReviewScheduleDefinitionId $reviewId |
5 Select-Object Id, Status, StartDateTime, EndDateTimeRetain, as the audit package, the pre-change CSV baselines from Steps 1 and 2, the review definition JSON, the approved change ticket, the pilot completion record, and a final export of decisions per instance via Get-MgIdentityGovernanceAccessReviewDefinitionInstanceDecision. This bundle is what you hand to an external auditor without reconstructing anything from memory under pressure.
#Failure Modes
| Symptom | Likely cause | Fix |
|---|---|---|
| Reviewers report never receiving an email | Reviewer lacks Entra ID P2 or Governance licence | Assign the licence before recurrence starts; licensing is not retroactive to missed instances |
| Review created but never generates an instance | startDate left in the past or recurrence pattern misconfigured | Patch the definition with Update-MgIdentityGovernanceAccessReviewDefinition and a corrected startDate |
| Break-glass account loses access unexpectedly | Account not excluded from scope before auto-apply enabled | Restore via PIM immediately, then rebuild the scope exclusion before the next cycle |
| Group-assigned role members untouched by the review | Review scoped to direct role assignment only, but the role is actually assigned through a group | Add a second review scoped to the group’s membership, or convert to direct PIM assignment |
| Definition fails to create, referencing a licensing requirement | Tenant lacks the Entra ID Governance or P2 SKU entirely | Confirm licensing in the Entra admin centre under Billing before retrying |
| Auto-apply removes a still-needed admin mid-incident | Instance deadline landed during an active incident window with no reviewer response | Manually reassign the eligible role via PIM, document the exception in the incident record |
#Rollback
If an access review incorrectly strips access, do not wait for the next cycle. First, identify the removed principal from the audit log entry captured in Step 7, or from Get-MgIdentityGovernanceAccessReviewDefinitionInstanceDecision. Then reassign the role through PIM directly:
1$params = @{
2 Action = "AdminAssign"
3 Justification = "Rollback of incorrect access review auto-removal - ticket CHG00123"
4 RoleDefinitionId = $role.RoleTemplateId
5 PrincipalId = $principalId
6 DirectoryScopeId = "/"
7 ScheduleInfo = @{ StartDateTime = (Get-Date); Expiration = @{ Type = "NoExpiration" } }
8}
9New-MgRoleManagementDirectoryRoleEligibilityScheduleRequest -BodyParameter $paramsTo halt a review definition entirely without deleting historical decision records, disable auto-apply rather than deleting the object:
Update-MgIdentityGovernanceAccessReviewDefinition -AccessReviewScheduleDefinitionId $reviewId -BodyParameter @{ settings = @{ autoApplyDecisionsEnabled = $false } }Only use Remove-MgIdentityGovernanceAccessReviewDefinition if the entire review concept was wrong for that role. This deletes past instance history, so export the decision records first — no exceptions.
#Hands-on task
Build a quarterly access review scoped to the Exchange Administrator role, covering eligible and active assignments, reviewers set to the identity governance group, defaultDecision set to Deny, autoApplyDecisionsEnabled true, and break-glass accounts excluded. Submit the returned JSON definition object and both pre-change CSV baselines as your completion artefact.
#Completion check
Confirm the review appears under Identity Governance, Access reviews in the Entra admin centre with a status of “In progress” or “Not started” and a future startDate. Confirm Get-MgIdentityGovernanceAccessReviewDefinition returns the object by Id, and confirm the change ticket is closed with baseline CSVs attached. Read through the vendor documentation on Entra ID access reviews and on creating an access review of role assignments before extending this pattern to additional roles.
#Operational Summary
You now have a recurring, evidenced recertification process for at least one privileged role, with automatic removal of unconfirmed access and an audit log alert covering the blast radius of that automation. The deliverable was never the PowerShell — it is the paper trail: baseline exports, the review definition JSON, pilot results, and decision history sitting in one place before an auditor asks for them. Extend the same pattern role by role, always piloting on lower-risk roles first, and do not enable auto-apply on Global Administrator until the pilot has run clean at least once. That discipline is what separates a control that exists on paper from one that actually holds under audit.
#Learning Objectives
By the end of this enrichment you should be able to explain how the recommendation engine referenced in Step 3 actually derives its Approve or Deny suggestion, how to configure a fallback reviewer so a review instance does not stall when the assigned reviewer has left the group, and how to distinguish the review decision states returned by the Graph API from the coarse Status field already covered in Verification.
Specifically, you should be able to: verify reviewer licensing programmatically before a review definition is created rather than discovering the gap after notifications silently fail; interpret a recommendation value against the sign-in activity window it is calculated from; configure stageSettings and fallbackReviewers on a definition; and read the applyResult field on a decision object to confirm whether an auto-apply action actually completed, is still pending, or failed.
#Worked Example
Before creating the Exchange Administrator review definition in Step 3, confirm every intended reviewer actually holds the required licence, since a missing licence produces a review instance with a populated reviewer list but zero notifications sent and no error surfaced to the administrator. Run Get-MgUser against the identity governance group's members with the LicenseDetails property expanded, for example Get-MgUser -UserId $reviewerId -Property AssignedLicenses,LicenseDetails, and cross-check the returned SKU IDs against the Entra ID P2 or Governance SKU GUID published for the tenant. Capture this output alongside the CSV baselines from Step 1 so the audit package shows reviewer eligibility was checked at build time, not inferred afterwards.
The recommendationsEnabled setting in the review body populates a suggested decision per reviewer, but that suggestion is derived purely from interactive sign-in recency for the principal, typically flagging Deny once a user has shown no interactive sign-in for roughly 30 days. This is a heuristic, not a policy decision, and a reviewer who blindly accepts every recommendation is not performing recertification, only rubber-stamping an activity report. When you present the recommendation column to reviewers, document in the review description for reviewers that the recommendation is advisory and that business justification for continued access still has to be entered manually where justificationRequiredOnApproval is true.
For roles reassigned through groups rather than direct PIM eligibility, per the failure mode already noted for group-assigned roles, a workable pattern is a second, group-membership-scoped review with its own fallbackReviewers entry set to the identity governance mailbox-enabled group, so that if a named reviewer's own account is disabled mid-cycle, the instance still resolves to a live decision path instead of defaulting every member to Deny through inaction.
#Practice Exercise
Using the Exchange Administrator review definition Id you recorded in the Hands-on task, patch the definition to add a fallbackReviewers array containing the identity governance group's object Id, using Update-MgIdentityGovernanceAccessReviewDefinition with a settings block that sets fallbackReviewers to that group. Before applying the patch, export the current settings object with Get-MgIdentityGovernanceAccessReviewDefinition -AccessReviewScheduleDefinitionId $reviewId | Select-Object -ExpandProperty Settings and save it as a pre-change snapshot, since this is the object you will restore from if the fallback configuration behaves unexpectedly.
Validate the change by re-querying the definition and confirming the fallbackReviewers property now reflects the group Id you supplied, then wait for or manually trigger a new instance and confirm via Get-MgIdentityGovernanceAccessReviewDefinitionInstanceDecision that decisions on that instance show a valid reviewedBy value even when the primary reviewer account is temporarily disabled in a test tenant. Roll back by re-applying the pre-change settings snapshot you exported, or by explicitly setting fallbackReviewers back to an empty array in the same Update-MgIdentityGovernanceAccessReviewDefinition call, and confirm the reverted state with a final Get-MgIdentityGovernanceAccessReviewDefinition read before closing the change ticket.
Comments
Add a thoughtful note on Configuring Entra ID Access Reviews for Privileged Roles. Comments are checked for spam and held for moderation before appearing.
Related articles
Enterprise IT Management
Continuous Control Monitoring for SOC 2 Audits
How AWS Config, Okta logs and GitHub audit events feed a continuous control monitoring pipeline that replaces manual SOC 2 evidence pulls.
Enterprise IT Management
Designing a Verifiable IT Management Workflow with Microsoft 365
A bounded Microsoft 365 Conditional Access workflow: staged rollout through report-only evaluation and pilot enforcement, explicit validation gates, and a rehearsed, non-destructive rollback path.
Discover more
Graduate Learning
Ops Playbook
Lexicon Definitions
Learn More About KBY
About KBY
Learn about our mission, editorial standards, and commitment to trusted engineering knowledge.
Why Trust KBY
Explore the processes and policies that ensure our publications are accurate, useful, and responsible.
Newsletter
Get our latest editorial publications, research and practical insights sent directly to your inbox.
Was this useful?
Build practical engineering skills.
Receive new lessons, learning paths, practical exercises and early-career guidance.