In this module

MSA1.6 Directory Structure and Administrative Units

8 hours · Module 1 · Free
What you already know

You've managed user accounts in Entra ID and probably noticed that every administrator role operates at the tenant level. A Helpdesk Administrator can reset any user's password across any site. A User Administrator can modify any user's attributes in any department. In on-premises Active Directory, you'd solve this with Organizational Units and delegated administration — different admins manage different OUs. Entra ID has its own mechanism: Administrative Units. This sub teaches you to design AU structure as architecture — not as admin convenience, but as a security boundary that limits blast radius, enables least-privilege administration, and protects sensitive accounts from unauthorised modification.

Most Entra ID tenants have no Administrative Units. Every administrator role operates at the full tenant scope. A Helpdesk Administrator at one site can reset any user.s password at any other site. A User Administrator in any department can modify user attributes for the Finance team. The blast radius of every administrative action is maximised. In on-premises AD, delegated administration through OUs is standard practice — nobody gives every admin control of every OU. In Entra ID, tenant-wide scope is the default, and most organizations never change it because nothing forces them to. Administrative Units fix this — they're the Entra ID mechanism for creating internal boundaries that scope administrative roles to specific populations.

Estimated time: 45 minutes.

What Administrative Units are — and what they're not

An Administrative Unit is an Entra ID container resource that holds users, groups, and devices. The container's purpose is to scope administrative roles — it determines which identities an administrator can manage. This is fundamentally different from what groups do.

A security group controls what resources its members can access. You add users to a group, then grant the group permissions to applications, SharePoint sites, or Teams. The group is about access. An Administrative Unit controls which administrators can manage specific identities. You add users to an AU, then assign administrative roles scoped to that AU. The AU is about delegation.

A user can be a member of both a security group (for resource access) and an AU (for administrative scoping) simultaneously. The two mechanisms are independent. Adding a user to the "NE-Site-Manchester" AU doesn't change what resources they can access. It changes which administrators can manage their account.

The comparison with Active Directory OUs

In on-premises AD, Organizational Units (OUs) serve both purposes — they're containers for organizing objects and they're the scope for delegated administration. You create an OU for the Manchester site, place Manchester users in it, and delegate Helpdesk and User Management permissions to the Manchester IT team. The OU defines both the organizational structure and the administrative boundary.

Entra ID separates these functions. Groups handle the organizational and access structure. AUs handle the administrative delegation. This separation is architecturally cleaner but requires you to think about delegation as a separate design decision, not a byproduct of your organizational structure.

There's another critical difference: in on-premises AD, every object must be in exactly one OU (objects live in a hierarchical tree). In Entra ID, a user can be in multiple AUs simultaneously. A Finance team member at the Manchester site can be in both the NE-Site-Manchester AU (for site-level delegation) and the NE-Function-Finance AU (for function-level delegation). This enables matrix delegation models that are difficult in AD's hierarchical OU structure.

What AUs cannot do

AUs don't affect Conditional Access policies. You can't create a CA policy that targets "users in the Manchester AU." CA policies target users, groups, roles, and applications — not AUs. If you want site-specific CA policies, you need site-specific groups (MSA1.10 covers this, and MSA3 designs the CA framework).

AUs don't affect license assignment. Licence groups are standard security groups, not AUs.

AUs don't affect application access. Application assignments use groups, users, or roles — not AUs.

Understanding these limitations prevents a common design mistake: trying to use AUs as a general-purpose organizational mechanism when they're specifically an administrative delegation mechanism.

Building AUs with the Graph API

Run this against your tenant to check whether any AUs exist:

Connect-MgGraph -Scopes "AdministrativeUnit.ReadWrite.All","RoleManagement.ReadWrite.Directory"

$existingAUs = Get-MgDirectoryAdministrativeUnit -All
Write-Host "Existing Administrative Units: $($existingAUs.Count)"
Existing Administrative Units: 0

If this returns zero, your tenant has no AUs — every admin role is tenant-scoped. This is the default state for most M365 tenants. If you see AUs listed, examine their scope and membership to understand the existing delegation model.

If your query returns zero AUs, every admin role in your tenant is tenant-scoped — a Global Admin can manage every object, a User Admin can reset every password. AUs are the mechanism for constraining administrative scope, and the rest of this sub designs the AU architecture.

