Question

I am trying to make a list of all groups that contain members from a specific OU. To do this, I am reading a file with the list of all group names and using get-ADGroupMember $groupName to find the members of each group. I am converting the value of each member to string and comparing to $member.indexOf("specific OU"). The problem is, I haven't figured out how to get $member[$i].indexOf("specific OU"). My code is below.

EDIT: If I use a for-each loop I can loop through the members properly, but I cannot use the break, which prevents duplicates.

Import-Module ActiveDirectory
#declaring end result group array
$results = @()

#sets path for files
$pathName = $MyInvocation.MyCommand.Path
$pathLen = $pathName.LastIndexOf("\")
$pathStr = $PathName.Substring(0,$pathLen +1)
$APgroupFile = $pathStr + "APGroups.csv"
$groupFile = $pathStr + "GGroups.csv"

#gets the list of group names and loops through them
get-content $groupFile | foreach-object{
#sets all of the group names
#start of if1 
if($_.IndexOf("CN=") -ge 0){
$nameStart = $_.IndexOf("CN=")+3
$nameEnd = $_.indexOf(",")-$nameStart
$name = $_.substring($nameStart, $nameEnd)

#issue starts here
#goal is to find member of "specific OU".
#If found, add group to $results.  If not, go to next group
$members = get-ADGroupMember -Identity $name
if($members.length -gt 0){
$i=0
for($i=0; $i -le ($members.length -1); $i++){
#need to check users OU for specific OU.  If a user is member, save group to .txt.  If none are members, move to next group
    $OU = $members.toString()
    if($OU.indexOf("OU=specific OU") -ge 0){#start of if OU
    $results += New-Object psObject -Property @{'GroupName'=$name; 'Member'=$OU}
    break
    }#end if OU
    }#end for mem.length
}#end if mem.length
}#end if1
}#end foreach

$results | Export-Csv $APgroupFile -NoTypeInformation
Was it helpful?

Solution

Try this:

Get-ADGroupMember -Identity $name |
Where-Object {$_.distinguishedName -like '*OU=specific OU*'}

OTHER TIPS

A consideration that you did not explicitly mention: what about nested OUs? I.e., are you only considering a member immediately within your target OU? Or would a member of an OU two or three levels deep also logically, for your purposes, be included? E.g., if "California" is your target OU, do you want only objects directly under California? Or do you want to include all the members of San Francisco and all the members of San Diego (which are sub-OUs of California) in the result set? Either way:

Get-ADUser includes search and filter capability - http://technet.microsoft.com/en-us/library/ee617241

  Get-ADuser -Filter {sAMAccountName -eq "jdoe"} -SearchBase "OU=IS,DC=foodomain,DC=com" -SearchScope SubTree

  Get-ADuser -Filter {sAMAccountName -eq "jdoe"} -SearchBase "OU=IS,DC=foodomain,DC=com" -SearchScope OneLevel

So the approach here is to search your target OU for your target user, a separate search for each user. You will get that user in the returned result-set, or not. That can be the condition you test for. Obviously you will want to replace "jdoe" with the appropriate variable (I think $members[i].SamAccountName will do the trick there).


Just saw Shay Levy's answer. Much more concise, good job. Without explicit searchbase, you might end up visiting containers with the same name that are buried under other parent OUs, but the result set should be the same. E.g., if every city contains a standard "Office Staff" OU, each of them will be searched with the "OU=Office Staff" expression. You might want to try both approaches and test for performance differences. That being equal, Shay Levy's reads more pleasantly.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top