Pipe or no pipe?

Home  >>  Cool  >>  Pipe or no pipe?

Pipe or no pipe?

On January 17, 2007, Posted by , In Cool,PowerShell,Quiz, With 2 Comments

Many built-in cmdlets take input from the pipe, but alternatively let you specify an input with the -InputObject parameter. An example is the Get-Member cmdlet.

I want to be able to do this with my own functions, but as far as I can tell, there is no built-in mechanism for this for using an specified parameter instead of the pipe.

[Updated]

What I do is this:

# A simple function that multiplies input items by 3
function times3 {
  param($i)
  # this inner function does the actual processing
  function proc($o) {
      $o * 3
  }
  # if -i supplied used instead of std $input
  if ($i) { $input = $i }
  foreach ($o in $input) {
    proc $o
  }
}

Normally, you’d use a function with a process block to process each object ($_) in the pipeline, but in this case, I iterate over the pipeline’s $input manually. If the -i is supplied, $input is replaced with its value.

If I run this sequence:

$debugpreference="Continue"
write-debug "----------- about to call as function"
times3

write-debug "----------- about to pipe 4 numbers in to function"
1..4 | times3

write-debug "----------- about to call as function with -i"
times3 -i (1..4)

I get this:

PS Documents\\proj\\ps1> ./pipeornot.ps1                                                                             
DEBUG: ----------- about to call as function                                                                                                                                                                
DEBUG: ----------- about to pipe 4 numbers in to function                                                               
3                                                                                                                       
6                                                                                                                       
9                                                                                                                       
12                                                                                                                      
DEBUG: ----------- about to call as function with -in                                                                   
3                                                                                                                       
6                                                                                                                       
9                                                                                                                       
12                                                                                                                      
PS Documents\\proj\\ps1> get-bufferhtml > out.html                                                                   

It would be nice if the the manual condition could be avoided by specifying

param($i=$input)

but sadly, this does not work.

Maybe in the next version of PowerShell, or perhaps there will be a more specific way of dealing with pipe or no pipe.

2 Comments so far:

  1. This is because you want to do it from your scripts and/or functions…

    Many “cmdlets” accept this, as you said, and in fact, you can write a cmdlet rather than a function that behaves this way, just like the other cmdlets. Start from here:

    http://msdn2.microsoft.com/en-us/library/ms714663.aspx

    PS – Keep up the great work – PSInvaders is AWESOME, you know ??

  2. adrian says:

    Thanks. I’m currently writing a whole load of cmdlets so know about things like [Parameter(Position=0,ValueFromPipe=true)] and so on.

    It’s a shame that that sort of thing couldn’t be exposed in PowerShell language itself.