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 signInActivity property used to determine inactivity is only available with a P2 (or Microsoft Entra ID Governance) license.

Time Estimate

TaskDuration
Identify stale accounts and review list30-60 minutes
Configure exclusion groups (emergency + service accounts)30 minutes
Set up automated disable workflow or TrueConfig rule30-60 minutes
Test with a pilot account15 minutes
Total1.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:

  1. Navigate to https://entra.microsoft.com.
  2. Go to Identity > Users > All users.
  3. Click Add filter > Last sign-in > is before > enter the date 90 days ago.
  4. 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.

  1. Navigate to Identity > Groups > All groups in Entra admin center.
  2. Create a security group named stale-account-disable-exclusions.
  3. Add all emergency access (break-glass) accounts to this group.
  4. Add all service accounts and non-interactive identities to this group.
  5. 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.lastSignInDateTime crosses 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):

  1. Navigate to Identity Governance > Lifecycle workflows > Workflows.
  2. Click + New workflow > Custom workflow.
  3. Set the trigger: Attribute changes > signInActivity.lastSignInDateTime older than 76 days.
  4. Add task: Send email notification to the user's manager.
  5. Exclude the stale-account-disable-exclusions group 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

  1. Create a second workflow triggered at 90 days of inactivity.
  2. Add task: Disable user account (built-in Lifecycle Workflows task).
  3. Exclude the stale-account-disable-exclusions group.
  4. 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:

  1. Navigate to Identity > Users > All users and filter by Account enabled = No to confirm accounts were disabled.
  2. Verify no accounts in the exclusion group were affected.
  3. Log the disable action: account UPN, disable date, days inactive, and approving automation rule.
  4. 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-exclusions group 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:

  1. Confirm P2 licenses are assigned.
  2. Alternatively, cross-reference with Entra sign-in logs (retained 30 days without Log Analytics) rather than the signInActivity property.
  3. 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:

  1. Re-enable the account immediately: navigate to Identity > Users > select the user > Edit > Account status = Enabled.
  2. Add the service account to the stale-account-disable-exclusions group before the next automation run.
  3. 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:

  1. Disable the account in on-premises Active Directory.
  2. Run a delta sync: Start-ADSyncSyncCycle -PolicyType Delta.
  3. Confirm the disabled state propagates to Entra ID.

Issue: Account Was Disabled but User Is on Parental Leave

Solution:

  1. Re-enable the account immediately via Entra admin center.
  2. Add the account to the exclusion group for the duration of the leave.
  3. Set a calendar reminder to remove the account from the exclusion group when the leave ends.

Best Practices

  1. 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.

  2. Review the exclusion group quarterly: service accounts accumulate over time. Remove entries that are no longer in use.

  3. Pair with access reviews: combine automated disabling with Entra ID Access Reviews (also P2) for a complete identity lifecycle posture.

  4. Log every automation action: write disable events to a Log Analytics workspace or SIEM for compliance evidence.

  5. 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

DateVersionAuthorChanges
2025-01-071.0TrueConfigInitial release