Tar Heel
Tar Heel

Reputation: 65

Loop through nested AD groups until all members are found

I need help figuring out the logic for looping through Active Directory security groups to find all members of any nested groups using Get-ADGroupMember. If I use the recursive switch on that cmdlet, it doesn't capture the name of the nested group, just the members. I need to capture everything. I feel like this needs to be done using a while or do/while.

This section of code gets me most of the way there. However, I can't figure out how to prevent it from running the Get-AdGroupMember inside of the while if the objectclass is User. I'm testing with 4 AD groups called "testgroup1", "testgroup2", "testgroup3" and "testgroup4". Testgropus 1,2 and 3 each have a single user as a member. Testgroup2 is a member of Testgroup1. Testgroup3 is a member of Testgroup2. Testgroup4 is a member of Testgroup 3 and it also has 4 users as members.

$groups = Get-ADGroupMember 'testgroup1'
$allGroups =$null

While($groups){
    $allGroups += $groups.SamAccountName
    $groups = $groups.SamAccountName | Get-ADGroupMember 
}

$allGroups

Upvotes: 2

Views: 2600

Answers (1)

Tar Heel
Tar Heel

Reputation: 65

We solved this issue by creating a function that gets the members of an AD group and adds only users to an array. If the object class returns as a group it calls the same function again on that new group and then adds users under it to the same array. Code is below.

function Get-MBusers {
Param (
    $Group,
    $adserver
)

$users=@()    

$members = Get-Adgroup -Identity $Group -Server $adserver -Properties members | Select-Object -ExpandProperty Members | Where-Object {$_ -notmatch "ForeignSecurityPrincipals"}  | ForEach-Object {Get-ADObject $_ -Server $adserver}
foreach ($member in $members) {
    Write-Debug "$($member.Name)"

    $type = Get-ADObject $member -server $ADServer -Properties samAccountname

    if ($type.ObjectClass -eq 'user') {
        $users += Get-Aduser $type.samaccountname -Server $ADServer
    }

    # If it's a group
    if ($type.ObjectClass -eq 'group') {
        Write-Debug "Breaking out group $($type.Name)"
        $users += Get-MBUsers $member $adserver
    }

}    

return $users

}

Upvotes: 1

Related Questions