Skip to main content
The Ops Playbook

Ending the Account Lockout Loop with Automated Root-Cause Triage

Stale cached credentials on mobile devices and mapped drives cause repeat AD lockouts; automated triage and self-service unlock cut ticket volume.

Ending the Account Lockout Loop with Automated Root-Cause Triage
Sarah LiangSarah Liang10 min readTier L240 min

This playbook covers

Share

#The Old Way vs the New Way

The old way of handling account lockouts looks like this: the phone rings, the user says they are locked out, the technician opens Active Directory

Users and Computers, finds the account, clicks Unlock, tells the user to try again, and closes the ticket. Fifteen minutes later the same user calls back because the account has locked again. Nobody asked why. Nobody looked at which device or service kept hammering the domain controller with a stale password. The technician just repeated the unlock, the user got frustrated, and the ticket queue absorbed the same incident three or four times before anyone traced it to a mobile mail profile or a mapped drive with a cached credential from six months ago.

The new way treats every lockout event as a data point, not an interrupt. Instead of a human manually unlocking an account and hoping the problem does not recur, an automated pipeline correlates the lockout with the source of the bad password attempts, scores the risk, and either fixes the root cause and notifies the user with the exact remediation step, or escalates immediately to a security reviewer if the pattern looks like an attack. The technician’s job shifts from repetitive unlocking to tuning the risk logic and reviewing the exceptions the automation could not resolve safely.

#Why This Ticket Keeps Coming Back

Account lockout tickets are one of the highest-volume categories in any service desk, and Security and Compliance teams care about them because a lockout storm is indistinguishable from a password-spray attack until someone investigates. In most environments the recurring offender is one of four things: a mapped network drive with a saved credential that was not updated after a password change, a mobile device ActiveSync or Exchange profile still holding the old password, a scheduled task or Windows service running under the user’s account with a hard-coded credential, or a browser or Credential Manager entry that keeps replaying an old password during single sign-on negotiation. None of these are visible from the standard ADUC unlock screen, which is exactly why the same ticket reopens.

account lockout ticket deflection

#Prerequisites and Permissions

  • Windows Server Active Directory with audit policy enabled for Account Lockouts and Logon Events (Success and Failure) on all domain controllers, PDC emulator role identified.
  • A centralised log destination – Log Analytics workspace, Sentinel, or an equivalent SIEM – receiving forwarded Security event logs from all domain controllers.
  • Microsoft Entra ID (Azure AD) tenant with Identity Protection enabled (requires Entra ID P2 for full risk detections).
  • An app registration with the following Microsoft Graph application permissions, consented by a Global Administrator: User.ReadWrite.All, AuditLog.Read.All, IdentityRiskyUser.Read.All.
  • A delegated AD security group scoped via Delegation of Control to Reset Password and Unlock Account rights on a specific OU only – never domain-wide unlock rights for an automation account.
  • A service connection from your automation platform (Azure Automation, Power Automate, or a scheduled runbook host) to both on-premises AD (via a hybrid runbook worker) and Microsoft Graph.
  • Least privilege note: the automation identity should hold Unlock and Reset Password rights only, never Domain Admin, and its credential should be stored in a managed identity or vault, not a plaintext script variable.

