Join our Newsletter — 33% off our NHI Course
Home› Guides› How to find AD accounts with password never…
Guide Non-Human Identity (NHI)

How to find AD accounts with password never expires: Find, triage and fix the risky ones

PDF for newsletter subscribers · free to read online

← All guides
By NHI Mgmt Group, edited by Lalit Choda Updated 11 November 2026 13 min read
On this page

Accounts with "Password never expires" set are where Active Directory keeps its oldest passwords, and the oldest passwords are the ones most likely to be weak, shared, reused or already in someone else's hands. The flag itself is not always wrong: current NIST guidance says verifiers should not force periodic changes, and Microsoft recommends no expiry for cloud-only accounts. What makes an account risky is the combination: never-expiring plus a password set years ago by a person, plus an SPN, privileged group membership or no owner. This runbook shows how to find every account with the flag, enrich it with the attributes that matter, sort the deliberate from the dangerous, and fix the dangerous ones without breaking the services that depend on them. It is for Active Directory administrators and identity security teams. Retiring accounts that carry SPNs is covered in How to find and retire Active Directory service accounts with SPNs.

This is an independent guide from NHI Mgmt Group, based on Microsoft's public documentation and NIST SP 800-63B as of November 2026. It is not sponsored or reviewed by Microsoft. Product features change, so confirm settings against Microsoft's current documentation.

Key takeaways

  • It is one bit. The flag is DONT_EXPIRE_PASSWORD in userAccountControl, value 0x10000 (decimal 65536). LDAP bitwise filters need the decimal value.
  • The flag is a lead, not a verdict. NIST SP 800-63B (section 3.1.1.2) says verifiers shall not require periodic password changes, but shall force a change on evidence of compromise. A long, unique, MFA-protected human password with no expiry can be correct policy.
  • Password age is the real risk signal. Pair the flag with pwdLastSet: a never-expiring password set five years ago on an account nobody owns is the finding.
  • Service accounts are most of the list. Expect the flag on accounts that run services, scheduled tasks and integrations, because an expiry would break them. The fix there is a managed account or a vaulted, rotated password, not just clearing the flag.
  • Clearing the flag can lock things out. If the password is older than the domain maximum age, removing the flag makes it expire at once. Reset first, then change the flag, in a change window.

When you need this

  • Audit or pentest finding: "accounts with non-expiring passwords" is a staple of AD assessments and of control testing against NIST SP 800-53 IA-5(1) Password-based Authentication.
  • Service account programme start: the never-expiring list is the fastest way to seed a service account inventory. See the Service Account Inventory Template.
  • After a credential leak or password spraying campaign (ATT&CK T1110.003): old, never-changed passwords are the ones most likely to be in breach corpora or guessable.
  • Before tightening password policy: changing the domain or fine-grained policy does nothing for flagged accounts, so you need the list before the policy change.

Before you start

  • Tools: the ActiveDirectory PowerShell module on an admin workstation, read access to every domain in the forest, and your SIEM or domain controller Security logs.
  • Audit policy: confirm Audit User Account Management is enabled on domain controllers so event 4738 ("A user account was changed") is generated. It records changes to the flag.
  • Policy context: record the domain's maximum password age and any fine-grained password policies. An account without the flag can still effectively never expire if its policy has a maximum age of 0, so check both.
  • Agree the house rule: decide in writing which account types may hold the flag (for example: break-glass accounts with long random vaulted passwords, human accounts covered by MFA and breached-password checks) and which may not. Triage is quick once the rule exists.

Where never-expiring passwords come from

SourceHow to see itTypical owner
DONT_EXPIRE_PASSWORD flag (0x10000) on the accountLDAP filter on userAccountControl, or Search-ADAccount -PasswordNeverExpiresWhoever created the account; often set at build time for services
Domain password policy with maximum age 0Default Domain Policy settingsDomain administrators; affects every account without a fine-grained policy
Fine-grained password policy (PSO) with no or very long maximum agePassword Settings Container; resultant policy per userOften created for service account groups
Cloud-only Entra ID user with per-user never-expire setMicrosoft Graph user passwordPoliciesEntra administrators (User Administrator or above)

Step-by-step

