Top 5 Scripts Every M365 Admin Should Use to Track Admin Role Activity

Keeping track of admin roles is critical for securing your Microsoft 365 tenant. Privileged role misuse, accidental assignments, or orphaned roles can leave you exposed to serious risk.

Below are 5 essential Graph PowerShell scripts to help M365 admins audit, track, and stay in control of admin role activity.

List All Global Administrators

# Get all directory roles
$roles = Get-MgDirectoryRole
# Find the role ID for global administrators
$globalAdminRole = $roles | Where-Object { $_.DisplayName -eq "Global Administrator" }
# Initialize counts and arrays for storing details
$totalGlobalAdmins = 0
$globalAdminDetails = @()
# Get the members of the global administrator role
if ($globalAdminRole -ne $null) {
    $globalAdmins = Get-MgDirectoryRoleMember -DirectoryRoleId $globalAdminRole.Id -All
    $totalGlobalAdmins = $globalAdmins.Count
    $globalAdmins | ForEach-Object {
        $user = Get-MgUser -UserId $_.Id
        $globalAdminDetails += [PSCustomObject]@{
            DisplayName = $user.DisplayName
            Email = $user.UserPrincipalName
        }
    }
}

Write-Output "Total Global Administrators: $totalGlobalAdmins"
Write-Output "Global Administrators Details:"
$globalAdminDetails | Format-Table -AutoSize

List All Admin Roles and Assigned Users

$roles = Get-MgDirectoryRole
foreach ($role in $roles) {
    Write-Host "`nRole: $($role.DisplayName)"
    $members = Get-MgDirectoryRoleMember -DirectoryRoleId $role.Id
    foreach ($member in $members) {
        Write-Output " - $($member.AdditionalProperties.displayName) ($($member.AdditionalProperties.userPrincipalName))"
    }
}

Track Role Assignment Changes via Audit Logs

Get-MgAuditLogDirectoryAudit -Filter "activityDisplayName eq 'Add member to role' or activityDisplayName eq 'Remove member from role'" `
                             -Property activityDisplayName, initiatedBy, targetResources, activityDateTime `
                             -All |
Select-Object activityDisplayName, activityDateTime,
              @{Name="InitiatedBy";Expression={$_.initiatedBy.user.displayName}},
              @{Name="TargetUser";Expression={$_.targetResources[0].displayName}}

Get Role Assignments Without Owners (Orphaned Roles)

$roles = Get-MgDirectoryRole

foreach ($role in $roles) {
    $members = Get-MgDirectoryRoleMember -DirectoryRoleId $role.Id
    if (-not $members) {
        Write-Output "Orphaned Role: $($role.DisplayName)"
    }
}

Export All Admin Role Assignments to CSV

$report = @()

$roles = Get-MgDirectoryRole

foreach ($role in $roles) {
    $members = Get-MgDirectoryRoleMember -DirectoryRoleId $role.Id
    foreach ($member in $members) {
        $report += [pscustomobject]@{
            RoleName = $role.DisplayName
            DisplayName = $member.AdditionalProperties.displayName
            UserPrincipalName = $member.AdditionalProperties.userPrincipalName
        }
    }
}

$report | Export-Csv "AdminRoleAssignments.csv" -NoTypeInformation

Final Thoughts

Tracking admin role activity isn’t optional — it’s a fundamental part of Microsoft 365 security. These 5 scripts will help you maintain transparency, control, and compliance in your tenant, while also alerting you to risky gaps in privilege assignment.

Did You Know? Managing Microsoft 365 applications is even easier with automation. Try our Graph PowerShell scripts to automate tasks like generating reports, cleaning up inactive Teams, or assigning licenses efficiently.

Ready to get the most out of Microsoft 365 tools? Explore our free Microsoft 365 administration tools to simplify your administrative tasks and boost productivity.

© Your Site Name. All Rights Reserved. Design by HTML Codex