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.