Why Do You Need This Script?
Guest users in Entra ID (formerly Azure AD) are external users invited to collaborate within an organization. However, many guests:
🔹 Never accept their invitations
🔹 Stop using their accounts after a period of time
🔹 Pose a security risk if their access isn’t revoked
To maintain security and compliance, IT administrators must track and manage guest users regularly. Manually reviewing thousands of guest accounts is time-consuming and error-prone—that’s where PowerShell automation comes in.
This script provides:
✅ An export of all guest users
✅ A list of users who never accepted their invite
✅ A list of users who haven’t signed in for the last 30 days
✅ An option to delete inactive guest users in bulk
PowerShell Script to Manage Guest Users
# Connect to Microsoft Graph
Connect-MgGraph -Scopes "User.Read.All", "Directory.ReadWrite.All"
# Define export location
$ExportPath = "C:\Entra ID\Guest Users"
If (!(Test-Path -Path $ExportPath)) { New-Item -ItemType Directory -Path $ExportPath }
# Function to write logs
Function Write-Log {
param ([string]$message)
$logFile = "$ExportPath\GuestUserLog.txt"
"$((Get-Date).ToString('yyyy-MM-dd HH:mm:ss')) - $message" | Out-File -Append -FilePath $logFile
}
# Get all guest users
$GuestUsers = Get-MgUser -Filter "UserType eq 'Guest'" -All
# Export all guest users
$GuestUsers | Select-Object DisplayName, UserPrincipalName, CreatedDateTime, SignInActivity |
Export-Csv -Path "$ExportPath\AllGuestUsers.csv" -NoTypeInformation
Write-Log "Exported all guest users."
# Find users who never accepted invites
$PendingInvites = $GuestUsers | Where-Object { $_.SignInActivity.LastSignInDateTime -eq $null }
# Export users who never accepted invites
$PendingInvites | Select-Object DisplayName, UserPrincipalName |
Export-Csv -Path "$ExportPath\PendingInvites.csv" -NoTypeInformation
Write-Log "Exported guest users who never accepted invites."
# Find users who haven’t signed in for 30 days
$InactiveUsers = $GuestUsers | Where-Object { $_.SignInActivity.LastSignInDateTime -lt (Get-Date).AddDays(-30) }
# Export inactive users
$InactiveUsers | Select-Object DisplayName, UserPrincipalName, LastSignInDateTime |
Export-Csv -Path "$ExportPath\InactiveUsers.csv" -NoTypeInformation
Write-Log "Exported guest users who have not signed in for 30 days."
# Delete inactive users
Function Delete-Users {
param ($csvFile)
$UsersToDelete = Import-Csv -Path $csvFile
foreach ($user in $UsersToDelete) {
try {
Remove-MgUser -UserId $user.UserPrincipalName -Confirm:$false
Write-Log "Deleted user: $($user.UserPrincipalName)"
} catch {
Write-Log "Error deleting user: $($_.Exception.Message)"
}
}
}
# Provide options to the admin
Write-Host "Select an option: `n1. Export all guest users`n2. Export users who never accepted invites`n3. Export inactive users (30+ days)`n4. Delete inactive users"
$choice = Read-Host "Enter choice (1-4)"
Switch ($choice) {
1 { Invoke-Item "$ExportPath\AllGuestUsers.csv" }
2 { Invoke-Item "$ExportPath\PendingInvites.csv" }
3 { Invoke-Item "$ExportPath\InactiveUsers.csv" }
4 { Delete-Users "$ExportPath\InactiveUsers.csv" }
}
Disconnect-MgGraph
Benefits of This Script
🔹 Security: Reduces stale guest accounts that may pose a risk.
🔹 Compliance: Ensures only active users have access.
🔹 Efficiency: Automates guest user management, saving hours of manual work.
This script helps organizations clean up inactive guest users, track pending invites, and remove security risks automatically. 🚀