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-InputObjectis not bound yet, because we didn't explicitly pass an argument to it. - The first element of the array
$exampleis 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$InputObjectand get the argument of parameter-Propertyfrom$Property. So$InputObjectwill be different for each run ofprocess{}, but$Propertydoes not change, it is constant. - The second element of the array
$exampleis 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.