Entra Admin Center

View existing AUs:
IdentityRoles & adminsAdmin units
Lists all AUs in the tenant. For NE, this list is empty.

Create a new AU:
Click Add → enter name and description → choose Assigned or Dynamic membership type → if Dynamic, enter the membership rule → optionally toggle Restricted management administrative unit to Yes → Next → optionally add members → Next → optionally assign roles → Create

Now create the Manchester site AU:

$manchesterAU = New-MgDirectoryAdministrativeUnit -BodyParameter @{
  displayName  = "NE-Site-Manchester"
  description  = "Manchester head office — 310 users. Helpdesk delegation to Manchester IT."
  membershipType = "Assigned"
  visibility   = $null
}
Write-Host "Created: $($manchesterAU.DisplayName)"
Write-Host "ID:      $($manchesterAU.Id)"
Write-Host "Type:    $($manchesterAU.MembershipType)"
Write-Host "Restricted: $($manchesterAU.IsMemberManagementRestricted)"
{
  "id":                          "e5f6a7b8-c9d0-1234-ef56-789012345678",
  "displayName":                 "NE-Site-Manchester",
  "description":                 "Manchester head office — 310 users. Helpdesk delegation to Manchester IT.",
  "membershipType":              "Assigned",
  "membershipRule":              null,
  "membershipRuleProcessingState": null,
  "isMemberManagementRestricted": false,
  "visibility":                   null
}

Every property is an architectural choice:

membershipType: Assigned — members are added individually (by admin or automation). The alternative is Dynamic, where members are added based on a rule expression. Assigned gives you exact control. Dynamic gives you automation. The trade-off is discussed below.

isMemberManagementRestricted: false — standard AU. Tenant-level administrators (Global Admin, Privileged Role Admin) can still modify members. This is correct for operational AUs — you want the central identity team to retain the ability to manage any user in an emergency. Restricted AUs are for protecting critical accounts (discussed below).

visibility: null — standard visibility. AU members are visible to directory queries. The alternative is HiddenMembership, where members are hidden from most directory roles. Hidden AUs have security implications (discussed in the persistence attack section below).

Now populate the AU. For synced users, the on-premises OU path (in OnPremisesDistinguishedName) identifies which site they belong to:

Entra Admin Center

Add members to an AU:
IdentityRoles & adminsAdmin units → select the AU → Users (or Groups / Devices) → Add member → search and select users

The portal adds members one at a time. For bulk population (310 Manchester users), PowerShell is significantly more efficient. For dynamic AUs, members are added automatically — no manual addition needed.

# Find Manchester users by their on-premises OU path
$manchesterUsers = Get-MgUser -All `
  -Filter "onPremisesSyncEnabled eq true" `
  -ConsistencyLevel eventual -CountVariable total `
  -Property Id, DisplayName, OnPremisesDistinguishedName |
  Where-Object { $_.OnPremisesDistinguishedName -match ",OU=Manchester," }

Write-Host "Manchester users found: $($manchesterUsers.Count)"

# Add each user to the AU
$added = 0
foreach ($user in $manchesterUsers) {
  try {
    New-MgDirectoryAdministrativeUnitMemberByRef `
      -AdministrativeUnitId $manchesterAU.Id `
      -BodyParameter @{
        "@odata.id" = "https://graph.microsoft.com/v1.0/users/$($user.Id)"
      }
    $added++
  } catch {
    Write-Host "Failed to add $($user.DisplayName): $($_.Exception.Message)"
  }
}
Write-Host "Added $added users to NE-Site-Manchester"
Manchester users found: 310
Added 310 users to NE-Site-Manchester

Now assign a scoped role. The Helpdesk Administrator role scoped to the Manchester AU means the Manchester IT admin can reset passwords, revoke sessions, and manage MFA methods — but only for users in the Manchester AU:

Entra Admin Center

Assign a scoped role:
IdentityRoles & adminsAdmin units → select the AU → Roles and administratorsAdd assignment → select the role (e.g., Helpdesk Administrator) → select the user → Add
The Assignment type column shows "Administrative unit" confirming the scoping.

Verify from the admin's perspective:
IdentityUsers → select the scoped admin → Assigned roles
The role should show with a Scope value of the AU name rather than "Directory."

# Get the Helpdesk Administrator role template
$helpdeskTemplate = Get-MgDirectoryRoleTemplate |
  Where-Object { $_.DisplayName -eq "Helpdesk Administrator" }

# Assign the role scoped to the Manchester AU
New-MgRoleManagementDirectoryRoleAssignment -BodyParameter @{
  roleDefinitionId = $helpdeskTemplate.Id
  principalId      = "ID-of-Manchester-IT-admin"
  directoryScopeId = "/administrativeUnits/$($manchesterAU.Id)"
}

# Verify the scoped assignment
Get-MgRoleManagementDirectoryRoleAssignment `
  -Filter "directoryScopeId eq '/administrativeUnits/$($manchesterAU.Id)'" |
  Select-Object PrincipalId, RoleDefinitionId, DirectoryScopeId

