Entra ID Guest Account Cleanup: How to Audit and Remove Stale B2B External Users Without Cutting Off Active Partners

Retool's new app builder is where AI-generated code ships safely
Building apps with AI is easy. Getting them to production safely is another story.
When you inherit an Entra ID tenant that has been running without a guest lifecycle policy, the guest account list tells a history of every partner engagement, vendor relationship, contractor stint, and conference collaboration over the past five years. Most of those relationships ended. The accounts did not.
The cleanup project looks straightforward until you start it. The first challenge is that revoking a guest who still has SharePoint site ownership, a Teams channel membership, or a shared mailbox delegation breaks something silently. The second challenge is that the original inviter often left the company, so there is no one to confirm whether the account is still needed. The third challenge is that Entra ID does not expose last sign-in data to most admin interfaces by default.
This guide covers how to build a complete guest account inventory using the Microsoft Graph API, how to risk-tier every account into actionable categories, and how to execute the cleanup safely using a disable-first approach that catches active accounts before you cut them off.
Build the complete guest inventory with Graph API
The Entra ID admin portal's Users list shows guest accounts but does not surface the last sign-in date without clicking into each record. For any tenant with more than 50 guests, you need the Graph API.
The critical field is signInActivity, which exposes lastSignInDateTime and lastNonInteractiveSignInDateTime. This field requires an Entra ID P1 or P2 license on the tenant. If your tenant does not have P1 or P2, you will not see sign-in data and will need to rely on account age alone.
The Graph API query to pull all guest accounts with sign-in data: GET https://graph.microsoft.com/v1.0/users?$filter=userType eq 'Guest'&$select=displayName,mail,userPrincipalName,createdDateTime,signInActivity,accountEnabled&$top=999
Run this with the Microsoft Graph PowerShell module: Connect-MgGraph -Scopes 'User.Read.All', 'AuditLog.Read.All' then Get-MgUser -Filter "userType eq 'Guest'" -Property DisplayName,Mail,UserPrincipalName,CreatedDateTime,SignInActivity,AccountEnabled -All.
Export to CSV and sort by LastSignInDateTime ascending. Accounts at the top of that list are your highest-priority cleanup candidates.
Risk-tier every account before touching anything
Bulk deletion of guest accounts without tiering causes two categories of pain: breaking active partner integrations, and generating legitimate access complaints that erode trust in the security program. The solution is a four-tier risk model that maps to a specific action for each tier.
Tier 1: Never signed in AND account age greater than 90 days. These accounts received an invitation that was either ignored or the link expired before first use. They have no active sessions, no cached tokens, and likely no access to resources they are using. Safe to disable immediately and delete after 30 days.
Tier 2: Last sign-in greater than 90 days ago. The partner accessed the tenant at some point but has been inactive for at least three months. Risk here depends on what the account has access to. Check group memberships (GET /v1.0/users/{id}/memberOf) and SharePoint role assignments before disabling.
Tier 3: Last sign-in between 30 and 90 days ago. Active enough to warrant a sponsor confirmation email before any action. Send the business owner a notification with a 14-day response window. No response equals Tier 2 treatment after the window closes.
Tier 4: Sign-in within the last 30 days. Do not touch. Add to the active guest register with a documented sponsor and schedule for next review cycle.
Briefings like this, every morning before 9am.
Threat intel, active CVEs, and campaign alerts, distilled for practitioners. 50,000+ subscribers. No noise.
The sponsor problem and how to resolve it
The most common blocker in guest cleanup projects is that the original inviter has left the organization. Entra ID records the inviting user's UPN in the createdBy field, but if that user's account is deleted, the field returns null or an orphaned reference.
For accounts with no traceable sponsor, the resolution process has three steps. First, look up the guest's email domain and cross-reference it against your organization's active vendor and partner list. If the domain belongs to a current vendor, route the account to the vendor relationship owner for confirmation. Second, check the guest's group memberships and SharePoint access. If the account has access to a SharePoint site owned by a specific department, that department's IT liaison becomes the default owner for the cleanup decision. Third, if neither step produces an owner within 14 days, treat the account as ownerless and proceed with disable.
Document every owner assignment in a guest account register. This register becomes the foundation of your lifecycle policy: every new guest invitation must have a sponsor recorded at creation time.
Safe cleanup: disable first, delete after 30 days
Never delete guest accounts directly without a disable-and-wait period. Disabling an account (accountEnabled = false) blocks all new sign-ins but preserves the account record, group memberships, and access assignments. This lets you catch the case where the partner was actually active but had not signed in recently because they use a service account or certificate-based flow.
Disable via Graph API: PATCH /v1.0/users/{id} with body {accountEnabled: false}. Or via PowerShell: Update-MgUser -UserId {id} -AccountEnabled:$false.
Set a 30-day calendar reminder to review complaint tickets. Any guest that generates a legitimate access complaint during that window gets re-enabled, documented, and added to the active register with a sponsor. Guests that generate no complaints after 30 days are safe to delete: Remove-MgUser -UserId {id}.
Note: deleting a guest who owns a SharePoint site makes the site ownerless, which causes administrative headaches. Before deletion, run Get-MgUserOwnedObject -UserId {id} to check for owned resources and transfer ownership first.
Prevent future sprawl with a guest lifecycle policy
The cleanup is a one-time project. Preventing recurrence requires three structural controls.
First, set a guest account expiration policy in Entra ID. Navigate to Entra ID > External Identities > External collaboration settings and set Guest user access expiration to 365 days. Guests who have not signed in within that window are automatically disabled. This requires Entra ID Governance.
Second, require a sponsor designation at invitation time. This is not a native Entra ID control but can be enforced by routing all guest invitations through an approved request workflow (ServiceNow, Jira, or a Power Automate flow) that captures the sponsor's name and business justification before generating the invitation link.
Third, run quarterly access reviews using Entra ID Access Reviews (P2 feature). Configure a recurring review for all guests, assigned to the designated sponsor for each account. Sponsors who do not respond within the review window trigger automatic revocation. This shifts the renewal burden to business owners rather than the security team.
The bottom line
The combination of no default expiration, no required sponsor, and no automated review creates the guest account sprawl problem in every mature Entra tenant. The cleanup is a Graph API export, a tiering spreadsheet, and a 30-day disable window. The prevention is a lifecycle policy, a sponsor requirement at invite time, and quarterly access reviews. Both are achievable without purchasing additional tooling beyond what Entra ID Governance already provides.
Frequently asked questions
How do I find all guest accounts in Entra ID that have never signed in?
Use the Microsoft Graph API with the signInActivity property: GET /v1.0/users?$filter=userType eq 'Guest'&$select=displayName,mail,signInActivity,createdDateTime. Filter results where lastSignInDateTime is null (never signed in) and createdDateTime is older than 90 days. This requires Entra ID P1 or P2 for the signInActivity field. Without P1/P2, you can only filter by account creation date, which is a less precise indicator.
Is it safe to bulk-delete stale guest accounts in Entra ID?
Bulk deletion without a disable period is risky because you may cut off accounts that are active through non-interactive flows (service-to-service, certificate authentication) that would not appear in recent interactive sign-in data. The safe approach is to disable accounts first using Update-MgUser -AccountEnabled:$false, wait 30 days for access complaints, and then delete accounts that generated no complaints. This catches the edge cases without requiring manual review of every account.
What breaks when you delete a guest account in Entra ID?
Deleting a guest account breaks any resource where that account has an explicit role assignment: SharePoint sites where the guest is an owner or member, Teams channels, shared mailboxes where the guest is listed as a delegate, and any Azure RBAC role assignments on subscriptions or resource groups. Before deletion, run Get-MgUserOwnedObject and Get-MgUserMemberOf to enumerate owned resources and group memberships, and transfer or remove those assignments before deleting the account.
Does Entra ID have a built-in guest account expiration feature?
Yes, but it requires Entra ID Governance (previously Azure AD Identity Governance). Navigate to Entra ID > External Identities > External collaboration settings and configure guest user access expiration. You can set accounts to expire after a period of inactivity. Without Governance licensing, guest accounts do not expire by default and persist indefinitely unless manually removed.
What is the biggest security risk from stale guest accounts in Microsoft 365?
Stale guest accounts represent two primary risks: credential compromise and excessive data access. A guest account belonging to a former partner or contractor employee who has left that organization may have weak credentials or no monitored authentication activity — if compromised, the attacker has access to all SharePoint sites, Teams channels, and OneDrive shared with that guest. The second risk is residual data access: guests often retain access to SharePoint document libraries and Teams channels long after the business relationship ends. Conduct quarterly access reviews using Entra ID Access Reviews to identify guests who have not authenticated in 90+ days and guests who no longer have an active business justification.
How do I prevent new guest accounts from being created without approval?
Configure Entra ID External Collaboration Settings to restrict guest invitations to admins and users with the Guest Inviter role only (not all users). Set the 'Guest invite restrictions' to 'Only users assigned to specific admin roles can invite guest users.' Then create an access package in Entra ID Identity Governance for legitimate guest access requests, requiring manager approval and a defined access duration (30, 60, or 90 days with auto-expiration). This eliminates ad-hoc guest invitations from end users and ensures every guest has a documented business justification and a defined access window from day one.
Sources & references
Free resources
Critical CVE Reference Card 2025–2026
25 actively exploited vulnerabilities with CVSS scores, exploit status, and patch availability. Print it, pin it, share it with your SOC team.
Ransomware Incident Response Playbook
Step-by-step 24-hour IR checklist covering detection, containment, eradication, and recovery. Built for SOC teams, IR leads, and CISOs.
Get threat intel before your inbox does.
50,000+ security professionals read Decryption Digest for early warnings on zero-days, ransomware, and nation-state campaigns. Free, daily, no spam.
Unsubscribe anytime. We never sell your data.

Founder & Cybersecurity Evangelist, Decryption Digest
Cybersecurity professional with expertise in threat intelligence, vulnerability research, and enterprise security. Covers zero-days, ransomware, and nation-state operations for 50,000+ security professionals every morning.
Win a $2,495 Black Hat pass.
Full-access to Black Hat USA 2026 in Las Vegas. Subscribe free to enter.
