Sunday, May 3, 2009

Use PowerShell to Recursively Get Group Members

I've noticed looking at my StatCounter logs that a few people found my post on recursion while looking for a way to recursively get group members in PowerShell, so I whipped up this script.

Note that it depends on the AD Cmdlets from Quest, and that it works in much the same way as the example. Whenever it finds that one of the group members is a group, it calls itself on that group and adds the result to the list of users.

Also note the technique of using a hashtable to keep a list of unique users. It's common to store a list in an array and use use -contains and -notcontains to find out if an item already exists, but this is tremendously inefficient compared to using a hashtable as an index, especially as the list of users gets longer, because it has to keep cycling through the list over and over. It's a trick I picked up in Perl that works equally well here.



3 comments:

Kelly said...

Do you think that may work for me?
I can't seem to get my script to check if a user is a member and if not add. Then proceed

$users = Get-QADUser -SearchRoot 'OU=Enabled,OU=Users,OU=Partners,DC=xxx,DC=com'-MemberOf 'Allpartners'
$un = read-Host "User Name domain\username" # Your domain and username
$pw = read-host "Enter password" -AsSecureString # Your Password
connect-QADService -service 'xxx.com' -ConnectionAccount $un -ConnectionPassword $pw

ForEach ($user in $Users) {Where-Object -FilterScript ($_.Memberof -ne 'Allpartners')} {
add-QADGroupMember -identity "CN=AllPartners,OU=Groups,OU=Partners,DC=xxx,DC=com" -member $user
Set-QADUser -Identity $user -ObjectAttributes @{primaryGroupID=@(222753)}
Remove-QADGroupMember -Identity 'Domain Users' -Member $user
}

tojo2000 said...

So here's how I would probably do what it looks like you're trying to do. MemberOf is an array of distinguished names, so pipe the results of your Get-QADUser and then filter out those where the MemberOf property does not contain the DN of the group you're targeting.

####### (I hope the formatting comes out right) ###

$un = read-Host "User Name domain\username" # Your domain and username
$pw = read-host "Enter password" -AsSecureString # Your Password
connect-QADService -service 'xxx.com' -ConnectionAccount $un -ConnectionPassword $pw

$group = Get-QADGroup 'AllPartners'
Get-QADUser -SearchRoot 'OU=Enabled,OU=Users,OU=Partners,DC=xxx,DC=com' |
Where-Object {$_.MemberOf -notcontains $group.dn} |
Foreach-Object{
add-QADGroupMember -identity 'AllPartners' -member $user
Set-QADUser -Identity $user -ObjectAttributes @{primaryGroupID=@(222753)}
Remove-QADGroupMember -Identity 'Domain Users' -Member $user
}

Anonymous said...

Error running...

Missing closing ')' in expression.
At C:\Windows\System32\WindowsPowerShell\v1.0\Get-RecurseMember.ps1:25 char:37