0

Problem Break-Down

So I'm trying to return a list of all the security user groups a user is in but have it be broken up by manager. I take a couple of steps to do this:

  1. Get all users into UserList
  2. Gather a list of managers using the list of users.
  3. Sort the list of managers into a unique list.
  4. Get Manager SamAccountNames.
  5. Get directreports attribute from the managers to create the list of subordinates.
  6. Get their SamAccountNames
  7. Use SamAccountNames to pull AD Security Groups and Descriptions.

Everything works when used in little pieces. If you declare some names for $DirectReports and then run the final for loop it returns everything appropriately.

When running the script however, it returns only the Manager name, the direct report name, and all the lines for the security groups but nothing is in the lines for the security groups.

No relevant error message. Thanks in advance for the help.

Code

#Search Organizational Unit to find all Users
$UserList = @(Get-ADUser -Filter * -SearchBase "COMPANY'S ORG UNITS").SamAccountName 

#For every user found in OU, select their manager
foreach ($User in $UserList) {
    $Manager = @(Get-ADUser $User -Properties * | Select-Object @{Name = "Manager";Expression = {($_.manager -split ',*..=')[1]}})
    $Managers += $Manager
}

#Sort and Select Unique Managers
$Managers = $Managers | Sort-Object -Property Manager -Unique

#Get SamAccountName From Manager Name
for ($a = 0; $a -lt $Managers.Count; $a++) {
    $FilterString = "Name -eq '{0}'" -f $Managers[$a].Manager
    $SAM = @(Get-ADUser -Filter "$FilterString" | Select SamAccountName)
    $SAMs += $SAM

}

#Get subordinates for each manager
for ($b=0; $b -lt 1; $b++) {
    
    #Get direct reporting individuals, second line cleans up output.
    $DirectReports = @(Get-ADUser $SAMs[$b].SamAccountName -Properties directreports | select-object -ExpandProperty DirectReports) 
    $DirectReports = $DirectReports -replace "(CN=)(.*?),.*",'$2' 
    
    $Managers[$b+1]
    Write-Output "`n"

    #Get SAM names for direct reporting individuals and use to get user properties
    for ($c = 0; $c -lt $DirectReports.Count; $c++) {
        $FilterString2 = "Name -eq '{0}'" -f $DirectReports[$c]
        $DirectReports[$c]
        $SAM2 = @(Get-ADUser -Filter "$FilterString2")
        $SAM2.SamAccountName
        Get-ADPrincipalGroupMembership -Identity $SAM2.SamAccountName | Get-ADGroup -Properties * | select name, description
        Write-Output "`n"
    }
} 
4
  • I don't understand step 5 - you want to discover all users who have the same manager while searching for the group memberships for a single user? Commented May 13, 2022 at 14:18
  • @MathiasR.Jessen Hey there, yes, I figure out all the managers and then figure out all their subordinates, which is easier to do with directreports. I know it's kind of round-a-bout but it gets done what I need done. Is there an easier way to pull users with the title manager and get their directreports from AD? Commented May 13, 2022 at 14:27
  • When Format-Table formatting is applied, which happens implicitly if an object has 4 or fewer properties, the first object in a collection locks in all display columns based on its properties. If subsequent objects have different properties, only those they share with the first one are displayed; if a given object shares none, a blank line is displayed. This is only a display problem, as you can verify by piping the objects to ... | Format-List. See this answer for more information. Commented May 13, 2022 at 14:36
  • If that is indeed your problem, we can close your question as a duplicate. Commented May 13, 2022 at 14:37

1 Answer 1

2

Alright, couple of things we need to improve in your solution, but you are in the right path.

You're doing:

  • Get all AD users
  • Get all managers uniquely
  • Get managers AD info
  • Get managers direct report
  • Get group membership of all direct reports

If you just want to return a list of SG per user, you could just go with:

$users = Get-ADUser -Filter * -Properties MemberOf
foreach ($membership in $users.MemberOf) {
    Get-ADGroup -Identity $membership
}

If you want something from the managers themselves, you could go:

## Get list of managers (DirectReports not null)
$managers = Get-ADUser -Filter { -not (DirectReports -like '*') } -Properties DirectReports

#Get subordinates for each manager
foreach ($manager in $managers) {
    foreach ($user in $manager.DirectReports) {
        $groupMembership = Get-ADUser -Identity $user -Properties MemberOf
        foreach ($membership in $groupMembership.MemberOf) {
            Get-ADGroup -Identity $membership | Select-Object Name, Description
        }
    }
} 

But for me this is just extra redundant work.
You can also use the Get-ADGroup cmdlet to list all groups.

Now let me explain what I changed from your script.

  • foreach loops instead of for loops. This makes object management easier

  • DistinguishedName is an identity together with SamAccountName, SID, ObjectGUId... Parsing DN for the CN is not reliable.

  • Instead of getting the users, then getting the managers, then getting the users again, then getting the groups, why not just get all groups?

  • No need to use the Get-ADPrincipalGroupMembership, there is an attribute called 'MemberOf' on the user object.

Things worth mentioning while using the ActiveDirectory PS module:

  • Be careful with the '-Filter *', some AD structures are too big and you'll end up with a timeout.

  • Use the '-Properties *' the least possible. Adding properties to the LDAP query slows it down considerably! and you may end up with a timeout. You can go for specific attributes instead, like '-Properties MemberOf'.

  • Even when specifying a single attribute, the standard ones always comes together. These are: DistinguishedName, Enabled, GivenName, Name, ObjectClassm ObjectGUID, SamAccountName, SID, Surname, UserPrincipalName.

I hope it helps!

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.