One of the most overlooked risks in Microsoft 365 environments is when disabled accounts still hold admin privileges. These accounts might have been offboarded improperly or simply forgotten, yet they retain access to sensitive administrative capabilities.
This article walks you through a Graph PowerShell script that helps you identify all disabled users assigned to admin roles—an essential step in maintaining a secure and compliant M365 tenant.
# Connect to Microsoft Graph
Connect-MgGraph -Scopes "RoleManagement.Read.Directory", "Directory.Read.All", "User.Read.All"
# Get all active directory roles (e.g., Global Admin, Helpdesk Admin)
$activatedRoles = Get-MgDirectoryRole -All
# Hashtable to track disabled admin users
$disabledAdminUsers = @{}
foreach ($role in $activatedRoles) {
try {
# Get members of the current role
$members = Get-MgDirectoryRoleMember -DirectoryRoleId $role.Id -All
foreach ($member in $members) {
# Process only user objects
if ($member.AdditionalProperties.'@odata.type' -eq "#microsoft.graph.user") {
$userId = $member.Id
# Fetch full user object
$user = Get-MgUser -UserId $userId -Property DisplayName, UserPrincipalName, AccountEnabled
# Include only disabled accounts
if (-not $user.AccountEnabled) {
if ($disabledAdminUsers.ContainsKey($userId)) {
# Append new role to existing user
$disabledAdminUsers[$userId].'Admin Role Assigned' += ", $($role.DisplayName)"
} else {
# Add new entry
$disabledAdminUsers[$userId] = [PSCustomObject]@{
'Admin Name' = $user.DisplayName
'User Principal Name' = $user.UserPrincipalName
'Sign In Status' = "Disabled"
'Admin Role Assigned' = $role.DisplayName
}
}
}
}
}
} catch {
Write-Warning "Error while processing role '$($role.DisplayName)': $_"
}
}
# Display final result
if ($disabledAdminUsers.Count -eq 0) {
Write-Host "No disabled users with admin roles were found." -ForegroundColor Yellow
} else {
$disabledAdminUsers.Values | Sort-Object 'Admin Name' | Format-Table -AutoSize
}
Here’s what happens under the hood:
You can easily build on this script:
$user = Get-MgUser -UserId $userId -Property DisplayName, UserPrincipalName, JobTitle, Department, AccountEnabled
For documentation or audit purposes:
$disabledAdminUsers.Values | Export-Csv -Path "DisabledAdminUsers.csv" -NoTypeInformation
With an approval workflow in place, use Remove-MgDirectoryRoleMemberByRef to clean up roles.
Error Message | Cause | Solution |
No activated roles found | No roles are currently active in your tenant | Activate roles in the Azure Portal or via Graph Explorer |
Get-MgDirectoryRoleMember : Access Denied | Missing required permissions or insufficient rights | Use Connect-MgGraph with appropriate delegated scopes |
@odata.type not accessible | The member object structure doesn't expose this directly | Access it using .AdditionalProperties.'@odata.type' |
Cannot bind argument to parameter...it is null | The user object is null or not of the expected type | Ensure only #microsoft.graph.user types are processed |
Here are real-world scenarios where this script provides high value:
Leaving disabled users assigned to admin roles is a major security loophole in any Microsoft 365 tenant. This Graph PowerShell script helps plug that gap by giving you clear visibility into these accounts, their sign-in status, and their role assignments.
By using this script as part of your routine administrative checks, you ensure that no dormant but privileged accounts linger undetected in your environment.
© m365corner.com. All Rights Reserved. Design by HTML Codex