1

In .NET if you have a subroutine whose implementation might change from one call to another, you can pass a delegate to the method that uses the subroutine. You can also do this in Powershell. You can also use scriptblocks which have been described as Powershell's equivalent of anonymous functions. Idiomatic powershell, however, makes use of powershell's pipeline parameter bindings. But neither delegates nor scriptblocks seem to make use of Powershell's pipeline parameter bindings.

Is there a (idiomatic) way to pass a powershell commandlet to another commandlet in a way that preserves support for pipeline parameter bindings?

Here is a code snippet of what I'd like to be able to do:

Function Get-Square{
    [CmdletBinding()] 
    Param([Parameter(ValueFromPipeline=$true)]$x)
    PROCESS{$x*$x}
}
Function Get-Cube{
    [CmdletBinding()] 
    Param([Parameter(ValueFromPipeline=$true)]$x)
    PROCESS{$x*$x*$x}
}
Function Get-Result{
    [CmdletBinding()]
    Param([Parameter(ValueFromPipeline=$true)]$x,$Cmdlet)
    PROCESS{$x | $Cmdlet}
}

10 | Get-Result -Cmdlet {Get-Square}
10 | Get-Result -Cmdlet {Get-Cube}
alx9r
  • 3,675
  • 4
  • 26
  • 55

1 Answers1

1

That'll work. You've just got some syntax issues with your function definitions and how you're passing the parameters:

Function Get-Square{
    [CmdletBinding()] 
    Param([Parameter(ValueFromPipeline=$true)]$x)
    $x*$x
}
Function Get-Cube{
    [CmdletBinding()] 
    Param([Parameter(ValueFromPipeline=$true)]$x)
    $x*$x*$x
}
Function Get-Result{
    [CmdletBinding()]
    Param([Parameter(ValueFromPipeline=$true)]$x,$Cmdlet)
    $x | . $cmdlet
}

10 | Get-Result -Cmdlet Get-Square
10 | Get-Result -Cmdlet Get-Cube

100
1000
mjolinor
  • 66,130
  • 7
  • 114
  • 135
  • Interesting. So `$Cmdlet` is a `[string]`. And `.` is used to ["dot source"](https://technet.microsoft.com/en-us/library/hh847841.aspx) the `[string]` and execute it as a script in the context of `Get-Result`. Is that right? – alx9r Feb 12 '15 at 19:05
  • Almost right. It's a function call, rather than a scriptblock invocation. It's a [string], because function names are [string]. – mjolinor Feb 12 '15 at 19:22
  • Hmm...I'm trying to wrap my mind around the implications of "It's a function call". I also determined that I actually also need to pass named and positional parameters with the cmdlet being passed. It's related but doesn't really fit into this question so [I asked it here.](https://stackoverflow.com/q/28486411/1404637). – alx9r Feb 12 '15 at 19:47
  • About the only implication is what kind of parameter you pass. Because it's a named function, you can just pass the name. If it was an "unnamed" or anonymous function, you'd need to pass the script block. – mjolinor Feb 12 '15 at 19:57
  • This all makes sense now. Thanks for your help. :) – alx9r Feb 12 '15 at 21:12