The directoryScopeId parameter is the architectural key. When set to /administrativeUnits/{au-id}, the role operates within that AU only. Compare this to a tenant-scoped assignment where directoryScopeId is / — that admin can manage every user in the tenant. The difference between / and /administrativeUnits/{au-id} is the difference between a tenant-wide blast radius and a site-limited blast radius.

Verifying the scope works — what a scoped admin can and can't do

The scoping isn't visible in the admin center's role assignment list. You need to test it. Connect as the scoped admin and attempt operations on users inside and outside the AU:

# Connected as the Manchester Helpdesk Admin:

# Test 1 — Reset password for a Manchester user (should succeed)
try {
  $result = Reset-MgUserAuthenticationMethodPassword `
    -UserId "t.ashworth@yourtenant.onmicrosoft.com" `
    -NewPassword "TempP@ss123!" `
    -RequireChangeOnNextSignIn
  Write-Host "Manchester user password reset: SUCCESS"
} catch {
  Write-Host "Manchester user password reset: FAILED — $($_.Exception.Message)"
}

# Test 2 — Reset password for a Newcastle user (should fail — outside AU scope)
try {
  $result = Reset-MgUserAuthenticationMethodPassword `
    -UserId "j.walker@yourtenant.onmicrosoft.com" `
    -NewPassword "TempP@ss123!" `
    -RequireChangeOnNextSignIn
  Write-Host "Newcastle user password reset: SUCCESS (PROBLEM — scope not working)"
} catch {
  Write-Host "Newcastle user password reset: BLOCKED — $($_.Exception.Message)"
}
Manchester user password reset: SUCCESS
Newcastle user password reset: BLOCKED — Insufficient privileges to complete the operation.

The scoped admin can manage Manchester users but is blocked from managing Newcastle users. This is the verification that proves the AU scoping works. Without this test, you're trusting that the directoryScopeId parameter did what you intended — which is configuration without validation.

Creating all six site AUs efficiently

The Manchester AU was created step-by-step for teaching. In practice, create all site AUs in a loop:

# NE site configuration — OU path pattern, expected user count, scoped admin
$sites = @(
  @{ Name="Manchester";  OUPattern="OU=Manchester";  Expected=310; Admin="m.taylor@yourtenant.onmicrosoft.com" }
  @{ Name="Newcastle";   OUPattern="OU=Newcastle";   Expected=180; Admin="j.walker@yourtenant.onmicrosoft.com" }
  @{ Name="Birmingham";  OUPattern="OU=Birmingham";  Expected=120; Admin="s.patel@yourtenant.onmicrosoft.com" }
  @{ Name="Leeds";       OUPattern="OU=Leeds";        Expected=90;  Admin="d.harrison@yourtenant.onmicrosoft.com" }
  @{ Name="Bristol";     OUPattern="OU=Bristol";       Expected=65;  Admin="k.lewis@yourtenant.onmicrosoft.com" }
  @{ Name="Edinburgh";   OUPattern="OU=Edinburgh";    Expected=45;  Admin="r.campbell@yourtenant.onmicrosoft.com" }
)

$helpdeskTemplate = Get-MgDirectoryRoleTemplate |
  Where-Object { $_.DisplayName -eq "Helpdesk Administrator" }

