Most Active Directory domains cannot answer a simple question: which accounts are services, not people? Managed service accounts are easy to list, but the risky ones are ordinary user accounts created years ago, named inconsistently, with passwords that never expire and nobody who remembers them. This runbook builds a service account inventory from the directory itself: it pulls every managed service account, finds user accounts behaving as services from several independent signals, confirms them with host and authentication evidence, and records each one with an owner. Every step is read-only. It is for identity engineers, Active Directory administrators and NHI programme leads preparing for rotation, gMSA migration, an audit or a clean-up.
This is an independent guide from NHI Mgmt Group, based on Microsoft's public documentation 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
- Managed accounts are the easy part.
Get-ADServiceAccount -Filter *returns standalone and group managed service accounts with theirObjectClassandHostComputers. They are service accounts by definition. - No single attribute marks a user account as a service. Combine signals: a service principal name, the
DONT_EXPIRE_PASSWORDflag, a naming prefix, delegation flags, logon workstation restrictions and placement in a service OU. Two or more signals make a strong candidate. - Prove it with behaviour. A Windows service or scheduled task configured with the account, or logon type 5 (service) and 4 (batch) events on member servers, confirms the classification. Interactive and remote desktop logons suggest a person, or a shared account that needs splitting.
- Treat lastLogonTimestamp as approximate. It only updates when the stored value is older than
msDS-LogonTimeSyncInterval, so it can lag real use by a couple of weeks and is not accurate enough to prove an account is unused. - An inventory without owners is a list. Microsoft's own guidance asks for owner, purpose, permission scopes, risk, expected lifetime and attestation for each account. Record those before anyone rotates or retires anything.
When you need this
- Before rotation or gMSA migration: you cannot rotate what you have not found. See Rotating a Windows or Linux Service Account Password for the next step per account.
- Kerberoasting or penetration test findings: testers report the SPN accounts; this inventory finds the rest of the population around them.
- Audit requests: CIS Controls v8.1 Safeguard 5.5 asks for an inventory of service accounts, and NIST SP 800-53 AC-2 expects accounts to have defined types and owners.
- Merger, divestment or domain consolidation: inherited domains carry undocumented service identities that will break if migrated blindly.
Before you start
| Evidence source | What it adds | Access needed | Limit to know |
|---|---|---|---|
| Directory attributes (ActiveDirectory module) | Account type, flags, SPNs, group membership, password age | Authenticated read on each domain | Says what an account could be, not what it does |
| Host configuration (Win32_Service, scheduled tasks, IIS, SQL Server) | Where the account is configured to run | Remote CIM or an endpoint management tool | Only the hosts you can reach |
| Security event logs or SIEM | Where and how the account actually authenticates | Domain controller and member server Security logs | Needs Audit Logon and Kerberos auditing enabled and retained |
| CMDB, vault and ticket history | Owner, application and purpose | Read access to those systems | Often stale; treat as a lead, not proof |
Run every query per domain in the forest, using -Server to target a domain controller in each. Store all output with a run date so the next run can be compared with this one.
Step-by-step
Step 1: List the managed service accounts
Run Get-ADServiceAccount -Filter * -Properties Description,servicePrincipalName,PrincipalsAllowedToRetrieveManagedPassword,whenCreated and group the results by ObjectClass. Standalone MSAs appear as msDS-ManagedServiceAccount and gMSAs as msDS-GroupManagedServiceAccount. On Windows Server 2025 domains, also look for delegated managed service accounts (dMSA): Microsoft documents that a dMSA can supersede an existing service account, and the attributes msDS-DelegatedMSAState (1 migration started, 2 completed) and msDS-ManagedAccountPrecededByLink show which legacy account it replaces. Record that link: a migration left in state 1 means the old account is still live.
Step 2: Find user accounts that look like services
Query user objects for each signal separately, so you can see why each account was picked. The userAccountControl values below come from Microsoft's flag reference; test them with the LDAP bitwise AND rule 1.2.840.113556.1.4.803.
| Signal | LDAP filter or method | Strength | Caveat |
|---|---|---|---|
| Service principal name | (&(objectCategory=person)(servicePrincipalName=*)), excluding krbtgt | Strong | Also a Kerberoasting exposure; see the SPN retirement runbook |
| Password never expires | (userAccountControl:1.2.840.113556.1.4.803:=65536) or Search-ADAccount -PasswordNeverExpires -UsersOnly | Medium | Also set on break-glass and some human accounts |
| Naming convention | (sAMAccountName=svc*) and any local prefixes such as sa_, app-, sql | Medium | Only as good as past discipline; ask each team for its prefixes |
| Delegation | UAC 524288 (TRUSTED_FOR_DELEGATION), 16777216 (TRUSTED_TO_AUTH_FOR_DELEGATION), or msDS-AllowedToDelegateTo present | Strong | High risk; flag for the delegation review |
| Weak account settings | UAC 32 (PASSWD_NOTREQD), 4194304 (DONT_REQ_PREAUTH), 2097152 (USE_DES_KEY_ONLY) | Medium | Legacy application workarounds; also attack paths |
| Logon workstation restriction | (userWorkstations=*), set by Set-ADUser -LogonWorkstations | Medium | Microsoft recommends this restriction for service accounts, so where it exists it is a deliberate marker |
| Location and description | Accounts in OUs named for services or applications; description containing service, app, batch, sql or a server name | Weak to medium | Descriptions are free text and often wrong |
| No human attributes | No mail, manager, employeeID or department, where HR sync populates these for people | Weak | Only useful where HR data is reliably synced |
Export each result with sAMAccountName, objectSid, distinguishedName, userAccountControl, pwdLastSet, lastLogonTimestamp, whenCreated, description, servicePrincipalName, msDS-SupportedEncryptionTypes and adminCount.
Step 3: Merge, de-duplicate and score
Join the lists on objectSid and count the signals per account. A practical starting rule: any SPN or delegation signal, or any two medium signals, makes the account a candidate. Keep the signal list in the record, because it explains the classification to the owner later.
Step 4: Add privilege context
Resolve nested group membership for each candidate, for example with the in-chain matching rule 1.2.840.113556.1.4.1941 against each protected group. Microsoft lists the protected groups, including Domain Admins, Enterprise Admins, Administrators, Account Operators, Backup Operators, Server Operators and Schema Admins; the AdminSDHolder process (SDProp, every 60 minutes by default) stamps their members. An adminCount of 1 on a service account that is no longer in any protected group shows it was privileged once and still carries the hardened, non-inheriting permissions. Microsoft states that service accounts should not belong to privileged groups, so every hit here goes to the top of the list. See How to find service accounts with Domain Admin rights.
Step 5: Confirm with host configuration
For each candidate, find where it is configured to run. The StartName property of Win32_Service holds the logon account as DOMAIN\user, a UPN or .\user; scheduled task principals, IIS application pool identities and SQL Server service and Agent accounts complete the picture. The full host sweep is covered in How to Find windows services running as domain accounts; here you only need the host list per account. Services running as LocalSystem use the computer account, and Microsoft notes that you then cannot tell which service is using it, so record such services against the server rather than inventing a service account.
Step 6: Confirm with authentication evidence
| Event | Where | What it shows for the inventory |
|---|---|---|
| 4624 logon type 5 (Service) | Member servers | The Service Control Manager started a service as this account: confirmed service use and the host |
| 4624 logon type 4 (Batch) | Member servers | Scheduled tasks and batch jobs running as the account |
| 4624 logon type 3 (Network) | Application and file servers | Which servers the account connects to; feeds dependency mapping |
| 4624 logon type 2 or 10 (Interactive, RemoteInteractive) | Any host | A person is logging on with the account: shared credential, needs an owner decision |
| 4768 and 4769 | Domain controllers | Ticket requests as, or to, the account, with client addresses |
Use at least 30 days of events, and 90 for anything tied to month-end or quarter-end jobs. Interactive use of a service account is common in older estates and is a finding in its own right; see Active Directory Security Monitoring and Event IDs Guide for collection.
Step 7: Classify each account
| Class | Evidence | Next action |
|---|---|---|
| Managed (sMSA, gMSA, dMSA) | Step 1 | Record hosts and owner; check who may retrieve the password |
| Confirmed user-based service account | Directory signals plus host or service and batch logon evidence | Full record; candidate for gMSA or dMSA |
| Shared service and human account | Service evidence plus interactive logons | Split into a service identity and named admin accounts |
| Suspected, no evidence | Signals only, no hosts, no logons in the window | Owner search; disable candidate via the SPN retirement runbook |
| Human account, false positive | Interactive use only, HR attributes present | Exclude, with the reason, so it is not re-flagged |
Step 8: Write the record and assign owners
For each service account, record the fields Microsoft recommends: owner, purpose, permission scopes, risk if compromised, anticipated lifetime and attestation interval, and where the password is stored and who can read it. Add the evidence fields from this runbook: domain, hosts, signals, privileged membership, delegation, password age from pwdLastSet, encryption types and last proven use with its source. The Service Account Inventory Template gives a ready column set. Accounts with no identifiable owner go to How to Assign owners to orphaned service accounts.
Verify it worked
- Reconcile both directions: every account found on a host in Step 5 must be in the inventory, and every confirmed account must have at least one host or logon source.
- Spot-check: pick ten confirmed accounts and ask their owners to name the application; pick ten excluded accounts and confirm they are people.
- Re-run and diff: a second run a month later should show only explained changes. New candidates with no ticket are your early warning of unmanaged creation.
Rollback and common errors
Steps 1 to 7 change nothing. If Step 8 writes owner text into the description attribute, export the original values first so you can restore them with Set-ADUser -Description. The common errors are about missing accounts, not breaking them:
- Querying one domain: service accounts live in resource and legacy domains too. Run per domain and record the domain in every row.
- SPN-only discovery: many service accounts never had an SPN. Skipping the other signals misses the batch, file share and application accounts.
- Trusting lastLogonTimestamp: Microsoft documents the update interval; use it for broad dormancy, never as proof that an account is unused.
- Ignoring nested groups: direct
memberOfhides privilege granted through a chain of groups. - Counting computer accounts as service accounts: LocalSystem services use the machine identity; inventory the server and service, and record that the account cannot be audited per service.
- Stopping at a spreadsheet: an inventory with no refresh date and no owner decays within a quarter.
Hardening afterwards
- Prevent new unmanaged accounts: a request form that captures owner, purpose and lifetime before creation, as Microsoft's governance guidance describes. See the Service Account Request Form Template.
- Apply account restrictions:
LogonWorkstations, account expiration withSet-ADAccountExpiration, a dedicated OU with delegated administration, and Audit Directory Service Changes so new accounts are detected. - Convert where possible: Microsoft's order of preference is gMSA, then sMSA, then computer account, then domain user. See How to convert AD service accounts to gMSA.
- Review on a schedule: Microsoft's worked example uses biannual owner reviews for medium and high risk accounts. See How to Run an Access Review for Service Accounts.
Small domain or large forest
A single domain with a few hundred users can run Steps 1 to 4 in an afternoon and confirm candidates with owners on a call. A multi-domain forest needs the queries scheduled per domain, event evidence pulled from the SIEM rather than individual logs, the classification stored in a database or CMDB, and work ordered by risk: privileged and delegation-enabled accounts first, then SPN accounts, then the rest.
Metrics
- Confirmed service accounts with a named owner, as a percentage (target 100).
- Service accounts in protected groups, directly or nested (target zero).
- User-based service accounts converted to gMSA or dMSA, as a percentage, trending up.
- Service accounts with interactive logons in the last 30 days (trend to zero).
- Suspected accounts still unresolved after 60 days.
- New service accounts created without a request record since the last run.
Framework mapping
| Framework | Reference | Relevance |
|---|---|---|
| CIS Controls v8.1 | Safeguard 5.5 Establish and Maintain an Inventory of Service Accounts | The direct requirement this runbook satisfies |
| NIST SP 800-53 Rev 5 | AC-2; AC-2(1); AC-2(3); CM-8; IA-5 | Account types and owners, automated management, disabling unused accounts, inventory, authenticator management |
| NIST CSF 2.0 | PR.AA-01; ID.AM-02 | Identities and credentials for services are managed; inventories of services are maintained |
| MITRE ATT&CK | T1078.002 Domain Accounts; T1558.003 Kerberoasting; T1087.002 Domain Account | The abuse of forgotten domain service accounts, and the attacker discovery this inventory pre-empts |
Where identity fits: AD service accounts are non-human identities with the same lifecycle needs as cloud workload identities. Feed this inventory into the same register as service principals and cloud keys so ownership and review work the same way; see NHI Inventory Reconciliation.
Practitioner checklist
- List all sMSAs, gMSAs and dMSAs per domain, including dMSA migration state.
- Query user accounts for every signal separately and keep the signal per account.
- Merge on objectSid and score candidates.
- Resolve nested privileged membership and flag adminCount leftovers.
- Confirm candidates from host configuration and 30 to 90 days of logon events.
- Classify each account and record exclusions with reasons.
- Record owner, purpose, scopes, risk, lifetime and password storage for each one.
- Re-run monthly and investigate any unexplained new account.
Standards and references
- Microsoft Learn: Secure on-premises service accounts
- Microsoft Learn: Govern on-premises service accounts
- Microsoft Learn: Get-ADServiceAccount
- Microsoft Learn: UserAccountControl flags
- Microsoft Learn: Delegated managed service accounts overview
- Microsoft Learn: Last-Logon-Timestamp attribute
- Microsoft Learn: 4624 An account was successfully logged on
- Microsoft Learn: Protected accounts and groups in Active Directory
Related NHI Mgmt Group resources: How to find and retire Active Directory service accounts with SPNs · Windows Services and Service Account Security Guide · Service Account Security Guide · Kerberoasting and AS-REP Roasting Defence Guide