How Do I... Determine My Function's Position in the Pipeline

Page last modified 02:43, 28 Dec 2009 by Jaykul | Page History
Table of contents
No headers

This came up on IRC in the context of determining whether a function was the last function on the pipeline, in order to create formatted output in that case, and output objects otherwise. Before I give the solution, I just want to say: don't do that. 

That is, don't change your output based on where you are in a pipeline.

There are numerous scenarios where your function will be the last one on a pipeline, but still be participating in further pipelines, including formatting and output modification. For example, take our function (defined below) Test-Pipeline in these three scenarios below. In none of these scenarios would it be appropriate for the function to write formatted output instead of outputting the raw object, but in each case, the function is the last function in the pipeline.

# Assignment
$order = Get-ChildItem | Test-Pipeline
$order | Format-Table *

# Nested Pipelines
Get-ChildItem | Where-Object { $_.PsIsContainer} | ForEach-Object {
Get-ChildItem $_ | Test-Pipeline
} | Select-Object Pipe*

# Nested Expressions
@( Get-ChildItem | Test-Pipeline )[0].PipelineLength | ForEach-Object { $_ }

 

However, if you want to determine your function's position in the pipeline for some other reason, the answer is simple. You need to use $MyInvocation and compare the PipelineLength and PipelinePosition properties:

 

## Useful for testing all sorts of things about the pipeline
function Test-Pipeline {
[CmdletBinding()]
Param(
   [Parameter(ValueFromPipeline=$true)]
   [PSObject]$InputObject,
   [Switch]$Passthru,
   [Switch]$PassCmdlet
)
BEGIN { 
   Write-Output $MyInvocation
   if($PassCmdlet) {
      Write-Output $PsCmdlet
   }
}
PROCESS { if($Passthru){ $_ } }
}

## Shows 
function Test-LastInPipeline {
Param(
   [Parameter(ValueFromPipeline=$true)]
   [PSObject]$InputObject,
   [Switch]$Passthru
)
BEGIN { 
   $IsLast = $MyInvocation.PipelineLength -eq $MyInvocation.PipelinePosition
   if(!$IsLast) { $MyInvocation }
}
PROCESS { if($Passthru){ $_ } }
}
Tag page
Page statistics
894 view(s), 3 edit(s), and 2294 character(s)

Comments

You must login to post a comment.

Attach file

Attachments