Simplify user tasks like bulk creation, updates, password resets, deletions, license checks & more — all from one place.
🚀 Launch ToolkitWhen you’re auditing access or validating delegated administration, you often need more than just AU names—you need a quick sense of how many objects are scoped inside each AU. This script exports every AU along with a MemberCount to a CSV. The file is perfect for audit trails, RBAC reviews, capacity planning, and governance reports where the AU Id and member totals are crucial.
# Connect to Microsoft Graph (run once per session)
Connect-MgGraph -Scopes "AdministrativeUnit.Read.All","Directory.Read.All"
# Output path (timestamped to avoid overwrites)
$OutputPath = ".\AdministrativeUnits_WithMemberCounts_{0}.csv" -f (Get-Date -Format "yyyyMMdd_HHmmss")
# Get all AUs with key properties
$aus = Get-MgDirectoryAdministrativeUnit -All -Property Id,DisplayName,Description
if (-not $aus) {
Write-Warning "No Administrative Units were found in the tenant."
$aus = @()
}
# Build rows with a MemberCount column
$rows = @()
$total = ($aus | Measure-Object).Count
$index = 0
foreach ($au in $aus) {
$index++
Write-Progress -Activity "Counting AU members" -Status "AU $index of $total" -PercentComplete (($index/$total)*100)
# Count members (users/devices/groups) for the AU
$memberCount = $null
try {
$memberCount = (Get-MgDirectoryAdministrativeUnitMember `
-AdministrativeUnitId $au.Id -All -Property Id -ConsistencyLevel eventual | Measure-Object).Count
} catch {
Write-Warning "Could not count members for AU '$($au.DisplayName)' ($($au.Id)): $($_.Exception.Message)"
$memberCount = $null
}
$rows += [pscustomobject]@{
Id = $au.Id
DisplayName = $au.DisplayName
Description = $au.Description
MemberCount = $memberCount
}
}
# Export to CSV (UTF-8)
$rows | Export-Csv -Path $OutputPath -NoTypeInformation -Encoding UTF8
Write-Host "Export complete: $OutputPath (AUs: $($rows.Count))"
# Filter by name prefix
$aus = Get-MgDirectoryAdministrativeUnit -Filter "startswith(displayName,'EMEA')" -ConsistencyLevel eventual -All -Property Id,DisplayName,Description
# Search by keyword
$aus = Get-MgDirectoryAdministrativeUnit -Search '"marketing"' -ConsistencyLevel eventual -All -Property Id,DisplayName,Description
Replace the single MemberCount with simple post-processing by inspecting @odata.type from Get-MgDirectoryAdministrativeUnitMember and tallying into UserCount, GroupCount, DeviceCount.
Create a JSON alongside the CSV:
$rows | ConvertTo-Json -Depth 6 | Out-File ($OutputPath -replace '\.csv$','.json') -Encoding utf8
| Error | Cause | Solution |
|---|---|---|
| Authorization_RequestDenied / Insufficient privileges | Missing Graph permission/consent. | Connect with AdministrativeUnit.Read.All (or Directory.Read.All), consent when prompted, then re-run the script. |
| Request_UnsupportedQuery (with -Filter/-Search) | Unsupported property or malformed OData, or search not enabled for that field. | Use filterable props like displayName. Keep filters simple (eq, startswith). For broad matching use -Search '"term"' and add -ConsistencyLevel eventual. |
| ResourceNotFound / 404 while counting members | AU Id is wrong or the AU was deleted mid-run. | Re-list AUs to confirm the Id, then re-run. |
| TooManyRequests / 429 throttling | Rapid per-AU member calls. | Re-run at off-peak, pause between iterations (e.g., Start-Sleep -Seconds 1), or reduce any parallelism if you added it. |
| Empty/Null MemberCount for some AUs | Transient API issues or access limitations on specific objects. | Re-run the script; if persistent, verify permissions and try on a smaller subset using -Filter to isolate. |
This no-functions script produces a clean CSV with AU Ids, names, descriptions, and member counts—exactly what admins need for audits, RBAC reviews, and governance. It’s easy to read, easy to run, and simple to extend with filters, per-type counts, or alternate output formats.
© m365corner.com. All Rights Reserved. Design by HTML Codex