I was reading about how pipeline works in PowerShell at about_Pipelines, and got to know that pipeline delivers one object at a time.
So, this
Get-Service | Format-Table -Property Name, DependentServices
Is different from this
Format-Table -InputObject (Get-Service) -Property Name, DependentServices
So here, going by the explanation, in the first case, the Format-Table
works on one object at at time and in the second example, Format-Table
works on an array of objects. Please correct me if I am wrong.
If this is the case, then I wonder how does Sort-Object
and other cmdlets that need to work on collections of data work with pipe character.
When I do :
Get-Service | Sort-Object
How is Sort-Object
able to sort if it just gets to work with one object at a time. So, assume there are 100 service objects that are to be passed to Sort-Object
. Will Sort-Object
be called 100 times (each for one object) ? And, How will that yield in Sorted results that I see on the screen.
Sort-Object
(and other cmdlets that need to evaluate all input objects before outputting anything) work by collecting the input objects one by one, and then not doing any actual work until the upstream cmdlet (Get-Service
in this case) is done sending input.How does this work? Well, let's try and recreate
Sort-Object
with a PowerShell function.To do so, we first need to understand that a cmdlet consists of 3 separate routines:
Begin
- theBegin
routines of each cmdlet in a pipeline are invoked once before anything else occursProcess
- this routine is invoked on each cmdlet every time input is received from an upstream commandEnd
- this is invoked once the upstream command has calledEnd
and there are no more input items forProcess
to process(These are the block label names used in PowerShell function definitions - in a binary cmdlet you'd override the implementation of
BeginProcessing
,ProcessRecord
,EndProcessing
methods of your cmdlet)So, to "collect" every input item, we need to add some logic to the
Process
block of our command, and then we can put the code that operates on all the items in theEnd
block:If we invoke our new command with
-Verbose
, we will see how the input is collected one by one:For more information on how to implement pipeline input processing routines for binary cmdlets, see the "How to Override Input Processing".
For more information on how to take advantage of the same pipeline semantics in functions, see the
about_Functions_Advanced_Methods
and related help topics