Mathias R. Jessen has provided the crucial pointer:
In order to have Select-Object
extract only a property value from its input objects, that property's name must be passed to the -ExpandProperty
parameter.
- By default, with the (positionally implied)
-Property
parameter, even if you pass just one property name, that property's value is copied to a property of the same name in the output object, as evidenced by your output: a [pscustomobject]
instance with a single property, Propertynames
, was emitted.
Additionally, if the property values happen to be arrays, their elements are enumerated.
- This enumeration does not happen with
-Property
.
Note that this means that when the name of an array-valued property is passed to -ExpandProperty
and there are multiple input objects, a flat array of values is returned, which is the concatenation of the individual property-value arrays[1], so that the input-object boundaries are lost:
A simple example:
[pscustomobject] @{ foo = 1, 2 }, [pscustomobject] @{ foo = 3, 4 } |
Select-Object -ExpandProperty foo
The above outputs flat array 1, 2, 3, 4
.
Note that member-access enumeration behaves the same way - except that it requires the input collection to be collected in memory in full first:
# Except for not *streaming* the input objects, the result
# is the same as above:
([pscustomobject] @{ foo = 1, 2 }, [pscustomobject] @{ foo = 3, 4 }).foo
[1] Since the elements of a property that contains a collection - which or may not technically be an array - are enumerated to get the result, you'll always end up with regular PowerShell array, of type [object[]]
.