foreach ($site in $sites) {
  # Create the AU
  $au = New-MgDirectoryAdministrativeUnit -BodyParameter @{
    displayName  = "NE-Site-$($site.Name)"
    description  = "$($site.Name) site — $($site.Expected) users. Helpdesk delegation."
    membershipType = "Assigned"
  }
  Write-Host "Created AU: $($au.DisplayName)"

  # Find users by on-premises OU path
  $users = Get-MgUser -All `
    -Filter "onPremisesSyncEnabled eq true" `
    -ConsistencyLevel eventual -CountVariable c `
    -Property Id, OnPremisesDistinguishedName |
    Where-Object { $_.OnPremisesDistinguishedName -match ",$($site.OUPattern)," }

  # Add users to the AU
  $count = 0
  foreach ($user in $users) {
    try {
      New-MgDirectoryAdministrativeUnitMemberByRef `
        -AdministrativeUnitId $au.Id `
        -BodyParameter @{
          "@odata.id" = "https://graph.microsoft.com/v1.0/users/$($user.Id)"
        }
      $count++
    } catch { }  # Skip duplicates silently
  }
  Write-Host "  Added $count users (expected: $($site.Expected))"

  # Assign scoped Helpdesk Administrator
  $admin = Get-MgUser -UserId $site.Admin
  New-MgRoleManagementDirectoryRoleAssignment -BodyParameter @{
    roleDefinitionId = $helpdeskTemplate.Id
    principalId      = $admin.Id
    directoryScopeId = "/administrativeUnits/$($au.Id)"
  }
  Write-Host "  Scoped Helpdesk Admin: $($site.Admin)"
  Write-Host ""
}

# Final summary
$allAUs = Get-MgDirectoryAdministrativeUnit -All
Write-Host "=== AU Summary ==="
$allAUs | Select-Object DisplayName, Id,
  @{N='Members';E={(Get-MgDirectoryAdministrativeUnitMember -AdministrativeUnitId $_.Id -All).Count}} |
  Format-Table -AutoSize
Created AU: NE-Site-Manchester
  Added 310 users (expected: 310)
  Scoped Helpdesk Admin: m.taylor@yourtenant.onmicrosoft.com

Created AU: NE-Site-Newcastle
  Added 180 users (expected: 180)
  Scoped Helpdesk Admin: j.walker@yourtenant.onmicrosoft.com

Created AU: NE-Site-Birmingham
  Added 120 users (expected: 120)
  Scoped Helpdesk Admin: s.patel@yourtenant.onmicrosoft.com

Created AU: NE-Site-Leeds
  Added 90 users (expected: 90)
  Scoped Helpdesk Admin: d.harrison@yourtenant.onmicrosoft.com

Created AU: NE-Site-Bristol
  Added 65 users (expected: 65)
  Scoped Helpdesk Admin: k.lewis@yourtenant.onmicrosoft.com

Created AU: NE-Site-Edinburgh
  Added 45 users (expected: 45)
  Scoped Helpdesk Admin: r.campbell@yourtenant.onmicrosoft.com

=== AU Summary ===
DisplayName           Id                                    Members
-----------           --                                    -------
NE-Site-Manchester    e5f6a7b8-c9d0-1234-ef56-789012345678  310
NE-Site-Newcastle     f6a7b8c9-d0e1-2345-fa67-890123456789  180
NE-Site-Birmingham    a7b8c9d0-e1f2-3456-ab78-901234567890  120
NE-Site-Leeds         b8c9d0e1-f2a3-4567-bc89-012345678901   90
NE-Site-Bristol       c9d0e1f2-a3b4-5678-cd90-123456789012   65
NE-Site-Edinburgh     d0e1f2a3-b4c5-6789-de01-234567890123   45

Synced users distributed across site-based AUs. Each site has a scoped Helpdesk Administrator who can manage only their site's users. Central IT (the security architect, the CISO's team) retains tenant-scoped roles for cross-site management.

Dynamic membership — automation with a trust dependency

Dynamic AUs add members automatically based on a rule expression that evaluates user properties. For large, attribute-driven populations (all Finance users, all Manchester users), dynamic membership eliminates the manual overhead of keeping AU membership in sync with reality.

Entra Admin Center

Create a dynamic AU:
IdentityRoles & adminsAdmin unitsAdd → set Membership type to Dynamic

The Dynamic membership rules editor appears — the same interface used for dynamic security groups. Build rules visually (Property: Department, Operator: Equals, Value: Finance) or switch to the Rule syntax editor for direct expression entry.

The Validate rules tab lets you test whether specific users match the rule before saving. After creation, the Processing status column in the AU list shows whether evaluation is active and when it last processed.

# Create a dynamic AU for Finance
$financeAU = New-MgDirectoryAdministrativeUnit -BodyParameter @{
  displayName     = "NE-Function-Finance"
  description     = "Dynamic AU — all users where Department = Finance"
  membershipType  = "Dynamic"
  membershipRule  = "(user.department -eq `"Finance`")"
  membershipRuleProcessingState = "On"
}
Write-Host "Created dynamic AU: $($financeAU.DisplayName)"
Write-Host "Rule: $($financeAU.MembershipRule)"

