Subscribe via Email

Subscribe via RSS/JSON


Creative Commons Attribution 4.0 International License
© Rakhesh Sasidharan

Finding groups a user belongs to, including nested groups

Two days ago I had posted about the AdminSDHolder object. Related to this issue I had to find whether a particular user account was a member of the ‘Account Operators’ group or not. It wasn’t a member directly, but it looked like it was a member via some nested group and I needed some way of figuring out how.

Option one was to do this manually. Sorry, that doesn’t work for me! So I used PowerShell to enumerate the groups and nested groups:

The code looks more complicated than it really is. That’s because I have also put it some logic to indent the output for nested groups. If you don’t care about all that here’s what the code looks like:

The key thing is the Get-ADPrincipalGroupMembership cmdlet which lists the groups an object is a member of. So all I do is get such a list and then run this cmdlet for each group in this list.

I tried to be smart here and use recursion. What I did is:

  1. Create a function called Get-Groups which takes an object as input and returns the groups its a member of.
  2. For each such group, Get-Groups calls itself with the group as an input – which results in a list of groups that group is a member of.
  3. And that’s it!

The code can be made neater I think but I haven’t coded in PowerShell for a while and have lost touch. Not good, I know … I wish I were using it regularly than occasionally. :-/


If you are interested in capturing the output to a file via an Out-File pipe for instance, that won’t work because Write-Host outputs to the console by default. Replace Write-Host in my code above with Write-Output and that will correctly output to console or pipe to Out-File. Thanks to one of my readers for pointing this out!

Non admin accounts keep losing their delegated rights to admin accounts (part 2)

Previously I had stopped with an Event Log entry introducing the AdminSDHolder object.

Here’s the message from the Event Log entry:

Every hour, the Windows domain controller that holds the primary domain controller (PDC) Flexible Single Master Operation (FSMO) role compares the ACL on all security principal accounts (users, groups, and machine accounts) present for its domain in Active Directory and that are in administrative groups against the ACL on the AdminSDHolder object. If the ACL on the principal account differs from the ACL on the AdminSDHolder object, then the ACL on the principal account is reset to match the ACL on the AdminSDHolder object and this event is generated.

Turns out Active Directory protects its administrative groups by checking their Access Control Entries (ACEs) every hour against the ACE of the AdminSDHolder object. If the ACEs don’t match then the ACE of the administrative group is replaced with the ACE of the AdminSDHolder object. Not only that, every object that’s a member of these administrative groups too has its ACE compared with the AdminSDHolder object and if these ACEs don’t match they too are replaced!

This’s a pretty good security feature actually – this way no one can hijack admin accounts. Imagine you are a nice domain admin while I am a lowly evil admin who happens to have the right to reset everyone’s passwords. Maybe I wasn’t intended to have this right – I was assigned this right to all user accounts in the domain and via inheritance your domain admin account too had the right applied. Since I am a evil admin I can wait for you to go on holidays, reset your password, login as you and make any changes in your name. When you return from holidays your password won’t work but you’ll think that’s because you forgot your password while on holiday rather than anyone resetting it inappropriately. So you’ll get someone to reset it and carry on as usual; meanwhile I have got away with what I did.

Now imagine the same scenario but with the AdminSDHolder check active. What will happen now is that I will get reset passwords rights to your domain admin account, but in less than 60 mins AD will notice that the additional ACE does not match the ACE on the AdminSDHolder object and so remove it. Your account is thus safe and I can’t do anything naughty with it!

So what is the AdminSDHolder object? It is an object in the System container of the domain. It doesn’t have any objects within it but if you right click and check the Security tab you can view the various ACEs applied to it. These are the ACEs that will be applied to each administrative group, user, and machine in this domain.


The permissions on the AdminSDHolder are quite limited and more importantly inheritance is disabled so it doesn’t inherit permissions from elsewhere. Also the owner of this object is set to the Domain Admins group. This is important as the owner of an object can reset permissions.

The list of administrative groups that the AdminSDHolder object protects various with each version of Windows Server. Below is a list from Microsoft’s page.

admin groups

Worth noting that you could be in the “Print Operators” group too and that’s enough to protect your account! Turns out that’s because the “Print Operators” group has elevated permissions on domain controllers. It is possible to exclude the “Print Operators”, “Account Operators”, “Server Operators”, or “Backup Operators” groups from being a protected group. For that you need to DS-Heuristics attribute. This is a forest-wide attribute. The 16th character of this attribute controls the groups that are excluded from the AdminSDHolder protection. This page from Microsoft shows how you can exclude the groups.

Non admin accounts keep losing their delegated rights to admin accounts (part 1)

Here’s something that I learnt the other day.

At work we use a bunch of admin accounts for various tasks. Previously all these admin accounts were part of the Domain Admins group, but recently in a drive to tighten down things we removed many of these accounts the from Domain Admins group. These accounts are still members of the other built in groups such as Account Operators and/ or Server Operators though, but not Domain Admins.

After removal we noticed that the accounts that were not Domain Admins could no longer reset passwords or unlock accounts for any admin accounts. Not surprising – since the Domain Admins group is what has such rights on all accounts once these users are removed from the Domain Admins group they naturally lost their rights. This needed fixing so here’s what we did: all our admin accounts (both Domain Admins and others) were in an OU called “Admin Accounts”, so we put the accounts that were not in the Domain Admins group into a group called Limited Admins and delegated this group rights to reset passwords on the “Admin Accounts” OU.



Notice the Limited Admins group has a reset password Access Control Entry (ACE) on the “Admin Accounts” OU. This is a result of the delegation. If I check an individual account in this OU, the ACE entry is present on it too.


Once this was done and dusted a funny thing happened. Initially the Local Admin groups members could reset everyone’s passwords but soon they complained they were unable to. We checked the OU and an example Domain Admin account and noticed the previous ACE was no longer present. The ACE was still present on the OU and on accounts that were not members of the Domain Admins group, but it was missing from accounts that were members of the Domain Admins group or even groups such as Account Operators and Server Operators. Very odd!

We checked whether any of the other admins were removing these rights intentionally but none were. Next we checked the Event Viewer but that didn’t have anything to add. Finally we enabled auditing of account management activities to see if that sheds some light. An important point (which I had missed out initially) is that to view the extra details one must check the Event Viewer of the Domain Controller with the PDC Emulator role. To find out the DC with the PDC Emulator role open “AD Users and Computers”, right click on the domain name, select Operations Master:


Sure enough when we went through the Event Viewer of this DC there was an entry which explained what was happening:

event 4780

Interesting! At least this explains what was happening. And now that we knew what was happening the next step was to read more about the AdminSDHolder object and tweak things so our accounts didn’t get their ACEs stripped. This post took longer than expected to type up, so more on that in my next post …