← Back to Blog

The Accounts That Can Take Your Domain Aren't on Your Admin List

13 October 2026 Identity Security 9 min read
What a search for adminCount=1 returns, and what it should adminCount = 1 Holds power over the domain Left a protected group mark stays set inheritance still off no longer privileged Protected groups direct members nested members Privilege by permission replication rights owner or WriteDacl on the domain edit rights on DC Group Policy never marked marked, not privileged The mark is a record of protection by group membership, past or present. Privilege is wider than that, and narrower.

The overlap is the only part a search on adminCount gets right.

Ask a team for a list of everyone with administrative power over their domain, and a good share of them will run the same one-line query: every account with adminCount set to 1. It's quick, it's in every hardening checklist, and the attribute's own documentation says it marks objects whose permissions were secured "because it was a member of one of the administrative groups (directly or transitively)."

The trouble is in that past tense. adminCount records that an account was protected at some point. It doesn't record that the account is privileged now, and it says nothing at all about privilege that doesn't come from a group. So the list is wrong in both directions: it holds accounts that lost their power years ago, and it leaves out accounts that can take the whole domain.

This post takes both errors apart, gives you the PowerShell to find each, and closes with the detection that watches the second one, because that is the one attackers use.

Where the mark comes from

Active Directory keeps a template of permissions on an object called AdminSDHolder, under CN=System. Every 60 minutes by default, a process called SDProp runs on the domain controller holding the PDC emulator role, compares the permissions on each protected account and group with that template, and resets any that differ. Microsoft lists the protected groups: Account Operators, Administrators, Backup Operators, Domain Admins, Domain Controllers, Enterprise Admins, Enterprise Key Admins, Key Admins, Print Operators, Read-only Domain Controllers, Replicator, Schema Admins and Server Operators, plus the Administrator and krbtgt accounts.

Protection follows nesting. An account in a group that sits inside Domain Admins is protected exactly as a direct member is. Microsoft's own write-up of the mechanism notes that this applies even when the nested group is a distribution group, which grants no access token membership at all.

When an account is protected, two things change on it. adminCount is set to 1, and permission inheritance is switched off, so the account's permissions come only from AdminSDHolder and nothing delegated on its organizational unit reaches it. That second change is the point of the whole mechanism: an administrator's account can't be taken over through a permission someone granted on the OU it happens to live in.

The mark stays when the membership goes

Remove the account from its last protected group and neither change is reversed. Microsoft says so plainly: the account is no longer protected, but its adminCount stays at 1 unless someone changes it, SDProp stops maintaining its permissions, and it still inherits nothing from its parent. It now sits in an OU whose delegations don't apply to it, holding a frozen copy of whatever AdminSDHolder looked like the last time SDProp touched it.

Three problems follow, and they compound over years:

  • Every review counts it. A former administrator, a helpdesk member who was once in Account Operators, a service account that spent a week in Domain Admins during a migration: each keeps showing up as privileged, and the real list hides among them.
  • Delegation silently skips it. The helpdesk's password-reset delegation on the OU doesn't apply, so someone eventually grants a broader right to make the reset work, and that right is rarely taken back.
  • An attacker reads the same attribute. Any authenticated user can query adminCount. A marked account that nobody uses, often a forgotten admin account from years ago, is exactly what an intruder who has read the directory goes after first.

Finding leftovers means comparing the mark with current membership, walked recursively the way SDProp walks it:

# Accounts carrying adminCount=1 that are in no protected group today
$protected = 'Administrators','Domain Admins','Enterprise Admins','Schema Admins',
             'Account Operators','Backup Operators','Server Operators','Print Operators',
             'Replicator','Key Admins','Enterprise Key Admins'
$members = foreach ($g in $protected) {
    Get-ADGroupMember -Identity $g -Recursive -ErrorAction SilentlyContinue |
        Where-Object objectClass -eq 'user' | ForEach-Object SamAccountName
}
$members = @($members) + 'Administrator', 'krbtgt' | Sort-Object -Unique

