get AD users inside the groups and subgroups of OU (not duplicated)

95 Views Asked by At

I want to get email address of all the users that are indirectly in one OU, in that OU there are groups and the groups members are sometimes groups and sometimes users (I need all the users in all groups and subgroups) so I write the following script

$groups = Get-ADGroup -Filter * -SearchBase 'OU=someOU,DC=someDomain,DC=com' 
foreach ($group in $groups) 
{
$groupDN = (Get-ADGroup $group).distinguishedName 
Get-ADuser -LDAPFilter "(memberOf:1.2.840.113556.1.4.1941:=$groupDN)" |ft
}

and the problem is that some users are member of different groups and it shows them more than once . I also tried other way

Get-ADobject -LDAPFilter "(&(objectClass=person)(objectClass=user)(memberof:1.2.840.113556.1.4.1941:='OU=someOU,DC=someDomain,DC=com'))"

and it does not show anything, also tried this

Get-ADobject -Filter * -SearchBase 'OU=someOU,DC=someDomain,DC=com' -SearchScope Subtree | Select-Object name 

which shows only the qroups in that OU but I want group members and nested group members. can someone solve my problem thanks in advance  

3

There are 3 best solutions below

0
On

It's usually not a problem to have duplicate users, because 1 user can be a member of more than one group and you need all group, subgroup and user too. Or am I wrong?

But to write about the code too, the following commands can be a good choice:

  • Select-Object -Unique
  • Sort-Object -Unique
  • Get-Unique
  • [HashSet<T>]
  • Compare-Object $obj[0] $obj[1] -Property X
  • [Linq.Enumerable]::Distinct

Meausement: https://ridicurious.com/2018/04/13/unique-items-in-powershell/

Please note: I have described possible solutions and not the best solution.

Reference: https://ridicurious.com/2018/04/13/unique-items-in-powershell/

Of course I know that the coding part is the issue here, but... I think that the data you are collecting, if it looks like that somehow:

Group |Member| Email
g1    | u1   | [email protected]
g2    | g1   | [email protected]
g2    | u2   | [email protected]
g2    | u3   | [email protected]

It looks much better and is much easier to use if you display it in a pivot table or power bi.

You can make a statement that:

  • Who are the members of which group
  • Which groups a given user belongs to
  • etc.

Once again, please don't stone me for the pivot/bi, I know the coding was the issue.

1
On

You could store all users in the array and then filter out duplicates

$Users = @()
$groups = Get-ADGroup -Filter * -SearchBase OU=ZimbraImported,OU=DistributionLists,OU=Exchange,OU=Applications,DC=ad,DC=spreadgroup,DC=com" 
foreach ($group in $groups) {
    $groupDN = (Get-ADGroup $group).distinguishedName 
    $Users += Get-ADuser -LDAPFilter "(memberOf:1.2.840.113556.1.4.1941:=$groupDN)"
}
$Users = $Users | Sort-Object samaccountname| Select-Object -Unique
0
On

You can use a Hashset<T> to de-duplicate your output:

$hash = [System.Collections.Generic.HashSet[guid]]::new()
Get-ADGroup -Filter * -SearchBase 'OU=someOU,DC=someDomain,DC=com' | ForEach-Object {
    foreach ($user in Get-ADuser -LDAPFilter "(memberOf:1.2.840.113556.1.4.1941:=$($_.DistinguishedName))") {
        if ($hash.Add($user.ObjectGuid)) {
            $user
        }
    }
}