Privileged Accounts Checklist
“Privileged” in AD means more than Domain Admins. This is the list I run through before signing off on any account hardening engagement.
The default privileged groups
If a person account is in any of these, they are tier-0 — every workstation they log into is now a domain-compromise risk.
| Group | What it gives | Should a human be in it? |
|---|---|---|
| Domain Admins | Full control of the domain | No — service accounts only, ideally none |
| Enterprise Admins | Full control of every domain in the forest | No |
| Schema Admins | Modify the schema | Empty, except during schema changes |
| Administrators (built-in) | Local admin on every DC | No |
| Account Operators | Manage users (can elevate themselves) | No |
| Backup Operators | Read/write any file on DC, including NTDS.dit | No |
| Print Operators | Load drivers on DCs → SYSTEM | No |
| Server Operators | Manage DC services → SYSTEM | No |
| DnsAdmins | DLL load via DNS server → SYSTEM on DC | No |
| Group Policy Creator Owners | Modify GPOs → can ship malicious GPO | No |
| Cert Publishers | Approve cert requests → AD CS abuse | Service only |
| Domain Controllers | The DCs themselves | Computer objects only |
Find every privileged human
PowerShell, one-liner-ish:
$tier0 = @(
"Domain Admins","Enterprise Admins","Schema Admins",
"Administrators","Account Operators","Backup Operators",
"Print Operators","Server Operators","DnsAdmins",
"Group Policy Creator Owners","Cert Publishers"
)
foreach ($g in $tier0) {
Get-ADGroupMember $g -Recursive |
Where-Object { $_.objectClass -eq "user" } |
Select-Object @{n="Group";e={$g}}, Name, SamAccountName, distinguishedName
} | Export-Csv tier0-humans.csv -NoTypeInformationOutput is the audit trail: every human-mapped account with tier-0 access.
The hidden flags
memberOf is not the only story. Check these per account:
Get-ADUser -Filter * -Properties UserAccountControl, AdminCount,
TrustedForDelegation, TrustedToAuthForDelegation,
msDS-AllowedToDelegateTo, msDS-AllowedToActOnBehalfOfOtherIdentity,
ServicePrincipalName, PasswordNeverExpires, PasswordNotRequired,
DoesNotRequirePreAuth, AllowReversiblePasswordEncryptionFor each:
| Flag | Meaning | Risk |
|---|---|---|
AdminCount = 1 | Was once in a protected group; ACL is hardened, may not have been re-cleaned | Lingering trust |
TrustedForDelegation | Unconstrained delegation — collects TGTs | Used with coercion = TGT for any user |
TrustedToAuthForDelegation | Protocol transition | Combined with constrained delegation = silver ticket |
msDS-AllowedToActOnBehalfOfOtherIdentity | RBCD — resource-based constrained delegation | Easy persistence vector |
ServicePrincipalName set on a user | Kerberoastable | Offline crack possible |
PasswordNeverExpires = True | Static credential | Long-lived risk |
PasswordNotRequired = True | Blank password permitted | Domain compromise in one query |
DoesNotRequirePreAuth | AS-REP roastable | Offline crack possible |
AllowReversiblePasswordEncryption | Password recoverable in clear | Critical |
PasswordNotRequired = True on any user account is a domain-compromise
bug. Check it first on every assessment.
Protected Users group
The single biggest defensive control nobody enables. Members of Protected Users get:
- No NTLM, no CredSSP, no Kerberos DES/RC4 (only AES)
- No unconstrained or constrained delegation possible
- 4-hour TGT lifetime, no renewable
Put every tier-0 account in Protected Users. The friction is tiny; the defensive lift is enormous.
Get-ADGroupMember "Domain Admins" -Recursive |
Where { $_.objectClass -eq "user" } |
ForEach-Object { Add-ADGroupMember "Protected Users" -Members $_ }Don’t forget computer accounts
Domain Controllers are privileged accounts that happen to be machines. So is any server running:
- AD CS (Certificate Services) —
ESC1throughESC11are all live in the wild - ADFS — service account is effectively a domain compromise
- Azure AD Connect — same
- Exchange — historical
Exchange Trusted SubsystemACL abuse - SCCM / MECM — primary site server is tier-0 in practice
- Any backup software with domain-wide read access
These all need the same protections you give a DC.
Quick win checklist
In order of “fastest mitigation per attacker capability removed”:
- Add every tier-0 user to Protected Users. 5 minutes.
- Remove
PasswordNotRequiredfrom every account. 1 hour. - Move service accounts to gMSAs wherever supported.
- Audit and remove
AdminCount=1legacy ACLs on non-tier-0 accounts. - Disable unconstrained delegation on every host that doesn’t need it.
- Enable LAPS on all workstations and servers (Windows LAPS, not legacy).
- Implement a tiering model with separate admin workstations (PAWs).