The rule evaluates continuously. When a user's Department attribute changes to "Finance" (because HR updated it in on-premises AD and the sync engine propagated it), they're automatically added to the AU. When it changes from "Finance" to something else, they're automatically removed.

But dynamic membership introduces a trust dependency: the accuracy of the attribute the rule evaluates. Query the attribute quality before trusting it for AU membership:

# Assess Department attribute quality across the tenant
$allMembers = Get-MgUser -All -Filter "userType eq 'Member'" `
  -ConsistencyLevel eventual -CountVariable total `
  -Property Department, DisplayName

$withDept = ($allMembers | Where-Object { $_.Department }).Count
$withoutDept = ($allMembers | Where-Object { -not $_.Department }).Count
$deptValues = $allMembers | Where-Object { $_.Department } |
  Group-Object Department | Sort-Object Count -Descending

Write-Host "Department attribute coverage: $withDept / $($withDept + $withoutDept) ($([math]::Round($withDept/($withDept+$withoutDept)*100,1))%)"
Write-Host ""
Write-Host "Top 10 department values:"
$deptValues | Select-Object -First 10 Name, Count | Format-Table -AutoSize
Department attribute coverage: check your count (target: 100%)

Top 10 department values:
Name             Count
----             -----
Engineering        312
IT                  87
Finance             68
Operations          64
Sales               52
HR                  41
Marketing           28
Legal               18
Facilities          12
Executive            5

84.8% coverage means 123 users have no Department set. Those 123 users won't appear in any dynamic AU that evaluates Department. If some of those users are in Finance but their attribute wasn't populated, they'll be invisible to the Finance AU's delegation model — the Finance IT admin won't be able to manage them, and they won't be subject to any Finance-specific policies that reference AU-scoped roles.

The values also reveal data quality issues. "Engineering" has 312 users — is that one department or should it be "Mechanical Engineering," "Civil Engineering," and "Electrical Engineering"? "Executive" has 5 — is that complete, or are some executives classified under their functional department? These questions determine whether the dynamic rule captures the intended population.

The design principle: Use dynamic membership for large operational AUs where the source attribute is reliably maintained (typically by HR via the sync pipeline). Use assigned membership for small, sensitive AUs where exact membership control matters (Executive, Privileged). Never use dynamic membership for AUs that protect critical accounts — a manipulated attribute could remove a protected account from its restricted AU.

How AUs interact with CA, PIM, and access reviews

AUs scope administrative roles. They don't directly control access policies. But they interact with three downstream systems that MSA3, MSA4, and MSA12 design:

Conditional Access — AUs are not CA targets

CA policies target users, groups, roles, and applications. They don't target AUs. You cannot create a CA policy that says "require MFA for users in NE-Site-Manchester AU." If you need site-specific CA policies (for example, requiring device compliance for Manchester users but not for Edinburgh users who use shared workstations), you need a security group that mirrors the AU population.

This means your AU design and your group design must be coordinated. If the Manchester AU has 310 members and the SG-Manchester-Staff group has 308 members (because two users were added to the AU but not the group), the administrative scope and the policy scope are misaligned. MSA1.10 (Group Architecture) addresses this coordination. The practical recommendation: if you use dynamic membership for an AU, use the same dynamic rule for the corresponding security group. If you use assigned membership, automate the synchronization between AU and group membership.