Steps 1 to 5 are read-only. Steps 6 to 8 change the directory and are reversible if you keep the baseline export.

  1. List every account with the flag. Run Search-ADAccount -PasswordNeverExpires -UsersOnly, adding -SearchBase to scope by OU. For the attributes you need for triage, use an LDAP bitwise AND filter (matching rule 1.2.840.113556.1.4.803) with Get-ADUser -LDAPFilter '(userAccountControl:1.2.840.113556.1.4.803:=65536)' -Properties pwdLastSet,PasswordLastSet,LastLogonDate,Enabled,servicePrincipalName,memberOf,adminCount,Description,whenCreated,msDS-SupportedEncryptionTypes and export to CSV. Run it against each domain in the forest. Without -UsersOnly, Search-ADAccount also returns computer and managed service accounts, which you can set aside: their passwords are machine-generated and rotated.
  2. Turn pwdLastSet into an age. pwdLastSet is a count of 100-nanosecond intervals since 1 January 1601 (UTC); the module's PasswordLastSet property gives it as a date. A value of 0 normally means "must change at next logon", except when the never-expire flag is set, so treat 0 on a flagged account as a password state to investigate, not a date. Bucket ages: under 1 year, 1 to 3 years, 3 to 5 years, over 5 years.
  3. Add the risk attributes. For each account mark: enabled or disabled; holds an SPN (Kerberoastable, ATT&CK T1558.003); member of a privileged group directly or nested, or adminCount = 1; PASSWD_NOTREQD (0x0020) also set; DONT_REQ_PREAUTH (0x400000) also set; and last logon. LastLogonDate is replicated with a lag and approximate, so treat it as a hint and confirm with logon events before acting.
  4. Classify the account type. Use naming, OU, description and where it logs on to sort into: service or integration account, human user, break-glass or built-in Administrator, shared or generic account, test account. Event 4624 logon types on member servers show service (type 5) and batch (type 4) logons, which identify where a credential is configured as a service or scheduled task identity.
  5. Find an owner. Every account needs a named person or team. No owner after a reasonable search means the account is a disable candidate, not a keep.
  6. Fix by category using the triage table below. For service accounts, the target is a group managed service account (gMSA) or, where that is impossible, a long random password held in a vault and rotated by it. See How to convert AD service accounts to gMSA.
  7. Reset before you clear the flag. For accounts that should expire, set a new password first, update every place it is configured, then clear the flag with Set-ADUser <account> -PasswordNeverExpires $false. Microsoft documents that this parameter sets the ADS_UF_DONT_EXPIRE_PASSWD flag, and that it cannot be set to true on an account that also has ChangePasswordAtLogon set to true.
  8. Disable what nobody owns. Set-ADUser <account> -Enabled $false with a description holding the date and change reference, move it to a quarantine OU, and leave it through a full business cycle before deletion. Disabling does not touch the password, so re-enabling restores service.

Triage table

What you findRiskAction
Enabled, privileged group member, password over 1 year oldHighest: one guessed or cracked password gives domain-level accessRemove privilege or reset to a vaulted random password now; review logon history for misuse
Enabled, SPN, password over 3 years oldKerberoastable with a likely human-chosen passwordConvert to gMSA; otherwise long random password, AES only
Enabled, no logons in 90 days, no ownerDormant credential nobody will miss or noticeDisable, quarantine, delete after the quiet period
Human user, MFA enforced, breached-password checks in placeLow, and consistent with NIST SP 800-63BKeep; document as accepted under the house rule
Human user, no MFA, password over 1 year oldSpraying and reuse targetEnforce MFA, reset, consider clearing the flag until MFA is in place
Break-glass or built-in AdministratorExpected to be non-expiring; risk is in storage and monitoringKeep the flag, confirm the password is long, random and vaulted, alert on every sign-in. See the Break-Glass Account Guide
Flag plus PASSWD_NOTREQDAccount may hold a blank or trivial passwordSet a strong password, clear PASSWD_NOTREQD, investigate why it was set
Disabled, flag setLow now; returns if someone re-enables itDelete if confirmed unused; otherwise reset the password before any re-enable

Small versus large estates

A single domain with a few hundred flagged accounts can be triaged in a spreadsheet with owners on a call over a couple of weeks. A multi-domain forest with thousands needs the work split by the triage table: privileged accounts first, then SPN accounts with old passwords, then dormant accounts, then everything else, with each wave given a deadline. In large estates, feed the CSV export into your identity governance or CMDB tooling so ownership is tracked, and make the export a scheduled job rather than a one-off, because new flagged accounts will keep appearing until the house rule is enforced at creation.

Verify it worked

  • Re-run step 1: the count of enabled, flagged accounts with passwords older than your threshold falls, and every remaining flagged account has an owner and a documented reason.
  • Watch event 4738: Microsoft's monitoring guidance for this event suggests watching "'Don't Expire Password' - Enabled" for critical accounts, or for all accounts if your organisation does not allow the flag. After the clean-up, any new instance should map to an approved request.
  • Check dependent services: watch logon failures (event 4625) and service start failures for accounts you reset or disabled during the quiet period.
  • Check the Password Last Set field: event 4738 also records pwdLastSet changes, giving evidence that resets actually happened.

Detection and metrics

Signal or metricSourceTarget or alert condition
Flag enabled on any accountEvent 4738, User Account Control fieldAlert for privileged accounts; ticket for all others if the house rule restricts the flag
Enabled flagged accounts with password over 1 year oldScheduled LDAP exportDownward trend; zero for privileged accounts
Flagged accounts without a named ownerInventoryZero
Flagged accounts in privileged groupsExport joined to group membershipOnly break-glass accounts, each with sign-in alerting
Service accounts converted to gMSA or vaulted rotationInventoryRising percentage per quarter
Logons by flagged accounts from unexpected hostsEvents 4624 and 4769Alert: an old service credential used from a workstation is a strong compromise signal

