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 an independent consultant, technical writer, trainer and presenter. Adam specializes in consulting and evangelizing all things IT automation mainly focused around Windows PowerShell. Adam is a Microsoft Windows PowerShell MVP, 2015 powershell.org PowerShell hero and has numerous Microsoft IT pro certifications. He is a writer, trainer and presenter and authors IT pro course content for Pluralsight. He is also a regular contributor to numerous print and online publications and presents at various user groups and conferences. You can find Adam at adamtheautomator.com or on Twitter at @adbertram.

Featured

comments powered by Disqus

Office 365 Watch

Sign up for our newsletter.

I agree to this site's Privacy Policy.