Can someone please help me understand the difference between the below two pieces of code . Why are the results different for both . I each case i am selecting the same property (name) :
Code 1 :
$obj = Get-Service | Where-Object {$_.Status -eq "Running"} | foreach-object {$_.Name} | select -first 3
foreach ( $item in $obj ) { write-output "Name is : $item" }
Output :
Name is : AeLookupSvc
Name is : Appinfo
Name is : AudioEndpointBuilder
Code 2 :
$obj = Get-Service | Where-Object {$_.Status -eq "Running"} | select -first 3 name
foreach ( $item in $obj ) { write-output "Name is : $item" }
Output :
Name is : @{Name=AeLookupSvc}
Name is : @{Name=Appinfo}
Name is : @{Name=AudioEndpointBuilder}
Select-Object returns an array of custom objects to the pipeline; in this case having only one property which happens to be a string.
As @walidtourni mentions, using expand
works around this issue. This is because expand
causes the output to be the property's value, instead of a custom object with a property with that value. The reason this is possible is expand
only takes one argument; i.e. there's no possibility of you attempting to return multiple values for the same "row".
The foreach-object on the other hand is simply spitting stuff out to the pipeline. If you tried to include a second property without manually wrapping both into a custom object, the output would create another row rather than two properties on the same row.
To demonstrate, run the following:
Clear
$x = Get-Service | Where-Object {$_.Status -eq "Running"} | select -first 3
$x | foreach-object {$_.Name} #returns 3 rows, single column; string
$x | foreach-object {$_.Name;$_.CanPauseAndContinue;} #returns 6 rows, single column; alternate string & boolean
$x | select Name #returns 3 rows, single column (string); custom object
$x | select Name, CanPauseAndContinue #returns 3 rows, two columns (string & boolean); custom property
$x | select -expand Name #returns 3 rows, single column; string; notice the lack of column header showing this is a string, not a string property of a custom object
$x | select -expand Name,CanPauseAndContinue #error; -expand can only take single valued arguments
$x | select -expand Name -expand CanPauseAndContinue #error; you can't try to define the same paramenter twice
For similar result you can change the second example like this:
select -first 3 -expand name
Select-object select properties object
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With