PIM — AU-scoped eligible roles

Privileged Identity Management (MSA4) supports AU-scoped eligible role assignments. An identity architect can make the Manchester IT admin eligible for Helpdesk Administrator scoped to the Manchester AU. The admin activates the role when needed (just-in-time access), provides justification, and the activated role is limited to the AU scope.

This is powerful because it combines two least-privilege mechanisms: time-limited activation (PIM) and scope-limited authorization (AU). The admin doesn't have the role at all times (PIM), and when they activate it, it only applies to Manchester users (AU). Compare this to a permanent, tenant-scoped Helpdesk Administrator assignment — the admin has the role always, and it covers every user.

# Example: Create a PIM-eligible assignment scoped to the Manchester AU
# (This is the Graph API call — MSA4 covers the full PIM design)
$eligibleAssignment = @{
  action           = "adminAssign"
  roleDefinitionId = $helpdeskTemplate.Id
  principalId      = "ID-of-Manchester-IT-admin"
  directoryScopeId = "/administrativeUnits/$($manchesterAU.Id)"
  justification    = "Site-level helpdesk delegation for Manchester office"
  scheduleInfo     = @{
    startDateTime = (Get-Date).ToUniversalTime().ToString("o")
    expiration    = @{
      type     = "afterDuration"
      duration = "P365D"
    }
  }
}

Access reviews — AU membership review

Access reviews (MSA12) can review AU membership. "Are these 310 users still at the Manchester site?" is a valid review question. The review asks a designated reviewer (the Manchester site manager, for example) to confirm each member still belongs. Users who the reviewer marks as "deny" are removed from the AU — and lose the administrative delegation that comes with it.

This is especially important for assigned AUs where membership can drift. Dynamic AUs self-correct (assuming the source attribute is updated), but assigned AUs accumulate members who transfer sites or leave the organization without anyone updating their AU membership.

Restricted management AUs — protecting critical accounts

Standard AUs scope administrative roles, but tenant-level administrators (Global Admin, Privileged Role Admin) can still modify AU members. If a Global Administrator's account is compromised, the attacker can modify any user in any standard AU — reset passwords, change attributes, disable accounts.

Restricted management AUs change this. When isMemberManagementRestricted is set to true, only administrators with roles explicitly scoped to that specific AU can modify its members. Tenant-level administrators — including Global Administrators — receive an error:

Entra Admin Center

Create a restricted management AU:
IdentityRoles & adminsAdmin unitsAdd
Enter name and description. Toggle Restricted management administrative unit to Yes — this is the critical setting.

Restricted AUs display a shield icon in the AU list. Users within a restricted AU show a "Restricted" tag on their profile page. Add members and assign AU-scoped roles using the same process as standard AUs.

# Create a restricted management AU for critical accounts
$restrictedAU = New-MgDirectoryAdministrativeUnit -BodyParameter @{
  displayName = "NE-Restricted-Privileged"
  description = "Break-glass, CISO, sync service accounts. Only Identity Architect can manage."
  membershipType = "Assigned"
  isMemberManagementRestricted = $true
}

# Add break-glass accounts
$bg01 = Get-MgUser -UserId "bg01@yourtenant.onmicrosoft.com"
New-MgDirectoryAdministrativeUnitMemberByRef `
  -AdministrativeUnitId $restrictedAU.Id `
  -BodyParameter @{
    "@odata.id" = "https://graph.microsoft.com/v1.0/users/$($bg01.Id)"
  }

# Assign User Administrator scoped to this AU — ONLY the security architect
New-MgRoleManagementDirectoryRoleAssignment -BodyParameter @{
  roleDefinitionId = (Get-MgDirectoryRoleTemplate |
    Where-Object { $_.DisplayName -eq "User Administrator" }).Id
  principalId      = "ID-of-Marcus-Webb"
  directoryScopeId = "/administrativeUnits/$($restrictedAU.Id)"
}

Now test. A Global Administrator tries to reset bg01's password:

# As Global Admin (without AU-scoped role):
try {
  $newPassword = @{
    passwordProfile = @{
      password = "NewP@ssw0rd!"
      forceChangePasswordNextSignIn = $true
    }
  }
  Update-MgUser -UserId $bg01.Id -BodyParameter $newPassword
  Write-Host "Password reset succeeded"
} catch {
  Write-Host "Error: $($_.Exception.Message)"
}
Error: Target object is a member of a restricted management administrative unit
and can only be modified by administrators scoped to that administrative unit.

The Global Administrator is blocked. Only the security architect (who has User Administrator scoped to the NE-Restricted-Privileged AU) can modify these accounts. This is the architectural protection for break-glass accounts, the CISO's account, and the Cloud Sync service account.

The AU persistence attack — Datadog Security Labs

In September 2024 (updated February 2025), Datadog Security Labs published research demonstrating that restricted management AUs can be weaponised for persistence. The attack scenario unfolds in three steps:

Step 1. An attacker who has already compromised a Global Administrator account creates a new restricted management AU with isMemberManagementRestricted: true.

Step 2. The attacker adds their own controlled account to the restricted AU and assigns themselves an AU-scoped role (User Administrator or Privileged Authentication Administrator) for that AU.

Step 3. When the defending security team discovers the compromise and tries to remediate — disable the attacker's account, remove their roles, delete the account — the restricted AU blocks the action. Even the defender's Global Administrator account can't modify a member of a restricted management AU without an explicit AU-scoped role for that specific AU.

The attacker has created a persistence mechanism that survives the standard remediation playbook. To remove the attacker's account, the defender must: discover the restricted AU exists, understand why their Global Admin can't modify the attacker's account, assign themselves an AU-scoped role for the restricted AU, and then perform the remediation. This multi-step process delays incident response and may not be immediately obvious to a responder who hasn't encountered restricted AUs before.

The research additionally found that hidden membership AUs (created with visibility: HiddenMembership) don't reveal their members to most directory roles. Combining restricted management with hidden membership creates an AU that is hard to find and hard to remediate.

Architectural defense:

Monitor AU creation in the Entra audit log. Any new AU — especially restricted management AUs — should trigger an alert:

# Detection query: list all restricted management AUs
$restrictedAUs = Get-MgDirectoryAdministrativeUnit -All |
  Where-Object { $_.IsMemberManagementRestricted -eq $true }

Write-Host "Restricted management AUs: $($restrictedAUs.Count)"
$restrictedAUs | Select-Object DisplayName, Id, Description,
  @{N='Created';E={$_.Id}} | Format-Table -AutoSize

# Detection query: list all hidden membership AUs
$hiddenAUs = Get-MgDirectoryAdministrativeUnit -All |
  Where-Object { $_.Visibility -eq 'HiddenMembership' }

Write-Host "Hidden membership AUs: $($hiddenAUs.Count)"

Your organization should have a documented, expected set of restricted AUs. Any restricted AU that doesn't match the expected set is suspicious. In the organization's architecture, exactly one restricted AU should exist: NE-Restricted-Privileged. Any additional restricted AU triggers an investigation.

In Sentinel (MSA8), create an analytics rule that fires when the Entra audit log records the creation of an Administrative Unit with isMemberManagementRestricted: true:

AuditLogs
| where OperationName == "Add administrative unit"
| extend Properties = parse_json(tostring(TargetResources[0].modifiedProperties))
| mv-expand Properties
| where Properties.displayName == "IsMemberManagementRestricted"
  and Properties.newValue == "\"true\""
| project TimeGenerated, InitiatedBy, OperationName

This rule is part of the detection architecture you build in MSA9.

Designing your AU structure

The AU structure should reflect your administrative delegation model. Consider two levels of delegation — site-based (who manages users at each location) and function-based (who manages users in sensitive departments):

Administrative Unit              Type        Members    Scoped Roles
-------------------------------  ----------  ---------  ----------------------------
NE-Site-Manchester               Assigned    310 users  Helpdesk Admin (Manchester IT)
NE-Site-Newcastle                Assigned    180 users  Helpdesk Admin (Newcastle IT)
NE-Site-Birmingham               Assigned    120 users  Helpdesk Admin (Birmingham IT)
NE-Site-Leeds                    Assigned     90 users  Helpdesk Admin (Leeds IT)
NE-Site-Bristol                  Assigned     65 users  Helpdesk Admin (Bristol IT)
NE-Site-Edinburgh                Assigned     45 users  Helpdesk Admin (Edinburgh IT)
NE-Function-Finance              Dynamic*    68 users   User Admin (Finance team lead)
NE-Function-Executive            Assigned    12 users   (central IT only — no scoped
                                                         role for non-central admins)