#Implementation Steps

  1. Action: Enable and centralise lockout auditing. Configure Group Policy Advanced Audit Policy for Account Lockout (Success) and Logon (Failure) on all domain controllers, then forward Security logs to your Log Analytics workspace using the Log Analytics agent or Azure Monitor Agent.

    Expected result: Event ID 4740 (account locked out) and 4625 (failed logon) from every domain controller appear centrally within two minutes of occurrence.

    Evidence to capture: A sample Kusto query result showing a 4740 event with the CallerComputerName field populated.

    1Get-WinEvent -ComputerName DC01 -FilterHashtable @{LogName='Security'; Id=4740} -MaxEvents 10 |
    2  Select-Object TimeCreated, @{n='TargetUser';e={$_.Properties[0].Value}}, @{n='CallerComputer';e={$_.Properties[1].Value}}
  2. Action: Correlate the lockout with the preceding failed logon storm to find the actual bad-password source, since the CallerComputer on the 4740 event is often the DC itself, not the client.

    Expected result: A ranked list of client hostnames or IP addresses generating repeated 4625 events for that user in the sixty seconds before the lockout.

    Evidence to capture: Query output showing the top offending source IP or hostname with an attempt count.

    1$user = 'jsmith'
    2$window = (Get-Date).AddMinutes(-5)
    3Get-WinEvent -FilterHashtable @{LogName='Security'; Id=4625; StartTime=$window} |
    4  Where-Object { $_.Properties[5].Value -eq $user } |
    5  Group-Object { $_.Properties[19].Value } |
    6  Sort-Object Count -Descending |
    7  Select-Object Name, Count
  3. Action: Pull the Entra ID sign-in logs for the same user and time window via Microsoft Graph to identify the client application, since a hostname on-premises does not tell you whether the offender is a phone, a mapped drive, or a scheduled task.

    Expected result: A JSON response listing app display name, client app type, and status for each failed attempt.

    Evidence to capture: The appDisplayName and clientAppUsed fields from the response, e.g. \”Outlook Mobile\” or \”Other clients\” (legacy auth signature of a mapped drive or service).

    1import requests
    2
    3token = get_graph_token()  # MSAL client credential flow
    4headers = {"Authorization": f"Bearer {token}"}
    5filter_query = (
    6    "userPrincipalName eq 'jsmith@contoso.com' and "
    7    "status/errorCode eq 50126 and "
    8    "createdDateTime ge 2024-05-02T09:09:00Z"
    9)
    10url = f"https://graph.microsoft.com/v1.0/auditLogs/signIns?$filter={filter_query}"
    11resp = requests.get(url, headers=headers)
    12for entry in resp.json().get("value", []):
    13    print(entry["appDisplayName"], entry["clientAppUsed"], entry["status"]["errorCode"])

    Expected output example:

    1Outlook Mobile   Mobile Apps and Desktop clients   50126
    2Outlook Mobile   Mobile Apps and Desktop clients   50126
  4. Action: Build the risk-scoring decision logic that decides whether to auto-remediate or escalate. Low risk means the source device is a known, previously-registered device belonging to that user and the Identity Protection risk score is none or low. High risk means an unfamiliar IP, a foreign country, an unmanaged device, or a medium/high risk detection.

    Expected result: A structured decision object the automation platform can act on.

    Evidence to capture: The JSON decision payload logged for audit purposes before any unlock action runs.

    1{
    2  "user": "jsmith@contoso.com",
    3  "lockoutTime": "2024-05-02T09:14:02Z",
    4  "offendingClient": "Outlook Mobile",
    5  "sourceDevice": "iPhone-JSmith",
    6  "riskLevel": "low",
    7  "identityProtectionRisk": "none",
    8  "decision": "auto-remediate",
    9  "remediationHint": "Update stored password in Outlook Mobile profile settings"
    10}
  5. Action: For low-risk cases, auto-unlock the account via Microsoft Graph, revoke stale sign-in sessions so the cached bad credential stops retrying, and notify the user with the specific fix rather than a generic \”try again\” message.

    Expected result: Account unlocked, sessions revoked, Teams or email message delivered within thirty seconds of the lockout event.

    Evidence to capture: Graph API response code 204 for the unlock call and the delivered notification payload.

    1Connect-MgGraph -Scopes 'User.ReadWrite.All'
    2$userId = (Get-MgUser -Filter "userPrincipalName eq 'jsmith@contoso.com'").Id
    3Update-MgUser -UserId $userId -AccountEnabled:$true
    4Invoke-MgGraphRequest -Method POST -Uri "https://graph.microsoft.com/v1.0/users/$userId/revokeSignInSessions"
    1{
    2  "type": "MessageCard",
    3  "summary": "Account unlocked automatically",
    4  "text": "Hi Jane, your account was unlocked automatically. The lockout was caused by an outdated password stored on Outlook Mobile. Please update the password in your phone's mail settings to prevent this from recurring.",
    5  "themeColor": "0076D7"
    6}
  6. Action: For high-risk cases, block automatic remediation, keep the account locked, and raise an enriched ServiceNow incident tagged for SOC review instead of routing it to the general L1 queue.

    Expected result: A ticket is created only for the exceptions that genuinely need human judgement, with the full correlation data already attached.

    Evidence to capture: The ServiceNow API response containing the new incident number.

    1{
    2  "short_description": "High-risk AD lockout: jsmith - foreign IP detected",
    3  "category": "Security",
    4  "subcategory": "Identity Risk",
    5  "urgency": "1",
    6  "assignment_group": "SOC-Tier3",
    7  "work_notes": "Lockout correlated to sign-in from IP 203.0.113.44 (Country: RO), Identity Protection risk: medium, offending client: legacy protocol (IMAP). Auto-remediation withheld."
    8}
  7. Action: Wrap steps one through six in a scheduled runbook or Logic App triggered by the 4740 event forwarded to Log Analytics, so the entire pipeline runs without a technician touching a ticket queue.

    Expected result: End-to-end latency from lockout event to either auto-remediation or ticket creation under sixty seconds.

    Evidence to capture: Runbook execution log with a timestamp delta between trigger and completion.

  8. Action: Pilot the automation against a single OU or a volunteer group of fifty users for two weeks before enabling it tenant-wide.

    Expected result: Zero false-positive unlocks (accounts unlocked that should have stayed locked) during the pilot window.

    Evidence to capture: A pilot summary report comparing manual versus automated resolution counts and time-to-resolution.

