How to find and remove stale guest users in Microsoft 365
This guide shows how to list guest accounts that have not signed in for a long time, review them with their owners and remove them safely. It is written for Microsoft 365 and Entra administrators who want to reduce external access without breaking active collaboration.
Before you start
- Roles: Reporting needs a role that can read users and sign-in activity, such as Global Reader or Reports Reader. Blocking or deleting guests needs User Administrator or Global Administrator.
- Licences: the sign-in activity property needs Microsoft Entra ID P1 or higher. Access reviews need Microsoft Entra ID P2 or Microsoft Entra ID Governance.
- Tools: the Microsoft Entra admin center and the Microsoft Graph PowerShell module.
- Decide what stale means: pick a number of days that fits your business, for example the longest gap between two projects. Write it down so the clean-up is repeatable.
- Tell the business first. Guests are often tied to a Microsoft 365 group, a Teams team or a shared site. Removing a guest removes that access.
Step by step
- List guests with their last sign-in. Run the read-only report below and export it to CSV. Guests with an empty last sign-in have no recorded sign-in at all.
- Add the invitation state. A guest whose
externalUserStateisPendingAcceptancenever redeemed the invitation. These are the safest to clean up first. - Find the owner. For each remaining stale guest, check which groups and teams they belong to, and ask those owners whether the access is still needed.
- Prefer an access review for the ongoing process. In the Microsoft Entra admin center go to ID Governance > Access reviews > New access review, choose Teams + Groups, scope it to guest users only, set a recurrence and let group owners be the reviewers. Decide what happens when nobody responds, and consider enabling automatic application of results.
- Block before you delete. For guests you are unsure about, disable sign-in first and wait a defined period, such as 30 days, to see whether anyone complains.
- Delete confirmed stale guests. A deleted user can be restored from Entra ID > Users > Deleted users within 30 days.
- Tighten who can invite. Review Entra ID > External Identities > External collaboration settings to restrict guest access, limit invitations to the Guest Inviter role and allow only approved domains, so the problem does not return.
These commands change your tenant. Run them only on a reviewed list, and start with a test account. Disabling is reversible at once. Deleting is reversible for 30 days.
# CHANGE: block sign-in for one reviewed guest (reversible)
Connect-MgGraph -Scopes "User.ReadWrite.All"
Update-MgUser -UserId "<guest-object-id>" -AccountEnabled:$false
# CHANGE: delete one reviewed guest (soft delete, restorable for 30 days)
Remove-MgUser -UserId "<guest-object-id>"Check it worked
This report only reads data. Run it before any change to build the list, and again afterwards to confirm the stale guests are gone or disabled. Replace 90 with your own threshold.
Connect-MgGraph -Scopes "User.Read.All","AuditLog.Read.All"
$cutoff = (Get-Date).AddDays(-90)
Get-MgUser -Filter "userType eq 'Guest'" -All `
-Property Id,DisplayName,UserPrincipalName,CreatedDateTime,ExternalUserState,AccountEnabled,SignInActivity |
Where-Object {
$last = $_.SignInActivity.LastSignInDateTime
-not $last -or $last -lt $cutoff
} |
Select-Object DisplayName, UserPrincipalName, CreatedDateTime,
ExternalUserState, AccountEnabled,
@{n="LastSignIn";e={$_.SignInActivity.LastSignInDateTime}} |
Sort-Object LastSignIn |
Export-Csv -Path ./stale-guests.csv -NoTypeInformationAfter clean-up, the list should shrink to guests you have decided to keep. If a guest you removed was needed, restore it from Deleted users.
Common mistakes
- Treating an empty last sign-in as proof of abandonment. It can also mean a very recent invitation. Check the created date first.
- Deleting without asking owners. The guest may be the only external member of a team or a shared site.
- Skipping the block step. Disabling first gives you a quiet, reversible trial of the removal.
- Running a one-time clean-up and stopping. Guests accumulate again. Set up a recurring access review.
- Forgetting the invite settings. If anyone can invite anyone, the stale list will refill.
- Deleting from an unreviewed export. Always read the list before you pipe it into a change command.
How ConfigCobra helps
ConfigCobra is read-only and never changes your tenant, so it does not remove guests itself. Its Microsoft 365 inventory lists your users and guests, and the built-in Guests who never signed in risk view shows the never-used guest accounts without a script, with CSV export. The relation graph shows how a guest connects to groups, ownership and Conditional Access scope. Related CIS benchmark controls cover guest access restrictions, invitation limits and access reviews for guest users, and a scan reports whether each passes. For a failing control, remediation impact analysis shows who and what a fix would affect before you apply it, and each finding comes with a copy-paste remediation script or portal steps. Continuous scanning and drift detection alert you when a control regresses.
Go further
- All guidesAdmin how-tos for Microsoft 365, Azure, Google Cloud and AWS
- Check libraryEvery CIS check, explained
- RemediationSee what a fix changes in your tenant before you apply it, then use the generated script
- Inventory & InsightsEvery user, app, device and resource in one inventory, with built-in risk views
See where your Microsoft 365 stands
A read-only assessment against the CIS benchmarks, prioritised so you know what to fix first.