PowerShell Gotcha – Export-CSV, Out-GridView and others
I came across this one a little while back and was hoping it would be fixed in V2, I haven’t seen anyone else mention it so I thought I would add it to my blog as a warning to other PowerShell freaks like me….
I have changed the example to be more universal so you get the point:
I was creating a list of my servers and how big the disks were, to do this I decided to create a collection of custom PS objects so I could add further details to the object later as below:
$Computers = "Localhost","TESTPC01"
$AllDisks = @()
Foreach ($comp in $Computers){
$Disks = Get-WMIObject Win32_LogicalDisk -computer $comp -filter "DriveType=3" |Select SystemName,DeviceID,VolumeName,Size
$Details = New-object PSObject
$Details |Add-Member -Name Name -Value $comp -Membertype NoteProperty
$DiskNum = 0
Foreach ($disk in $disks){
$Details | Add-Member -Name "Disk$($DiskNum)DeviceID" -MemberType NoteProperty -Value $Disk.DeviceID
$Details | Add-Member -Name "Disk$($DiskNum)VolumeName" -MemberType NoteProperty -Value $disk.VolumeName
$Details | Add-Member -Name "Disk$($DiskNum)Size(MB)" -MemberType NoteProperty -Value ([math]::Round($disk.Size / 1MB))
$DiskNum++
}
$AllDisks += $Details
}
This was fine and worked as I expected, if I output the results to Format-List I had the desired results (Note my second server has 2 disks).
| $AllDisks | Format-List
Name : Localhost Disk0DeviceID : C: Disk0VolumeName : System Disk0Size(MB) : 20478 Name : TESTPC01 Disk0DeviceID : C: Disk0VolumeName : Disk0Size(MB) : 34703 Disk1DeviceID : D: Disk1VolumeName : Data Disk1Size(MB) : 140004
|
Great all results are fine you can clearly see server 1 has 1 disk and server 2 has 2 disks, so lets output them to Out-Gridview:
Spot the difference ! Yes, my second disk has disappeared and what’s more there was no error at the prompt, the same thing happens with Export-CSV.
From what I can tell these cmdlets base the row names on the first object in the collection, if the subsequent objects have more properties then it drops them with no warning to the prompt, something I found the hard way when exporting my results to CSV.
So how can we get around this ? The easiest way I have found to do this is to list the objects with the most amount of disks first so they all have the most amount of rows, either this or you will have to determine how many disks the servers are going to have as a maximum and create blank spaces for all other records.
Have you had this issue before, is it just me scripting in a strange way, I would love to hear your thoughts on this.
Thanks goes to LucD for helping me work out what was going on here !
Onyx – Why Learn PowerCLI ? PowerCLI: Bring on the next version











It has been talked about some, but usually you shouldn’t run into this as you should avoid variable amounts of properties on the same type objects.
One work around is to create a disk count property with the number of disks, then sort that descending before piping to Export-CSV or Out-GridView.
I was going to suggest creating an object for each disk that includes the computer name, then group by computer name. But it appears that they removed the group fuctionality from Out-GridView!
Al, did you tried $AllDisks|select *|Out-GridView ?
@Jason Archer
Thanks for the comment, glad to see its not just me ! looks like we used the same workaround too, my main purpose of the post is to let people know it happens as there is no output to the screen to tell you that it has dropped some rows.
Interesting topic. One workaround would be to pipe the output through
$yourinput | Sort-Object -Property @{Expression={$_.psobject.properties | Measure-Object | Select-Object -ExpandProperty Count};Descending=$true} | out-gridview
or something to that effect.
I think the challenge lies in the fact that we are dealing with an object pipeline of dynamic objects and, as you’ve described, the property list is being determined by the first object through the pipeline, rather than being dynamically modified by the objects entering the pipeline.