Powershell Script to output all Distribution groups and nested groups into a csv

powershell

Hi I'm pretty new to powershell so I might be going about this completely wrong but I have to dump all our companies Distribution groups, their nested groups, and the users of those groups into a csv or txt file. So far I got a list of all the names of our Distribution groups by doing

Get-DistributionGroup | select name >> goups.csv

and from there I'm trying to run it through a script that will trim the whitespace on the names and pipe each value through the Get-QADGroupMember command and output that into a final csv. Here's what I have so far…

Import-Module ActiveDirectory

Add-PSSnapin quest.activeroles.admanagement

$GroupList = Import-Csv groups.csv | ForEach-Object {
$_.PSObject.Properties | ForEach-Object {$_.Name = $_.Name.Trim()}
}

ForEach ($_ in $GroupList){
   $_.Name

 Get-QADGroupMember $_.Name -indirect | sort name >> $_.Name.csv

   }

and right now it's saying that "Name" is a read only property. I've tried setting read only as false through powershell but its still giving the same error. Is there something I did wrong when writing this?

Best Answer

You seem to have been trapped by property inception

The $_.PSObject reference gives you access to runtime metadata about the object in question, no need to fiddle around with this

$GroupList = Import-Csv groups.csv | ForEach-Object {
$_.PSObject.Properties | ForEach-Object {$_.Name = $_.Name.Trim()}
}                                           ^
                                            |
                  This is the Name property of the Name NoteProperty from the CSV

For the Name property that you want, you only need a single ForEach-Object run. Also, since the value of the Name property is the only thing you are really interested in, you can either just drop $_.Name.Trim() in the pipeline instead of assigning it to $_.Name or you can use Select-Object:

$GroupList = Import-Csv .\groups.csv | ForEach-Object {
    $_.Name.Trim()
}

$GroupList = Import-Csv .\groups.csv | ForEach-Object {
    $_.Name = $_.Name.Trim()
} | Select-Object -ExpandProperty Name

You can do with the Active-Directory module alone, using the -Recursive switch, which serves the same purpose as ActiveRoles' -Indirect.
Instead of using classical cmd output redirection, you should pipe the output to Out-File or Export-Csv:

foreach($Group in $GroupList)
{
    Get-ADGroupMember $Group -Recursive | Select-Object Name | Sort-Object Name | Out-File "$Group.csv" -Append
}