CustomObject with multi-value property

I have been tasked with created an output that will list the group and along with their respective members (one per line) in a csv file. I can’t seem to get the Object to correctly list out the members and pass them to the output file.

I’ve started with this:

Import-Module ActiveDirectory
$List = @()

$groups = @(
“Group A”
“Group B”
)

foreach ($grp in $groups)
{
$obj = [PSCustomObject] @{
Name = $grp
Member = Get-ADGroupMember $grp | Select Name
}
$list += $obj
}
$List | Export-Csv “c:\temp\TestOuput.csv” -NoTypeInformation

 

Any help would be greatly appreciated.

Kurt

Try something like this:
[pre]
$groups = @(group1,group2)

foreach ($group in $Groups) {
$members = (Get-ADGroup $group -Properties members).members
foreach ($member in $members) {
$name = (Get-ADUser $member).Name
$obj+=[PSCustomObject]@{
GroupName = $Group
MemberName = $name
}
}
}
$obj | Export-Csv “c:\temp\TestOuput.csv” -NoTypeInformation
[/pre]

I will add a couple of suggestions I learned at Summit this year to Wes’s response that will offer increased efficiencies. The “+=” doesn’t necessarily act as expected. Instead of adding the object to the array it completely destroys the array and rebuilds it with the new object included. Not necessarily an issue in most scenarios but it is a waste of resources. A better way that doesn’t require the array to be rebuilt with each object is to create a blank ArrayList object and assign to a variable, then use the ArrayLists .Add() method to add the object to the end of the array. The drawback? Console output on completion of the .Add() method. Easy enough to fix by assigning the output to the $null variable. Another way to reduce the calls to your DC is to use string manipulation on your AD-Group returns rather than making a new call to the DC for each object returned. See below

$groups = @(group1,group2)

[System.Collections.ArrayList]$obj = @()

foreach ($group in $Groups) {
    $members = (Get-ADGroup $group -Properties members).members
    foreach ($member in $members) {
        $name = ($member -split ',')[0] -replace 'CN=',''
        $null = $obj.Add([PSCustomObject]@{
        GroupName  = $Group
        MemberName = $name}
        )
    }
}
$obj | Export-Csv "c:\temp\TestOuput.csv" -NoTypeInformation

I’m still new to powershell, but I have fallen in love with this way of doing it. It uses the pipeline to create the array, and it is very fast.

$groups = @(group1,group2)

$obj = foreach ($group in $Groups) {
    $members = (Get-ADGroup $group -Properties members).members
    foreach ($member in $members) {
        $name = (Get-ADUser $member).Name
        # create the object and send it to the pipeline
        [PSCustomObject]@{
            GroupName  = $Group
            MemberName = $name
        }        
    }
}
$obj | Export-Csv "c:\temp\TestOuput.csv" -NoTypeInformation

This can be simplified to:

$groups = 'Group1', 'Group2'

$results = foreach ( $group in $groups ) {
    Get-ADGroupMember -Identity $group | 
    Select-Object -Property @{Name='GroupName';Expression={$group}}, Name, SamAccountName
}

$results | Export-Csv -Path 'c:\temp\TestOuput.csv' -NoTypeInformation

Thank you all for your assistance. I will try them and let you know the outcome.

Kurt