Rollback and common errors

  • Rollback of a flag change: Set-ADUser <account> -PasswordNeverExpires $true restores the previous state. Keep the baseline CSV from step 1 so you know which accounts had it.
  • Rollback of a disable: Set-ADUser <account> -Enabled $true and move it back to its original OU.
  • Rollback of a reset: there is none. A reset password cannot be restored, so update every dependent service, task and connection string in the same change window and test before closing the change.
  • Error: clearing the flag on an old password. If pwdLastSet is older than the maximum password age, the account's password is treated as expired the moment the flag goes, and services stop. Reset first.
  • Error: treating every flagged human account as a violation. Forcing expiry back on well-protected human accounts contradicts NIST SP 800-63B and Microsoft's own recommendation for cloud accounts, and tends to produce weaker passwords. Spend the effort on service and privileged accounts.
  • Error: looking only at the flag. Accounts under a fine-grained policy or a domain policy with maximum age 0 never expire either, and will not appear in a userAccountControl query.
  • Error: forgetting synced identities. On-premises accounts synchronised to Entra ID are governed by the on-premises policy for expiry unless the tenant enables CloudPasswordPolicyForPasswordSyncedUsersEnabled. Cloud-only accounts carry their own per-user setting, so review that list in Entra separately.
  • Error: missing the hosts. A service account password configured on a server nobody remembers will break silently after a reset. Use 4624 service and batch logons to map every host before you change anything.

Hardening afterwards

  • Enforce the rule at creation: provisioning workflows should refuse the flag except for the approved account types, and alert on 4738 when it is set outside them.
  • Move services to managed identities: gMSA passwords are generated and rotated by Active Directory. See the Group Managed Service Accounts (gMSA) Guide.
  • Vault what cannot be converted: put remaining service passwords under a PAM or secrets tool that rotates them on a schedule and on evidence of compromise, which is the trigger NIST requires.
  • Check human passwords against breach lists: where human accounts keep non-expiring passwords, pair them with MFA and breached-password screening. See Breached password checks.
  • Review on a schedule: include flagged accounts in the quarterly service account access review. See How to Run an Access Review for Service Accounts.

Framework mapping

FrameworkReferenceHow this runbook supports it
NIST SP 800-63BSection 3.1.1.2 Password VerifiersNo forced periodic change, forced change on evidence of compromise
NIST SP 800-53 Rev 5IA-5(1) Password-based Authentication; IA-5 Authenticator ManagementPassword age, strength and change triggers managed per account type
NIST SP 800-53 Rev 5AC-2 Account Management; AC-2(3) Disable AccountsOwners assigned; dormant flagged accounts disabled
NIST CSF 2.0PR.AA-01Credentials for users and services managed by the organisation
MITRE ATT&CK v20T1078.002 Domain Accounts; T1110.003 Password SprayingFewer old, guessable domain passwords available to reuse or spray
MITRE ATT&CK v20T1558.003 Kerberoasting; T1201 Password Policy DiscoveryOld SPN passwords removed; less to gain from learning the policy

Practitioner checklist

  • Write the house rule for which account types may hold a non-expiring password.
  • Export every user account with userAccountControl bit 65536 set, in every domain, with pwdLastSet, SPNs, group membership and last logon.
  • Check domain and fine-grained policies for maximum age 0 or very long ages.
  • Bucket by password age and flag privileged, SPN, PASSWD_NOTREQD and pre-authentication-disabled accounts.
  • Assign an owner to every flagged account, or disable it.
  • Reset privileged and old SPN passwords first, then convert to gMSA or vaulted rotation.
  • Reset before clearing the flag, and map dependent hosts from 4624 service and batch logons.
  • Alert on event 4738 "Don't Expire Password" enabled outside approved accounts.
  • Review cloud-only Entra accounts with per-user never-expire separately.
  • Schedule the export monthly and track the metrics above.

Standards and references

Related NHI Mgmt Group resources: How to find and retire Active Directory service accounts with SPNs, Service Account Security Guide, Password Policy Guide (NIST-aligned), Kerberoasting and AS-REP Roasting Defence Guide.

PDF for subscribers

Take this guide with you

Every section, table and checklist in one PDF, with links to the sources and related guides. Subscribe to our weekly NHI & AI Identity Journal and we’ll email you a download link.

Free weekly newsletter

Subscribe to the NHI & AI Identity Journal

The latest on NHI and Agentic AI security – articles, research, breaches, news and events every week.

Bonus 33% off our NHI Course when you subscribe.

NHIMG Editorial Note
Researched and written by the NHI Mgmt Group editorial team using AI tools, under the editorial direction of Lalit Choda. Facts are drawn from the sources listed on this page and checked by our automated quality process. Last updated 11 November 2026. Spotted an error? Use our contact page.
NHI Mgmt Group, the independent authority on Non-Human Identity, IAM and Agentic AI security. nhimg.org

PDF Downloads for Newsletter Subscribers

Get the guide

Enter your details and we’ll email you a download link.

The full guide is free to read online. The PDF is a thank you for subscribing.

Fill in all fields marked * and tick the PDF box to continue.