Ending the Account Lockout Loop with Automated Root-Cause Triage architecture diagram 2

#Verification and Expected Evidence

Confirm the pipeline works by checking three things after a test lockout: the domain controller emits Event ID 4767 (account unlocked) with the automation service account as the actor, the Entra ID audit log shows a matching revokeSignInSessions action, and the user-facing notification arrived with the correct remediation hint rather than a generic message. For high-risk test cases, verify the account remains locked, Identity Protection shows a risk detection entry, and the ServiceNow incident exists with the assignment group set to the security queue, not the general helpdesk.

#Rollback

Disable the runbook trigger or the Logic App connector first; this is a single flag flip and stops all automated unlocks immediately while leaving manual unlock capability intact through ADUC. Do not delete the automation service account’s delegated permissions during rollback, since re-enabling later should not require re-running delegation. Roll back if the false-positive unlock rate exceeds two percent of processed lockouts in any rolling 24-hour window, or if a single incorrect auto-remediation on a privileged (Tier 0) account occurs, which should trigger immediate rollback regardless of overall accuracy.

#Failure and Escalation Conditions

Wake a human technician immediately when any of the following occur: the same account locks out more than three times within one hour despite an apparently successful auto-remediation, the offending source IP resolves to a country or ASN outside the organisation’s approved list, the account belongs to a Tier 0 or privileged access group, Identity Protection reports a risk level of medium or high, or the Graph API unlock call returns anything other than a success status code. In every escalation case, the automation should hold the account locked rather than guess, because a false unlock on a genuine attack is far more expensive than a delayed legitimate unlock.

#Measuring Ticket Deflection

Baseline the current state before deployment by pulling thirty days of lockout-related tickets from your ITSM platform and recording the average handle time and the reopen rate within four hours of first resolution. After deployment, track three numbers weekly: the percentage of lockouts resolved with zero ticket created (full deflection), the percentage escalated to a genuine security ticket, and the reopen rate for auto-remediated cases. A realistic target for a mature deployment is seventy to eighty-five percent full deflection, with the remainder split between edge cases needing device re-registration and the small proportion of genuine risk escalations. Multiply the deflected ticket count by your average fully-loaded handle time, typically twelve to eighteen minutes per lockout ticket including hold time and reopen churn, to produce a monthly hours-saved figure for reporting to operations leadership.

Evidence trail

Sources and verification

Primary documentation and external technical references used in this article.

  1. 01Microsoft's guide to troubleshooting Active Directory account lockout issueslearn.microsoft.com
  2. 02Microsoft Graph signIn resource type referencelearn.microsoft.com
  3. 03the Microsoft Entra ID Identity Protection overviewlearn.microsoft.com
Sarah Liang

Sarah Liang

Ops Playbook Architect

Sarah Liang is a Cloud Solutions Architect designing highly available, globally distributed applications.

Published
View Profile
Reader Interaction

Comments

Add a thoughtful note on Ending the Account Lockout Loop with Automated Root-Cause Triage. Comments are checked for spam and held for moderation before appearing.

Loading comments...
Comment submission is disabled until Cloudflare Turnstile keys are configured.

Learn More About KBY

Was this useful?

Operate smarter, with fewer recurring tickets.

Receive new operational playbooks, incident-prevention guidance, automation scripts and recovery runbooks.