Troubleshooting user account permissions – AdminSDHolder

Specops Password Reset, Specops Password Sync, uReset, and Specops Authentication all use low privilege service accounts in Active Directory.  When you add an OU or OUs to your management scope, we delegate extremely granular permissions for our service account to the user accounts within that OU.  We do this so we can operate on user accounts in your Active Directory without requiring Domain Admin or other high privilege group membership that would introduce additional security risk.

This works great for normal user accounts; however, for any accounts where security inheritance is disabled, our service account will not be able to interact with those user accounts.  Those users will encounter errors when attempting to enroll or reset their passwords, and you may see additional errors in the event logs of your Password Reset or Gatekeeper server.

Identifying Accounts with Security Inheritance Disabled

You can check if an individual service account has security inheritance disabled in AD Users and Computers.  Enable Advanced Settings, open the properties of the user account, and click the Advanced… button in the Security tab to see if inheritance is enabled or disabled.

You can also use the Active Directory PowerShell module to check directly if security inheritance is disabled:

get-aduser <username> -properties ntsecuritydescriptor | select -expand ntsecuritydescriptor | select areaccessrulesprotected

If the result is True then inheritance is disabled; if it is False, then inheritance is enabled.

You can also use PowerShell to search for any user account in your AD Scopes that has inheritance disabled:

get-aduser -searchbase <DN of AD Scope> -filter * -properties ntsecuritydescriptor | where
 {$_.ntsecuritydescriptor.areaccessrulesprotected -eq $true }

Before you re-enable inheritance on these accounts, we should determine why the inheritance was removed in the first place.  The most likely culprit by far: AdminSDHolder.

Understanding the AdminSDHolder Role

You can read our full description of the AdminSDHolder role, but the short version is that the accounts either are or were at some point members of certain protected groups in Active Directory.  The common culprits are the key admin groups (Domain Admins, Enterprise Admins, etc.) but some lower-privilege groups such as Account Operators are also affected.  The full list varies depending on your domain functional level.

Once an hour, a process called SDPROP runs, and the following steps are taken on all users and groups that are members of the protected groups:

  • Security inheritance is disabled
  • The ACL on the user/group is replaced with the ACL from the AdminSDHolder object in the System container in AD (a smaller, much more restrictive ACL)
  • The adminCount attribute on the user/group is set to 1

SDPROP runs automatically every 60 minutes.  If we reenable inheritance on the affected users and clear the adminCount attribute and the group membership that triggered those items being changed in the first place is still there, then SDPROP will revert our changes within the hour.  So before cleaning up the permissions on these accounts, we need to ensure they are not affected by AdminSDHolder.

Finding Users and Groups affected by AdminSDHolder

If the adminCount attribute on a user is set to 1, we can assume it is (or was at some point in the past) a member of a protected group and affected by the AdminSDHolder role.

You can check the adminCount attribute on a user in ADUC (with advanced features enabled) or ADSIEdit:

Alternatively, use PowerShell:

get-aduser <username> -properties admincount

Note: If this command returns no results, the adminCount attribute is not set and the user is not affected by AdminSDHolder.

To find all users in your AD scope with the adminCount attribute set, use another PowerShell query on your AD scope:

get-aduser -searchbase <DN of AD Scope> -filter * -properties adminCount | where {$_.adminCount -eq 1 }

Which Admin Groups Am I In (if any)?

At this stage, it helps to focus on one or two key user accounts and check which admin groups they are in, if any.

In lieu of manually browsing the “member of” tab in AD, we can stick to PowerShell and run a query to see which groups the user is in that also have the adminCount attribute set:

$user = get-aduser <username> -properties memberof

foreach ($group in $user.memberof) { get-adgroup $group -properties adminCount | where {$_.adminCount -eq 1} }

If this command returns no groups, that’s the best-case scenario.  This means whatever group membership caused the adminCount attribute to get set has already been cleaned up, and all you have to do is clear the adminCount attribute and reset permissions.  However, if one or more groups are returned:

Take a look at the list.  If a default protected groups appears in the list, that’s your answer there.  However, in the above example, we’ve got another group with the adminCount attribute set.  This means that group is or was nested in a protected group.

We can continue using PowerShell to query the group’s membership until we find one of those default protected groups.  In most environments it won’t be more than 1 or 2 layers of nesting before you find the culprit.

$protectedgroup = get-adgroup <groupname> -properties memberof

foreach ($group in $protectedgroup.memberof) { get-adgroup $group -properties adminCount | where {$_.adminCount -eq 1} }

Again, if you end up with an empty list when you query the group, that means the cleanup was already done.  Clear the adminCount attribute and reset permissions on the group and move on to user account cleanup.  However, if you do get to some of the default protected groups, the results will look something like this:

Here we see the IT Helpdesk group is nested in both Account Operators and (somewhat more alarmingly) Domain Admins.  Each of these groups is protected in AD, which is how our IT Helpdesk Group and its members ended up being affected by AdminSDHolder.

You will need to remove the membership in the protected groups.  Strategies here, from most to least recommended:

  • Remove the user accounts or groups from the protected groups. Create separate dedicated admin accounts for users’ privileged access and excluding those admin accounts from self-service reset.  Then clean up the original affected user accounts (this is what we recommend)
  • Exclude certain groups (e.g. Account Operators) from AdminSDHolder using dsHeuristics, then proceed with user account cleanup.
  • Grant the Specops Password Reset/Gatekeeper service account permissions on all accounts affected by AdminSDHolder by updating the ACL on the AdminSDHolder object in AD. With this scenario there is no need for manual cleanup, however you now run the risk of having a service account with permissions to manipulate all of your Domain Admin and other high privilege accounts.  This is NOT recommended.


Once you’re sure the accounts (and custom groups) with security inheritance disabled are no longer affected by AdminSDHolder, re-enable security inheritance and clear the adminCount attribute manually on each affected account.


Or using PowerShell:

set-aduser <username> -remove @{adminCount=1}

$user = get-aduser <username> -properties ntsecuritydescriptor


set-aduser <username> -replace @{ntsecuritydescriptor=$user.ntsecuritydescriptor}

If you have a large number of user accounts or groups to clean up, use the same PowerShell commands as part of a foreach loop to hit each user affected.  As with any large-scale automated change, double check and test your code before proceeding in production.

Note: Do not change the adminCount attribute or reset permissions on any default protected groups such as Domain Admins – only remove membership in these groups.  Not only does modifying the security on these groups present additional security concerns, but these changes will revert the next time SDPROP runs.

(Last updated on February 1, 2023)


Written by

Darren Siegel

Product Specialist, Specops Software

More Articles
Back to Blog

Related Articles

  • How things work: Group Policy Processing

    I have recently seen an error message appear during the first logon following a Windows 10 Anniversary Update. Below is information on how the problem manifests itself, the underlying technology (hardcore Group Policy knowledge) and how to work around it – as it can affect Specops customers. Problem description The error message displayed to the…

    Read More
  • How things work: Group Policy Caching

    The release of Windows 8.1 and Server 2012 R2 introduced a new Group Policy concept called Group Policy Caching. Its purpose is to reduce the time it takes to perform certain scenarios for synchronous foreground Group Policy refresh. Here’s the drawback: for every Group Policy update interval, Group Policy Caching will download, and store a…

    Read More