Analyse multiple assignement / nested groups

Dear Forum

Is there a possibility to find out for which users in an specific OU in the Active directory groups are assigned multiple times via nesting? it would be nice to have the result expoted in a CSV File.

User A is member af Group _a, but he recives this right not directlry but from an “upper” Group_supperior_A and a second assignement also from an other “upper” Group_supperior_B.

I need to analyse this multiple assignements, to eliminate them.

I have absolutely no idea, how to start. I get only the membership once and not multiple times

There’s always a way. :wink:

You could start with a query in which groups the user is directly. And run a seconds query to find all groups the user is memebr of. Now you compare these two queries and your done.

Thanks Olaf for your help
I already searched for direct assignements per one user and i searched recursive and I have the result per one user. But I don’t get in the recursive from where he gets this permission it shows me the ad group only once, but in fact he recieves it over mutliple ways.
And I wish do search this over all users.
With my knowledge I am at the limit to do that.


since we do not like to deliver ready to use code on request you may start with sharing the code you have so far and an explaination where you stuck.

I’d recommend to query all AD users once including their attribute “MemberOf” and all AD group once with their attribute “Members” and save the results for later use. This way you can work with the saved query results and do not need to query your AD again and again.

BTW: When you post code or sample data or console output please format it as code using the preformatted text button ( </> ). Simply place your cursor on an empty line, click the button and paste your code.
Thanks in advance

Hi Olaf
with this script I get the Clients of a specific ou and their assignet groups (MemberOf) no recurse

Get-ADComputer -Filter { Name -Like "*" } -SearchBase "myOU" | ForEach-Object { "" ; $_.SamAccountName ; "- - - -" ; Get-ADPrincipalGroupMembership $_ | Select-Object SamAccountName } | Out-File -FilePath "C:\Temp\Clients-MemberOf.csv" -Append -Encoding unicode

the problem is, that i wish it recoursivly and i wish as much lines per computer as much the computer is memberof a group.

in the recursive export I wish to see from where the user or in my script the client gets this assignement (see example)


and with this script i get the AD Groups of this specific ou

$OU = 'myOU'
# Get adgroups from specific OU
$adGroups =  Get-ADGroup -Filter * -SearchBase $OU
# Iterate through adgroups and get ad group name and user name
$adGroupMembers = foreach ($Group in $adGroups) {
    Get-ADGroupMember -Identity $Group -Recursive | Select-Object @{Name='Group';Expression={$Group.Name}}, @{Name='Member';Expression={$_.Name}}
# export ad group name and user to csv file
$adGroupMembers | Export-Csv -Path C:temp\adGroupMembers.csv -NoTypeInformation

How to mearch this results togehter that i can see the multiple assignements and count them per client / user

Before we proceed - may I ask whatfor do you want to have these information?

In your initial post you wrote:

What do you mean with “… eliminate them”?

I want that a client or user only gets a certain ad group only over one way and not over several ways. First I just want to know over how many ways the client or user gets the membership of this group.
When I have the result I need to analyse, which of this ways is the right and which could maybe be eliminated.
This is a manualy task and therefore it’s helpfull to have the result in an export file

OK, the reason I’m asking these question is - if there is a certain way a user or computer should get its group memberships, why not doing it the right way in the first place? So there wouldn’t be the need to do the hard work of analyzing the current state.

Lets “brainstorm” a little bit … :wink: :wink:

With the following snippets we get a complete list of groups including their memberships of a given list of searchbases and a complete list of users including their memberships of the given list of searchbases:

$SearchBaseList = @(

$AllGroupList = 
foreach ($SearchBase in $SearchBaseList) {
    Get-ADGroup -Filter * -SearchBase $SearchBase

$AllGroupMemberList =
foreach ($Group in $AllGroupList) {
    $MemberList = Get-ADGroupMember -Identity $Group.samaccountname -ErrorAction Stop
    foreach ($Member in $MemberList) {
            Group  = $Group
            Member = $Member

$AllUserList = 
foreach ($SearchBase in $SearchBaseList) {
    Get-ADUser -Filter * -SearchBase $SearchBase -Properties MemberOf

Now we can work with the data in the variables and don’t need to query the AD anymore.

To get the groups a user is direct member of is not that hard. Just for simplicity I select the first user.

$FirstUSer = $AllUserList | Select-Object -First 1

$DirectGroupMemberships =
$AllGroupMemberList |
    Where-Object {
        $_.Member.sAMAccountName -eq $FirstUSer.sAMAccountName

To get the groups a user is indirect member of isn’t that hard either:

$IndirectGroupMembership = 
$AllGroupMemberList |
Where-Object {
    $_.Member.sAMAccountName -eq $FirstUSer.sAMAccountName
} |
        ForEach-Object {
            $Group = $
            $AllGroupMemberList |
                Where-Object {
                    $Group.samaccountname -eq $_.member.samaccountname

… but to show the relations between the groups it’s better to show the complete result in this case:


Depending on the depth of the nesting structure of your AD groups you could repeat the last step with the result of the last step to digg deeper into the structure or you could create a recursive function to do it automatically and display the nested groups as needed.

I hope you can use something of this or at least it gives you some inspiration. :wink:

yes you are right, but this is actually the problem I am strugling with, to organize the chaos