When managing user accounts in Microsoft 365, it's crucial to track actions like hard deletions—permanent removals of user identities from Azure AD. Knowing who was deleted, when, and by whom is vital for security, compliance, and auditing. In this article, we’ll walk through a Graph PowerShell script that fetches hard deleted users using Azure AD audit logs
The following script queries Azure AD audit logs for the activity "Delete user", indicating a hard deletion. It retrieves and displays the:
# Connect to Microsoft Graph
Connect-MgGraph -Scopes "AuditLog.Read.All"
# Define the timeframe (last 30 days)
$startDateTime = (Get-Date).AddDays(-30).ToString("yyyy-MM-ddTHH:mm:ssZ")
# Fetch audit logs where users were permanently deleted
$deletedUserLogs = Get-MgAuditLogDirectoryAudit -Filter "activityDisplayName eq 'Hard Delete user' and activityDateTime ge $startDateTime"
# Create array to store hard deleted users
$hardDeletedUsers = @()
# Loop through the logs to extract user info
foreach ($event in $deletedUserLogs) {
$deletedTime = $event.ActivityDateTime
$deletedUser = ($event.TargetResources | Where-Object { $_.UserPrincipalName }).UserPrincipalName
$deletedBy = $event.InitiatedBy.User.UserPrincipalName
$resultStatus = if ($event.Result -eq 'success') { 'Success' } else { 'Failed' }
# Only include successfully deleted users
if ($resultStatus -eq 'Success' -and $deletedUser) {
$record = [PSCustomObject]@{
"Deleted Time" = $deletedTime
"Deleted User" = $deletedUser
"Deleted By" = $deletedBy
}
$hardDeletedUsers += $record
}
}
# Output the results
if ($hardDeletedUsers.Count -eq 0) {
Write-Host "No hard deleted users found in the last 30 days."
} else {
$hardDeletedUsers | Format-Table -AutoSize
}
Here are ways you can extend or customize the script:
$startDateTime = (Get-Date).AddDays(-90).ToString("yyyy-MM-ddTHH:mm:ssZ") # Last 90 days
$hardDeletedUsers | Export-Csv -Path "HardDeletedUsers.csv" -NoTypeInformation
Want to track deletions by a specific admin?
Where-Object { $_.DeletedBy -eq "admin@yourdomain.com" }
Here’s where this script is particularly useful:
Error | Cause | Solution |
Access Denied or Insufficient Permissions | Missing required permission scopes. | Connect using: Connect-MgGraph -Scopes "AuditLog.Read.All" |
The term 'Get-MgAuditLogDirectoryAudit' is not recognized | Graph module is not installed | Install-Module Microsoft.Graph -Scope CurrentUser Import-Module Microsoft.Graph |
No Results Found | No hard deletions in the date range | Extend the date range or verify that audit logging is enabled in your tenant. |
Tracking hard deleted users is a critical part of Microsoft 365 administration. Whether you're preparing for an audit, investigating suspicious activity, or maintaining clean records, this Graph PowerShell script provides a clear, efficient way to retrieve deletion data from your Azure AD audit logs.
Use this script to strengthen your security posture, maintain accountability, and ensure compliance across your organization.
© m365corner.com. All Rights Reserved. Design by HTML Codex