Get-ADUser -LDAPFilter '(adminCount=1)' -Properties nTSecurityDescriptor, lastLogonTimestamp |
    Where-Object SamAccountName -notin $members |
    Select-Object SamAccountName, Enabled,
        @{ n = 'InheritanceOff'; e = { $_.nTSecurityDescriptor.AreAccessRulesProtected } },
        @{ n = 'LastLogon';      e = { [datetime]::FromFileTime($_.lastLogonTimestamp) } }

Enterprise Admins, Schema Admins and Enterprise Key Admins exist only in the forest root domain, which is why the lookup tolerates errors. Run the same comparison with Get-ADGroup for groups, because a group removed from a protected group keeps the mark too.

Each row is an account to clean up. Clear the attribute and turn inheritance back on, in that order, and only after you've checked what the OU's delegations will grant once they apply:

$dn  = (Get-ADUser 'h.doyle').DistinguishedName
Set-ADUser 'h.doyle' -Clear adminCount
$acl = Get-Acl "AD:$dn"
$acl.SetAccessRuleProtection($false, $true)   # inherit again, keep the current entries
Set-Acl -Path "AD:$dn" -AclObject $acl

Then prove it stuck rather than waiting an hour. Writing 1 to the rootDSE attribute RunProtectAdminGroupsTask on the PDC emulator runs SDProp immediately, which Microsoft documents as the way to test AdminSDHolder changes. If the mark comes back, the account is still a member of something protected, usually through a nested group nobody remembered.

The privilege that never gets the mark

The other error is the dangerous one. SDProp protects accounts because of the groups they're in. Power over a domain can also be granted directly, as a permission on an object, and an account that holds it is in no protected group, so it never receives the mark.

The clearest case is replication. An account with the Replicating Directory Changes and Replicating Directory Changes All rights on the domain object can ask a controller for every account's password hash, which is the DCSync technique. By default only the administrators' groups and the controllers hold those rights. But there is one well-known account that holds them by design: the AD DS connector account Microsoft Entra Connect uses for password hash synchronization. Microsoft lists both replication rights in its required permissions, and since build 1.4 Entra Connect refuses to use a Domain Admin or Enterprise Admin account for the job. So in most hybrid domains there is an account, usually named MSOL_ followed by a string, that can replicate every secret in the domain, and a search on adminCount will never show it.

It's not the only one. Ownership or WriteDacl on the domain object lets an account grant itself replication rights. The same on AdminSDHolder lets it write an entry that SDProp then copies onto every administrator account within the hour. Edit rights on a Group Policy object linked to the Domain Controllers OU let it run code on every controller. None of these involve a protected group.

Reading the domain object's permissions shows the first two:

# Who can replicate secrets, or rewrite the permissions that decide who can
$domain = (Get-ADDomain).DistinguishedName
$repl = @{ '1131f6aa-9c07-11d1-f79f-00c04fc2dcd2' = 'Replicating Directory Changes'
           '1131f6ad-9c07-11d1-f79f-00c04fc2dcd2' = 'Replicating Directory Changes All' }
(Get-Acl "AD:$domain").Access |
    Where-Object { $_.AccessControlType -eq 'Allow' -and (
        $repl.ContainsKey($_.ObjectType.ToString()) -or
        $_.ActiveDirectoryRights -match 'GenericAll|WriteDacl|WriteOwner' -or
        ($_.ActiveDirectoryRights -match 'ExtendedRight' -and $_.ObjectType -eq [guid]::Empty)) } |
    Select-Object IdentityReference, ActiveDirectoryRights,
        @{ n = 'Right'; e = { $repl[$_.ObjectType.ToString()] } }

The last condition matters: an extended right with an empty object type grants every extended right, replication included. Expect the domain controllers, Enterprise Domain Controllers, Administrators and your connector account. Every other name is a finding, and it belongs on your privileged account list with an owner and a reason, exactly as a Domain Admin does.

Watch the right that doesn't show up in groups

Inventory tells you who could. Detection tells you who did. A replication request is recorded on the controller as event 4662, with the right's GUID in the event's properties, but only if the controllers audit directory service access and the domain object's audit list covers those rights. Check that a test replication produces the event before you trust a quiet result.

