If a user account is a member of a protected group in Active Directory, permission inheritance is disabled on the AD object and performing tasks like pool migrations, registrar enablement/disablement or granting policies will fail to execute and return an error similar to this:
Active Directory operation failed on "DC1.contoso.com". You cannot retry this operation: "Insufficient access rights to perform the operation"
This issue is fairly well documented both by Microsoft and by others in the Skype4B community, such as Pat Richard or James Ooi, so it is an almost certainty that you will see this at some point in time. Despite the pain it brings, Protected Groups are a good thing overall – it is a built-in functionality within Active Directory Domain Services to lock down Access Control Lists (ACLs) on user accounts that are members of certain built-in AD Security groups. The AD groups vary based on the version of your forest/domain functional level:
Windows Server 2003 with SP1 Windows Server 2003 with SP2 |
Windows Server 2008 RTM Windows Server 2008 R2 |
Account Operators | Account Operators |
Administrator | Administrator |
Administrators | Administrators |
Backup Operators | Backup Operators |
Domain Admins | Domain Admins |
Domain Controllers | Domain Controllers |
Enterprise Admins | Enterprise Admins |
Krbtgt | Krbtgt |
Print Operators | Print Operators |
Replicator | Read-only Domain Controllers |
Schema Admins | Replicator |
Server Operators | Schema Admins |
Server Operators |
So What’s the Fuss?
Typically you run across this issue with user accounts of folks in IT, as their user account was added to a Protected Group at some point during the lifecycle of that account and the Lync/Skype4B specific attributes of the account remain off-limits due to ACL inheritance being removed. Normal non-IT user accounts don’t typically get added to a Protected Group so I would expect you never to see a ‘normal user’ show up in there. Sometimes the case was an account was added to the ‘Domain Admins’ group (which is never a good thing – you should always have dedicated Administrative user accounts separate from non-admin user accounts…but I digress) or it may have been an account added to a seemingly minor group like ‘Account Operators’. Bottom line: any of the groups listed above are subject to the AdminSDHolder ACL configuration.
Despite the fact that the issue is already documented, there is a small point of clarification that often gets overlooked: AdminSDHolder and AdminCount apply even after you remove an account from a protected group. Microsoft’s own documentation on the subject makes it very clear that early design decisions in Active Directory led them to not revert ACL security after the account was removed from the protected group membership:
Question: What is AdminCount, and why is it not being decremented to ‘0’ or ‘<not set>’ when I remove a user from a Protected Group? Answer: AdminCount is an attribute on the user account that is set to 1 on any users being protected by AdminSdHolder. When protected, the user gets this attribute set and the security inheritance bit is removed from their account. The reason AdminCount isn’t set back to 0 when the user is removed from a protected group is that you told us not to! A survey of customers early on in Windows 2000's design found that they favored deleting a user account after its high-privilege rights were revoked, as the account could have created explicit backdoors before having its rights stripped. Therefore the DC does not remove the AdminCount attribute entry, as it is assumed that the account is going to be disabled or deleted. If for some reason you didn’t want to get rid of that account after ‘de-admining’ it, you must manually set back to allowing inheritance and set AdminCount to 0, usually through ADSIEDIT.MSC..
The Workaround
Most of the scenarios out on the Internet give instructions on searching each individual group and obtaining the membership list, like so:
(Get-AdGroupMember "Domain Admins") | Select-Object DistinguishedName,UserPrincipalName
Obviously the above scenario works, but there are two significant limitations to that approach:
- It requires to you search each individual group that is considered a protected group, and…
- It does not account for users that were once a member of a protected group and now are not
In the second scenario above, the users will still have ACLs limited even though they are no longer a member of a protected group.
To find all user accounts that may have an AdminCount attribute set, you can use the following Get-AdUser code:
Import-Module ActiveDirectory Get-AdUser -Filter {admincount -eq 1} -ResultSetSize $NULL | Select-Object DistinguishedName,UserPrincipalName
The above query will search the current domain and return all accounts that have the AdminCount value set to ‘1’, telling you not only which accounts may be in a protected group currently but also any accounts that may have been in a protected group in the past.
To identify which of those accounts are Lync/Skype4B enabled, you can use the same code as above with a slight modification:
Import-Module ActiveDirectory (Get-AdUser -Filter {admincount -eq 1} -ResultSetSize $NULL).DistinguishedName | Get-CsUser -ErrorAction SilentlyContinue | Select-Object UserPrincipalName,SipAddress
All we’re doing here is simply taking the results from Get-AdUser and piping it into Get-CsUser to determine which accounts may be enabled for UC. If you have results that come back as UC enabled, your ideal path is to fix your Protected Group membership so that no normal user accounts are in those groups. Again, no normal user accounts should be in a Protected Group – once that is in place you can move forward with remediation of the accounts’ ACLs.
To specify user accounts to have their admincount attribute reset to default, simply create a CSV file containing the userprincipalname of the accounts that need to be fixed and use the following code:
Import-Module ActiveDirectory Import-CSV -Path C:\temp\admincountuserlist.csv ForEach{ Write-Host "Clearing admincount attribute on " -NoNewline:Write-Host $_.userprincipalname Set-AdUser -Identity $_.userprincipalname -Clear admincount -Verbose }
Once the admincount attribute is reset the next change required is resetting the Access Control List inheritance on the accounts, which sadly is a much more complex task. If the list of accounts is small, a manual inheritance change through Active Directory Users and Computers may be easiest, otherwise take a look at these two posts for information on resetting the ACLs from PowerShell:
Using my code snippet above (regarding the CSV), you should be able to take the PowerShell code from the above two URLs and modify it so that you only change the ACL configuration of the accounts specified in the CSV file. Should you not do that, the code from the URLs above will actually modify the ACLs of all accounts that have the admincount property set. Most InfoSec teams would have a heart-attack if you did that, so make sure you target your approach to only the accounts that are required.
Final Note
In order to reset the admincount attribute, the account invoking the changes must have sufficient access to do so. Usually this means membership within the Domain Admins or Enterprise Admins group, so plan these changes accordingly. Separately, you must have sufficient rights to make the ACL inheritance changes on the accounts as well. Make sure you’ve got all your ducks-in-a-row before attempting to make any changes!
As an aside: this issue also impacts Exchange Server deployments, too, so don’t think that Lync Server and Skype4B Server are the only products to see this problem!
Yes, we ran into this same thing when deploying our Exchange environment.