All scripts
Governance 214

Get-EntraStaleGuestAccounts

Finds guest accounts that have never signed in, or not signed in for a long time, so they can be reviewed and removed instead of accumulating indefinitely.

Get-EntraStaleGuestAccounts.ps1
<#
.SYNOPSIS
    Finds inactive or never-signed-in guest accounts.

.DESCRIPTION
    Checks last sign in activity for every guest account and flags any
    that have never signed in or have been inactive longer than a
    configurable threshold, so stale guest access gets reviewed instead
    of accumulating indefinitely.

.PARAMETER InactiveDays
    Days of inactivity before a guest is flagged. Defaults to 90.

.EXAMPLE
    .\Get-EntraStaleGuestAccounts.ps1 -InactiveDays 120

.NOTES
    Requires Microsoft.Graph.Users and Microsoft.Graph.Reports with an
    active Connect-MgGraph session and AuditLog.Read.All scope.

.AUTHOR
    Shehryar Hassan
#>

param(
    [int]$InactiveDays = 90
)

$cutoff = (Get-Date).AddDays(-$InactiveDays)
$guests = Get-MgUser -Filter "userType eq 'Guest'" -All -Property Id,DisplayName,Mail,SignInActivity

$stale = $guests | Where-Object {
    -not $_.SignInActivity.LastSignInDateTime -or $_.SignInActivity.LastSignInDateTime -lt $cutoff
} | Select-Object DisplayName, Mail, @{N="LastSignIn";E={$_.SignInActivity.LastSignInDateTime}}

$stale | Sort-Object LastSignIn | Format-Table -AutoSize
Write-Host "$($stale.Count) of $($guests.Count) guest account(s) are stale (no sign in within $InactiveDays days)" -ForegroundColor Cyan

Read it before you run it, and test in a safe tenant first.