PowerShell: get group membership using .NET

Hi All,

So recently I needed to get all the members of a group and all the members of the groups that a members of each of those groups… right on down the line. My head began to swim thinking about writting a function to get the members of one group, then degermine if a member was a user, computer, or another group, then getting the members of that group and so on, all while collecting the users in some form of global collection. really, it is messy!

Add to that, the fact that I don’t have a 2008 domain so everything here is of no value.

So, off I started my hunt and came across the .NET object GroupPrincipal in System.DirectoryServices.AccountManagement.

First thing I need to do is load the assembly so I have access to GroupPrincipal.

Add-Type -AssemblyName  System.DirectoryServices.AccountManagement

GroupPrincipal has a FindByIdentity method to get a group by name. But, the FindByIdentity requires a PrincipalContext.

PrincipalContext is defined as:

Encapsulates the server or domain against which all operations are performed, the container that is used as the base of those operations, and the credentials used to perform the operations.

This says to me that it is some kind of logical grouping for where the FindByIdentity should be looking. Looking into the simplest of the contstructor for the PrincipalContext “PrincipalContext(ContextType)” says it requires a ContextType. The Context Type is an enum for Machine, Domain, or ApplicationDirectory. For what I’m doing, I want the Domain option.

So, in PowerShell I need to create a new ContextType object for the domain.

$ContextType = [System.DirectoryServices.AccountManagement.ContextType]::Domain

Then, I need to use that to find my starting group by identity (name).

$group = [System.DirectoryServices.AccountManagement.GroupPrincipal]::FindByIdentity($ContextType ,"My-Group")

Lastly, I need to get the members of the group

$group.GetMembers() |ft -auto

Well, that’s great, but it doesn’t give me all the members of the group! Looking at that GetMembers member, I can see there are two signatures. GetMembers() & GetMembers(bool recursive)! So now, instead of $group.GetMembers() |ft -auto, I can use $group.GetMembers($true) |ft -auto! and Poof! There is everyone in that group and that group’s groups straight on down the line!

Sweet!

Now, here it is in it’s entirety:

$ContextType = [System.DirectoryServices.AccountManagement.ContextType]::Domain
$group = [System.DirectoryServices.AccountManagement.GroupPrincipal]::FindByIdentity($ContextType ,"My-Group")
$group.GetMembers($true) |ft -auto

Leave a Reply