GOV-02: Automatically Disable Stale Accounts
Overview
Stale accounts, those belonging to former employees, forgotten identities, or users who have not signed in for an extended period, are a persistent attack surface in any Microsoft 365 tenant. GOV-02 addresses this by automatically disabling accounts that have been inactive for 90 or more days, rather than deleting them.
Disabling is intentionally reversible. The account is blocked from sign-in but retains its group memberships, licenses, and data. A 14-day warning notification is sent to the account owner (or a designated contact) before the disable action fires, preventing disruption for legitimate users who may be on extended leave.
Two categories of accounts are always excluded from automated disabling:
- Emergency access (break-glass) accounts used when normal admin paths are unavailable
- Service accounts used by applications, scripts, or automated workflows
TrueConfig monitors sign-in activity and can automate the entire disable lifecycle, including the warning notification and exclusion list, using its auto-remediation engine.
Why it matters: Manual reviews miss accounts. Automated disabling ensures that former employees, forgotten accounts, and inactive identities cannot be used by attackers. The 14-day warning prevents disruption for legitimate users.
Prerequisites
Required Roles
- Security Administrator or Global Administrator to configure automation and exclusion lists
- User Administrator to disable individual accounts manually if needed
Required Licenses
- Microsoft Entra ID P2 (required): the
signInActivityproperty used to determine inactivity is only available with a P2 (or Microsoft Entra ID Governance) license.
Time Estimate
| Task | Duration |
|---|---|
| Identify stale accounts and review list | 30-60 minutes |
| Configure exclusion groups (emergency + service accounts) | 30 minutes |
| Set up automated disable workflow or TrueConfig rule | 30-60 minutes |
| Test with a pilot account | 15 minutes |
| Total | 1.5-3 hours |
Step-by-Step Instructions
Step 1: Identify Inactive Accounts
Use the signInActivity property (requires Entra ID P2) to find accounts with no sign-in in the past 90 days.
Via Microsoft Entra admin center:
- Navigate to https://entra.microsoft.com.
- Go to Identity > Users > All users.
- Click Add filter > Last sign-in > is before > enter the date 90 days ago.
- Review the list. Export it for cross-reference with your exclusion groups.
Via PowerShell:
Connect-MgGraph -Scopes "User.Read.All", "AuditLog.Read.All"
$cutoff = (Get-Date).AddDays(-90).ToString("yyyy-MM-ddTHH:mm:ssZ")
# Retrieve all enabled accounts with sign-in activity data
$staleAccounts = Get-MgUser -All `
-Filter "accountEnabled eq true" `
-Property "DisplayName,UserPrincipalName,Id,SignInActivity" |
Where-Object {
$_.SignInActivity -eq $null -or
$_.SignInActivity.LastSignInDateTime -lt (Get-Date).AddDays(-90)
}
$staleAccounts | Select-Object DisplayName, UserPrincipalName,
@{N="LastSignIn"; E={$_.SignInActivity.LastSignInDateTime}} |
Export-Csv "stale-accounts-review.csv" -NoTypeInformation
Step 2: Build Exclusion Groups
Before any automated action, define which accounts must never be disabled.
- Navigate to Identity > Groups > All groups in Entra admin center.
- Create a security group named
stale-account-disable-exclusions. - Add all emergency access (break-glass) accounts to this group.
- Add all service accounts and non-interactive identities to this group.
- Document the group purpose and owner.
Tip: Use a consistent naming prefix for service accounts (for example, svc-) so they are easy to identify and can be added programmatically.
Step 3: Configure the 14-Day Warning Notification
Before disabling an account, a warning notification must be sent 14 days in advance. This can be implemented via:
- Microsoft Entra Lifecycle Workflows (Identity Governance): create a workflow triggered when
signInActivity.lastSignInDateTimecrosses the 76-day mark (90 - 14). The workflow sends an email to the account's manager or a designated security inbox. - TrueConfig automation: TrueConfig's auto-remediation engine handles this timing automatically when you configure the exclusion list in TrueConfig settings.
Lifecycle Workflow approach (Entra admin center):
- Navigate to Identity Governance > Lifecycle workflows > Workflows.
- Click + New workflow > Custom workflow.
- Set the trigger: Attribute changes >
signInActivity.lastSignInDateTimeolder than 76 days. - Add task: Send email notification to the user's manager.
- Exclude the
stale-account-disable-exclusionsgroup in the workflow scope.
Step 4: Automate Account Disabling at 90 Days
Option A: TrueConfig (recommended)
In TrueConfig settings, enable the GOV-02 auto-remediation rule and point the exclusion list to the stale-account-disable-exclusions group. TrueConfig will handle detection, the 14-day warning, and the disable action.
Option B: Lifecycle Workflow
- Create a second workflow triggered at 90 days of inactivity.
- Add task: Disable user account (built-in Lifecycle Workflows task).
- Exclude the
stale-account-disable-exclusionsgroup. - Enable the workflow.
Option C: PowerShell (manual or scheduled)
Connect-MgGraph -Scopes "User.ReadWrite.All", "AuditLog.Read.All", "Group.Read.All"
# Load exclusion group members
$exclusionGroup = Get-MgGroup -Filter "displayName eq 'stale-account-disable-exclusions'"
$exclusions = Get-MgGroupMember -GroupId $exclusionGroup.Id |
Select-Object -ExpandProperty Id
# Find stale accounts not in exclusion list
$toDisable = Get-MgUser -All `
-Filter "accountEnabled eq true" `
-Property "Id,DisplayName,UserPrincipalName,SignInActivity" |
Where-Object {
$_.Id -notin $exclusions -and (
$_.SignInActivity -eq $null -or
$_.SignInActivity.LastSignInDateTime -lt (Get-Date).AddDays(-90)
)
}
foreach ($user in $toDisable) {
Update-MgUser -UserId $user.Id -AccountEnabled:$false
Write-Host "Disabled: $($user.UserPrincipalName)"
}
Run this script on a schedule (for example, weekly via Azure Automation) after warning notifications have been sent.
Step 5: Verify and Document
After each disable run:
- Navigate to Identity > Users > All users and filter by Account enabled = No to confirm accounts were disabled.
- Verify no accounts in the exclusion group were affected.
- Log the disable action: account UPN, disable date, days inactive, and approving automation rule.
- Re-enable any account disabled in error and add it to the exclusion group if needed.
Verification Checklist
- P2 license is assigned to users (or tenant-wide) so sign-in activity data is available
-
stale-account-disable-exclusionsgroup exists and contains all emergency access and service accounts - 14-day warning notification workflow or TrueConfig rule is active
- 90-day disable workflow or TrueConfig rule is active
- At least one test run completed against a pilot account with successful re-enable confirmation
- Disable actions are logged for audit purposes
- No emergency access accounts appear in the stale-accounts candidate list
Troubleshooting
Issue: SignInActivity Is Null for Some Accounts
Cause: Sign-in activity data requires Entra ID P2. Without P2, signInActivity returns null for all users, which the PowerShell query above treats as stale.
Solution:
- Confirm P2 licenses are assigned.
- Alternatively, cross-reference with Entra sign-in logs (retained 30 days without Log Analytics) rather than the
signInActivityproperty. - For accounts provisioned but never used, null activity is expected. Review whether those accounts should be in the exclusion group or disabled immediately.
Issue: Service Account Was Disabled
Cause: Service account not added to the exclusion group.
Solution:
- Re-enable the account immediately: navigate to Identity > Users > select the user > Edit > Account status = Enabled.
- Add the service account to the
stale-account-disable-exclusionsgroup before the next automation run. - Consider adding a distinguishing attribute (for example,
jobTitle = "Service Account") to enable dynamic group membership.
Issue: Synced Account Cannot Be Disabled from Entra
Cause: The account is synchronized from on-premises Active Directory. Entra ID reflects the on-premises state.
Solution:
- Disable the account in on-premises Active Directory.
- Run a delta sync:
Start-ADSyncSyncCycle -PolicyType Delta. - Confirm the disabled state propagates to Entra ID.
Issue: Account Was Disabled but User Is on Parental Leave
Solution:
- Re-enable the account immediately via Entra admin center.
- Add the account to the exclusion group for the duration of the leave.
- Set a calendar reminder to remove the account from the exclusion group when the leave ends.
Best Practices
-
Treat disabling as a first step, not final action: disabled accounts remain restorable. Permanent deletion is a separate, more deliberate process with its own prerequisites.
-
Review the exclusion group quarterly: service accounts accumulate over time. Remove entries that are no longer in use.
-
Pair with access reviews: combine automated disabling with Entra ID Access Reviews (also P2) for a complete identity lifecycle posture.
-
Log every automation action: write disable events to a Log Analytics workspace or SIEM for compliance evidence.
-
Communicate the policy broadly: users returning from extended leave should know in advance that accounts inactive for 90 days will be disabled, and who to contact for reinstatement.
Related Controls
- GOV-01: Stale account detection and review (manual baseline)
- GOV-03: Access reviews for automated lifecycle management
- PA-03: Configure Emergency Access Accounts (break-glass accounts must always be in the exclusion list)
Revision History
| Date | Version | Author | Changes |
|---|---|---|---|
| 2025-01-07 | 1.0 | TrueConfig | Initial release |