Simplify user tasks like bulk creation, updates, password resets, deletions, license checks & more โ all from one place.
๐ Launch ToolkitGlobal Administrators hold the highest level of privileges in Microsoft 365. Keeping track of who holds this role is vital for security, compliance, and operational governance.
This simple script retrieves all Global Admins in your tenant and sends the list as a CSV attachment to a designated administrator via Microsoft Graph PowerShell.
# ===== Simple Graph PowerShell Script =====
# Fetch all GLOBAL ADMINS and email the list to admin
# Requires: Microsoft.Graph module
# Scopes: Directory.Read.All, User.Read.All, Mail.Send
# --- Variables ---
$FromUser = "admin@contoso.com" # Sender (must have mailbox)
$To = "it-ops@contoso.com" # Recipient
$Subject = "Global Administrators report"
$CsvOutDir = "$env:TEMP"
# --- Connect to Microsoft Graph ---
Import-Module Microsoft.Graph -ErrorAction Stop
Connect-MgGraph -Scopes "Directory.Read.All","User.Read.All","Mail.Send"
# --- Resolve the 'Global Administrator' role object (handles legacy name too) ---
$globalRole = Get-MgDirectoryRole -Filter "displayName eq 'Global Administrator'"
if (-not $globalRole) {
$globalRole = Get-MgDirectoryRole -Filter "displayName eq 'Company Administrator'"
}
if (-not $globalRole) {
throw "Couldn't find the 'Global Administrator' (Company Administrator) role in this tenant."
}
# --- Get role members (directory objects) ---
$members = Get-MgDirectoryRoleMember -DirectoryRoleId $globalRole.Id -All
# --- Resolve only users (skip groups/service principals/devices) ---
$admins = foreach ($m in $members) {
try {
Get-MgUser -UserId $m.Id -Property Id,DisplayName,UserPrincipalName,JobTitle,Department,AccountEnabled -ErrorAction Stop
} catch {
# Not a user or not accessible; skip
}
}
# --- Export to CSV ---
if (-not (Test-Path -Path $CsvOutDir)) { New-Item -ItemType Directory -Path $CsvOutDir | Out-Null }
$ts = Get-Date -Format "yyyyMMdd_HHmmss"
$csvPath = Join-Path $CsvOutDir ("GlobalAdmins_{0}.csv" -f $ts)
$admins | Select-Object DisplayName,UserPrincipalName,JobTitle,Department,AccountEnabled,Id |
Export-Csv -Path $csvPath -NoTypeInformation -Encoding UTF8
# --- Prepare HTML Body ---
$summaryHtml = @"
<html>
<body style='font-family:Segoe UI,Arial,sans-serif'>
<h3>Global Administrators Report</h3>
<p>Total global admins: <b>$($admins.Count)</b></p>
<p>The full list is attached as a CSV.</p>
</body>
</html>
"@
# --- Prepare Attachment ---
$fileBytes = [System.IO.File]::ReadAllBytes($csvPath)
$base64Content = [System.Convert]::ToBase64String($fileBytes)
$csvFileName = [System.IO.Path]::GetFileName($csvPath)
$attachment = @{
"@odata.type" = "#microsoft.graph.fileAttachment"
name = $csvFileName
contentBytes = $base64Content
contentType = "text/csv"
}
# --- Prepare Mail Object ---
$mail = @{
message = @{
subject = "${Subject}"
body = @{
contentType = "HTML"
content = $summaryHtml
}
toRecipients = @(@{ emailAddress = @{ address = $To } })
attachments = @($attachment)
}
saveToSentItems = $true
}
# --- Send Email ---
Send-MgUserMail -UserId $FromUser -BodyParameter $mail
Write-Host "Done. CSV saved at: $csvPath" -ForegroundColor Green
You define the sender and recipient email addresses, email subject, and CSV export location.
The script loads the Microsoft Graph PowerShell module and signs in with delegated permissions:
The script checks for directory objects designated with role Global Administrator.
Get-MgDirectoryRoleMember retrieves all members of the Global Admin role. These can include users, groups, service principals, or devices.
The loop tries Get-MgUser for each ID. If itโs a user, details like DisplayName, UPN, JobTitle, Department, and AccountEnabled status are returned; non-user IDs are skipped.
The user list is saved to a timestamped CSV file.
The script creates a simple HTML summary, attaches the CSV, and sends it from $FromUser to $To using Send-MgUserMail.
Error | Cause | Solution |
---|---|---|
Authorization_RequestDenied | Missing required Graph scopes or consent not granted | Reconnect with Directory.Read.All, User.Read.All, and Mail.Send scopes; ensure admin consent. |
Couldn't find the 'Global Administrator' | Role name mismatch or role not activated in the tenant | Check with Get-MgDirectoryRole to confirm active roles; enable via Azure AD portal if needed. |
Get-MgUser not recognized | Users module not installed | Install unified Microsoft.Graph or Microsoft.Graph.Users module. |
Empty CSV output | No active global admins or IDs resolved as groups/devices | Verify in Entra admin center and adjust role membership if necessary. |
Email not sent | $FromUser account lacks a mailbox or send rights | Use a mailbox-enabled account with permissions to send to $To. |
This script gives you a straightforward way to identify all Global Administrators in your Microsoft 365 tenant and deliver that list directly to an adminโs inbox. With minimal modification, it can become part of a regular security and compliance reporting process, ensuring your privileged access is always under control.
© m365corner.com. All Rights Reserved. Design by HTML Codex