In-Depth

How To Find Nested Active Directory Group Memberships in PowerShell

Find the actual number of users in a group by locating those that may be hard to find in a hidden subgroup.

As someone that manages Active Directory users and groups, trying to figure out the true membership of a particular group can be hard. Why? It's because of the way in which Active Directory allows groups to nested inside one another.

Let's say that I have a group called Grandparent. This group is then assigned various permissions throughout your environment. One day you discover that a user that was assigned to a group called Child is somehow inheriting the rights that the Grandparent group has. How did this happen? This could easily happen if this Child group is nested inside of one or more other groups that have different ACLs set in the same places. There are lots of scenarios like this I've personally come across in my years of managing Active Directory and it's a topic that can have major consequences if not addressed properly.

When you add a user into a group with Active Directory Users and Computers you don't have an easy way to determine what groups this user will truly be a member of. You aren't able to see parent groups of the group at hand. By using PowerShell though, we can use the power of recursion to allow you to specify a group and then be able to find all the users that group truly has.

To do this, we'll first need to figure out any groups that are members of that group, query each of those groups and continue doing this until we come to a group that has no other nested groups. This is recursion and, with PowerShell, we can create a function that can automatically do this for us.

First, you'll need to ensure you have the Remote Server Administration Tools installed and I'm assuming that you had read permissions in Active Directory to read group memberships. I'll be performing this on domain-joined computer.

I have a group called Grandparent in Active Directory. I first need to determine its membership. I can do this through the Get-ADGroupMember cmdlet. I'll first check out the members of the Grandparent group.

PS> Get-ADGroupMember Grandparent

[Click on image for larger view.]  Figure 1.

You'll see that I just have a single member and it's a group called Parent. Now, let's see what members the Parent group has.

PS> Get-ADGroupMember Parent
[Click on image for larger view.]  Figure 2.

 

I just have another group called Child. I do the same for Child.

PS> Get-ADGroupMember Child
[Click on image for larger view.]  Figure 3.

You can see that I finally come to the end of the line with only a single user object in the Child group. At this point, we don't need to query any other group memberships to get a true picture of all users being "in" the Grandparent group.

We now need to do this automatically with a function rather than manually querying each group's membership.

function Get-NestedGroupMember 
{
[CmdletBinding()]
param
(
[Parameter(Mandatory)]
[string]$Group
)

## Find all members in the group specified
$members = Get-ADGroupMember -Identity $Group
foreach ($member in $members)
{
## If any member in that group is another group just call this function again
if ($member.objectClass -eq 'group')
{
Get-NestedGroupMember -Group $member.Name
}
else ## otherwise, just output the non-group object (probably a user account)
{
$member.Name 
}
}
}

You can see from above, I've built a small function called Get-NestedGroupMember. It's a function that uses recursion to call itself when it encounters another group nested inside of a group. If it detects that a group member is not a group it will simply output the name of that object to the console.

I've run this function against the same scenario as I explained earlier with the Grandparent/Parent/Child groups.  Now, instead of having to manually run Get-ADGroupMember for each of these groups I can now simply pass the group name of Grandparent to my Get-NestedGroupMember function and immediately see my user account of Adam Bertram.

PS> Get-NestedGroupMember –Group Grandparent
[Click on image for larger view.]  Figure 4.

About the Author

Adam Bertram is a 20-year veteran of IT. He's an automation engineer, blogger, consultant, freelance writer, Pluralsight course author and content marketing advisor to multiple technology companies. Adam also founded the popular TechSnips e-learning platform. He mainly focuses on DevOps, system management and automation technologies, as well as various cloud platforms mostly in the Microsoft space. He is a Microsoft Cloud and Datacenter Management MVP who absorbs knowledge from the IT field and explains it in an easy-to-understand fashion. Catch up on Adam's articles at adamtheautomator.com, connect on LinkedIn or follow him on Twitter at @adbertram or the TechSnips Twitter account @techsnips_io.


Featured

comments powered by Disqus

Subscribe on YouTube