Sorry for asking a novice question, as I am learning Powershell and I am confused how select-object -property parameter works with pipeline. As mentioned in help it doesnot accept the value through pipeline.
For e.g: the below code should have given an error:
get-process|select-object -property name,vm,pm
Can someone explain or guide me, thanks in advance.
CodePudding user response:
To better understand how Select-Object
works, here is a very simplified demo function that works similar to Select-Object
:
function Select-ObjectSimplified {
[CmdletBinding()]
param (
# "ValueFromPipeline" means this parameter accepts pipeline input
[Parameter(Mandatory, ValueFromPipeline)] [PSObject] $InputObject,
# This parameter does NOT accept pipeline input
[Parameter(Mandatory)] [Object[]] $Property
)
# The process section runs for each object passed through the pipeline.
process {
# Create an ordered hashtable that will store the names and values
# of the selected properties.
$OutputObject = [ordered] @{}
# Loop over each property of $InputObject
foreach( $InputObjectProperty in $InputObject.PSObject.Properties ) {
# Check if the current property is listed in -Property argument.
if( $Property -contains $InputObjectProperty.Name ) {
# Add the current property to the output object.
$OutputObject[ $InputObjectProperty.Name ] = $InputObjectProperty.Value
}
}
# Convert the hashtable to a PSCustomObject and (implicitly) output it.
[PSCustomObject] $OutputObject
}
}
Demo:
# Create an array of two objects.
$example = [PSCustomObject]@{ Foo = 4; Bar = 8 },
[PSCustomObject]@{ Foo = 15; Bar = 16 }
# Pass the array as input to the pipeline.
$example | Select-ObjectSimplified -Property Foo | Format-List
Output:
Foo : 4
Foo : 15
Although the parameter -Property
doesn't accept pipeline input, we can still use it when we process the pipeline input that binds to parameter -InputObject
. There is no need for -Property
to accept pipeline input, because it stays constant during the whole run of the pipeline.
The demo is executed by PowerShell like this:
$example | Select-ObjectSimplified -Property Foo | Format-List
- The argument "Foo" gets bound to parameter
-Property
. The parameter-InputObject
is not bound yet, because we didn't explicitly pass an argument to it. - The first element of the array
$example
is passed through the pipeline. The argument[PSCustomObject]@{ Foo = 4; Bar = 8 }
gets bound to parameter$InputObject
. - The
process{}
section runs. There we can get the current pipeline object from$InputObject
and get the argument of parameter-Property
from$Property
. So$InputObject
will be different for each run ofprocess{}
, but$Property
does not change, it is constant. - The second element of the array
$example
is passed through the pipeline. The argument[PSCustomObject]@{ Foo = 15; Bar = 16 }
gets bound to parameter$InputObject
. - Like 3), but with different value for
$InputObject
.
Hope that shed some light on the topic. To get an even better understanding I suggest to read About Pipelines and then follow a tutorial to write your own pipeline function. The concept only did really click for me, once I successfully wrote my first real pipeline functions.