thepip3r
thepip3r

Reputation: 2935

PowerShell: Collection converted to array reporting array-value lengths instead of array-values

$sample = @"
name,path,type
test1, \\server1\path1\test1.txt, 1
test2, \\server1\path1\test2.txt, 1
test3, \\server1\path2\test3.txt, 2
test4, \\server1\path1\test4.txt, 2
test5, \\server1\path3\test1.txt, 3
"@

$s = $sample | ConvertFrom-Csv

$g = $s | Group-Object -Property type
# $g[0].Group.GetType() reports as Collection`1

$t = $g[0].Group | Select -ExpandProperty Path
# $t.GetType() reports as Name=Object[], BaseType=System.Array

$t
# reports:
# \\server1\path1\test1.txt
# \\server1\path1\test2.txt

$t | Select *
# reports:
# Length
# ------
#    25
#    25

I've run into a problem in one of my scripts that I was able to reproduce with the previous code. I have an array from Import-Csv that includes a bunch of UNC paths. I'm grouping those paths based on different CSV-attribute criteria and then trying to use the resulting .Group property Collection object to perform more work on that group. My problem is that if I try to do anything with that object besides just emit it to the console, the object reports as the value lengths rather than the values itself.

For example: $t | Converto-Html -Fragment

Can anyone explain what's going on that the lengths are being emitting as opposed to the values and ultimately how to fix this to get the values instead of the lengths with Group-Object, Group Properties involved? TIA

Upvotes: 1

Views: 92

Answers (1)

mklement0
mklement0

Reputation: 437052

Since you're using -ExpandProperty, $t = $g[0].Group | Select -ExpandProperty Path stores (an array of) mere string values ([string] instances) in $t, namely the values of the .path properties on the input objects.

Select * reports the properties of those [string] instances (wrapped in [pscustomobject] instances), and given that strings only have one property - .Length - you'll see those length values only, not the strings' contents.

A simple example (reports the length of string 'one', i.e., 3):

PS> 'one' | Select-Object *

Length
------
     3

Note that you'd get a similar result with ConvertTo-Csv / Export-Csv, because they too serialize properties of their input objects:

PS> 'one' | ConvertTo-Csv
"Length"
"3"

If you omit the -ExpandProperty switch, you get [pscustomobject] instances with a .Path property containing the path strings of interest:

PS> $g[0].Group | Select Path

path
----
\\server1\path1\test1.txt
\\server1\path1\test2.txt

Upvotes: 1

Related Questions