Home > database >  How select-object cmdlet accepts input by pipeline?
How select-object cmdlet accepts input by pipeline?

Time:05-11

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

  1. 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.
  2. The first element of the array $example is passed through the pipeline. The argument [PSCustomObject]@{ Foo = 4; Bar = 8 } gets bound to parameter $InputObject.
  3. 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 of process{}, but $Property does not change, it is constant.
  4. The second element of the array $example is passed through the pipeline. The argument [PSCustomObject]@{ Foo = 15; Bar = 16 } gets bound to parameter $InputObject.
  5. 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.

  • Related