NE-Restricted-Privileged         Restricted  6 accts    User Admin (the security architect ONLY)
                                 Assigned    bg01, bg02,
                                             CISO,
                                             sync svc ×2,
                                             identity arch

* Dynamic rule: (user.department -eq "Finance")
  Prerequisite: Department attribute coverage verified at 84.8%.
  68 Finance users confirmed in the dynamic membership.

Design principles applied:

Site AUs are assigned because the OnPremisesDistinguishedName attribute (which contains the OU path indicating site) isn't directly usable in dynamic AU rules — the membershipRule syntax supports user.onPremisesDistinguishedName but the OU path matching requires a contains operator that can match mid-string, which can produce false positives for similarly named OUs. Assigned membership with automated population via a scheduled script is more reliable.

The Finance AU is dynamic because the Department attribute is well-maintained for Finance users (the Finance team insists on accurate HR data for budgeting). The Executive AU is assigned because executives are a small, sensitive population — dynamic membership based on a job title attribute that might be "CEO," "Chief Executive Officer," or "Managing Director" is too unreliable for a protected population.

The Restricted AU uses assigned membership by definition — you never want dynamic rules controlling which accounts are protected from Global Admin modification. A manipulated attribute could remove a protected account from the restricted AU, exposing it to modification by a compromised Global Admin.

What we see in 90% of tenants (and why it fails)

No Administrative Units at all — the default. Every Helpdesk Administrator in the tenant can reset every user's password. A junior IT admin at a regional site accidentally resets the CISO's password because they clicked the wrong account in the admin center. A disgruntled admin at one site changes attributes on users at another site. An attacker who compromises any admin account has tenant-wide scope for that role's capabilities. The blast radius of every administrative action is maximised because no boundaries exist. And for organizations that do create AUs, the second anti-pattern: they create them but assign all admin roles at tenant scope instead of AU scope — the AUs exist as empty containers that provide no administrative boundary.

Before moving on, verify your understanding: Explain the difference between an AU and a security group. A user is in both "NE-Site-Manchester" AU and "SG-Manchester-Staff" group. What does AU membership control that group membership doesn't? What does group membership control that AU membership doesn't? The Department attribute has 84.8% coverage. Explain the specific consequence for the 123 users without a Department value. If 5 of those users actually work in Finance, what happens to them in the dynamic Finance AU?


Reusable script — the commands from this sub assembled for operational use:

Copy the NE AU design table into your architecture package at 01-identity/au-design.md. Include the design principles (why each AU uses assigned vs dynamic, why the Executive AU doesn't use dynamic, why the Restricted AU is assigned).

For your own organization, answer these design questions:

  1. What are your administrative delegation boundaries? (Sites, regions, departments, business units)
  2. Which user populations need separate administrative scope?
  3. Which attributes are reliable enough for dynamic AU rules? (Run the attribute quality query)
  4. Which accounts need restricted management protection?
  5. How will you keep AU membership and security group membership in sync for CA targeting?

The AU structure feeds into MSA4 (PIM eligible roles scoped to AUs), MSA9 (detection for AU manipulation), and MSA12 (access reviews for AU membership).

Next

MSA1.7 — The Identity Lifecycle. You've structured the directory. MSA1.7 teaches the identity lifecycle — the architectural problem of what happens when someone joins the organization, changes role, and leaves. The lifecycle isn't an HR process. It's the mechanism that determines whether access is correctly provisioned at hire, correctly updated when responsibilities change, and correctly revoked when someone departs. Most organizations handle joining and leaving adequately. Almost none handle the mover stage — and that's where access accumulates silently over years.

You're reading the free modules of m365-security-architecture

The full course continues with advanced topics, production detection rules, worked investigation scenarios, and deployable artifacts.

View Pricing See Full Syllabus