Help modifying code to retrieve department, manager name, and location

Hi guys! I have this bit of code below

foreach ($group in $groups) {
>>     $groupName = $group.Name
>>     foreach ($member in $group.Members) {
>>         $memberName = (Get-ADUser $member).Name
>>         Write-Output "$memberName, $groupName"
>>     }
>> }

that returns the list of members that are in groups that have a like name. I also have to return the location, department, and manager of these members but I’m having trouble doing so. I tried adding another variable to the above like this…

PS N:\> foreach ($group in $groups) {
>>     $groupName = $group.Name
>>     foreach ($member in $group.Members) {
>>         $memberName = Get-ADUser $member.Name
>>         $departmentName = Get-AdUser $member.department
>>         Write-Output "$memberName, $groupName, $departmentName"
>>     }
>> }

but it doesn’t produce what I want it to. I feel like it has something to do with my for loop…

Welcome to the forum! Thanks for sharing your code.
I’m going to assume that $Groups contains an array of Active Directory groups, possibly the result of something like this:

$Groups = Get-ADGroup -Identity "Domain  Admins" -Properties Members

Assuming in your end you’re searching for groups in a particular OU, or maybe it’s a list from somewhere else. But whatever it is let’s say it’s an array full of AD Groups.
In your first example, this is correct for looking up a user and returning the name property:

$memberName = (Get-ADUser $member).Name

This is because the $member property contains the Distinguished name of a group member. Looks something like this:
CN=John.Smith,OU=User Accounts,DC=contoso,DC=local
Get-ADUser will accept a Distinguished Name as an argument for the -Identity parameter. You’re not calling the Identity parameter by name, but you are leveraging it by position because your’re supply $member as the first argument.
By wrapping it in parenthesis you’re saying “do this first” and then the .name is returning the value of the Name property from that result.

But here’s what your second example is doing

foreach ($group in $groups) {
    $groupName = $group.Name
    # group name = Domain Admins
    foreach ($member in $group.Members) {
        # Member = CN=John.Smith,OU=User Accounts,DC=contoso,DC=local
        $memberName = Get-ADUser $member.Name
        # name = "Smith, John". This will fail to find a user as that's not a valid identity to look someone up.
        $departmentName = Get-AdUser $member.department
        # this will fail to find anything because we're feeding a department to Get-ADUser's -Identity parameter to look up a user.
        Write-Output "$memberName, $groupName, $departmentName"
    }
}

In this example the $member variable is a distinguished name like described above. It does not have a Name property or a Department property. It’s just a string. This means both your Get-AdUser lookups will fail. Here’s what I would try instead. and then I’ll explain why.

foreach ($group in $groups) {
    foreach ($member in $group.Members) {
        # Member = CN=John.Smith,OU=User Accounts,DC=contoso,DC=local
        $AdUser = Get-ADUser -Identity $Member -Properties Manager,Department,State,StreetAddress
        # AdUser now contains an ADUser object with the default returned properties PLUS the ones listed above. 
        # The manager property is a distinguished name which means we have to look them up too
        $Manager = Get-ADUser -Identity $($AdUser.Manager)

        [PSCustomObject]@{
            Name        = $AdUser.Name
            Group       = $Group.Name
            Department  = $AdUser.Department
            Manager     = $Manager.Name
            State       = $AdUser.State
            Address     = $AdUser.StreetAddress
        }
    }
}

<# example output of one member
Name       : Smith, John
Group      : Domain Admins
Department : Information Technology
Manager    : Anderson, Bob
State      : WA
Address    : 1234 Initrode lane
#>

Knowing that each “member” object from a group is a Distinguished name we know we have to do at least one AD lookup so we can get info about that user in a more meaningful way. I want to do this as few times as possible, so we do one lookup and specify all of the properties we want in addition to the default set of properties (when you run just get-aduser username).
The manager object, similar to a group member, is returned as a distinguished name so we have to do a look up on that object as well and I’m choosing to save that information in a separate variable.
Then instead of using Write-Output to return a common separated list, I’m going to continue using objects because it allows you to do more with the output. I create a PSCustomObject and define the property names on the left hand side, and their values on the right hand side.
This makes it so if you want you can capture all of this output with a variable and then filter is on the CLI, or pipe it to Export-Csv and make a spreadsheet, etc.

2 Likes

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.