I have a [pscustomobject] with the property ‘id’. According to PowerShell documentation, the parameter ‘-id’ can be passed through the pipeline using ByPropertyName. I discovered that the approach with ForEach-Object works (although I don’t understand why), while the approach without ForEach-Object does not.
$obj = [pscustomobject]@{id=4444}
# doesn't work
$obj | get-process -id $_.id
# it works
$obj | foreach{get-process -id $_.id}
apparently the "foreach" does the trick, but why?
>Solution :
The
ValueFromPipelineByPropertyNameargument indicates that the parameter accepts input from a property of a pipeline object. The object property must have the same name or alias as the parameter.
The binding happens by pipeline already, you don’t need to manually pass the argument, moreover, $_ (PSItem) is only automatically populated in the context of scriptblock and your second statement has no scriptblock.
$obj = [pscustomobject]@{ id = 4444 }
# works, the value of `id` is taken from pipeline
$obj | Get-Process
As to why the ForEach-Object example works, simply because you’re passing the value of id property as argument to the -Id parameter, it is pretty much the same as:
Get-Process -Id $obj.Id