In Microsoft Sentinel:

// Requests for every secret in the domain from anything that isn't a controller
let DomainControllers = dynamic(["DC01$", "DC02$"]);     // your controllers' accounts
let SyncAccounts = dynamic(["MSOL_0123456789ab"]);       // your Entra Connect connector account
SecurityEvent
| where EventID == 4662
| where Properties has "1131f6ad-9c07-11d1-f79f-00c04fc2dcd2"
| where SubjectUserName !in (DomainControllers) and SubjectUserName !in (SyncAccounts)
| summarize Requests = count(), FirstSeen = min(TimeGenerated), LastSeen = max(TimeGenerated)
    by SubjectUserName, Computer

In Splunk, with the fields as the Splunk Add-on for Microsoft Windows extracts them:

index=wineventlog sourcetype="WinEventLog:Security" EventCode=4662
    Properties="*1131f6ad-9c07-11d1-f79f-00c04fc2dcd2*"
    NOT src_user IN ("DC01$", "DC02$", "MSOL_0123456789ab")
| stats count AS Requests, min(_time) AS FirstSeen, max(_time) AS LastSeen BY src_user, host

Name your controllers and your connector account explicitly rather than excluding every account that ends in $. A computer account that has been granted replication rights is exactly the kind of quiet grant this post is about, and a blanket exclusion hides it.

The allowlist carries a risk you should write down: the connector account's own replication is allowed, so its credential is as valuable as a Domain Admin's. The Entra Connect server belongs in tier 0 for the same reason, and the connector account's sign-ins from anywhere other than that server deserve their own alert.

Where to read more

  • Microsoft Learn, Appendix C: Protected Accounts and Groups in Active Directory, for AdminSDHolder, SDProp, the protected groups and running SDProp by hand.
  • Microsoft's archived Admin Free Active Directory and Windows, Part 2, on what happens to adminCount and inheritance when an account leaves a protected group.
  • Microsoft Learn, Microsoft Entra Connect: Accounts and permissions, for the connector account's replication rights.
  • Microsoft Learn, the Admin-Count attribute reference, and the troubleshooting note on batches of event 4780 on the PDC emulator, which is SDProp rewriting protected accounts' security descriptors every hour.
  • MITRE ATT&CK, T1003.006 DCSync.

What to do this week

  1. Run the leftover comparison and count the accounts carrying the mark with no protected membership. Clean them up one at a time, and confirm each with a manual SDProp run.
  2. Read the domain object's permissions with the second block, and put every name that isn't a controller, an administrators' group or your connector account on the privileged list with an owner.
  3. Check that 4662 is recorded for replication on your controllers before relying on any DCSync detection.
  4. Deploy the replication detection in KQL or SPL with your controllers and connector account named, and alert on the connector account signing in from anywhere but the Entra Connect server.
  5. Change the question your reviews ask. Not "who has adminCount=1" but "who can change what the controllers enforce", answered from group membership and from permissions together.

A list of administrators built from one attribute is a list of who used to be protected. The accounts that can take a domain today are the ones holding the rights, whether or not any group says so.

Free preview: Defending Active Directory

What Active Directory is, why control of it is control of the business, and what the controllers write down when someone takes it.

Read the free section →
Ridgeline Cyber Defence Written by security professionals. Published weekly on Tuesdays.

Related Articles

7 July 2026

Core Security Settings to Secure Your Active Directory Environment

Six Active Directory defaults still shipping in most domains, each mapping to a named 2026 attack: LAPS, NTLM signing, K

30 June 2026

Resetting the Password Won't Help: Why AD CS Relay (ESC8) Is the AD Attack That Survives Your Incident Response

ESC8 turns a coerced domain controller into domain-wide compromise with no password cracked, and the certificate it issu

16 May 2026

KQL Sign-In Log Analysis, What ResultType != 0 Actually Tells You

KQL sign-in log analysis: what ResultType values mean, how to detect password spray, MFA fatigue, and CA blocks in Senti