在this technique to use Cmdlets as "delegates"的基础上,我留下了这个问题:
有没有办法将带有规定的命名或位置参数的命令行开关传递给另一个使用powershell管道将其余参数绑定到传递的命令行开关的命令行开关?
以下是我希望能够运行的代码段:
Function Get-Pow{
[CmdletBinding()]
Param([Parameter(ValueFromPipeline=$true)]$base,$exp)
PROCESS{[math]::Pow($base,$exp)}
}
Function Get-Result{
[CmdletBinding()]
Param([Parameter(ValueFromPipeline=$true)]$x,$Cmdlet)
$x | . $Cmdlet
}
10 | Get-Result -Cmdlet 'Get-Pow -exp 2'
10 | Get-Result -Cmdlet 'Get-Pow -exp 3'
10 | Get-Result -Cmdlet Get-Pow -exp 2
10 | Get-Result -Cmdlet Get-Pow -exp 3
前两次调用Get-Result
会导致CommandNotFoundException
,因为Get-Pow -exp 2
"不是cmdlet的名称。"
对Get-Result
的最后两次调用会导致NamedParameterNotFound,Get-Result
,因为该语法实际上是在尝试将参数-exp
传递给它没有的Get-Result
。
是否有其他方法可以设置它以便它有效?
答案 0 :(得分:1)
我不确定这是最好的方法,但至少它类似于PowerShell惯用语:
Function Get-Amount{
[CmdletBinding()]
Param(
[Parameter(ValueFromPipeline=$true)]$t,
[Parameter(position=1)]$r,
[Parameter(position=2)]$P)
PROCESS{$P*[math]::Pow(1+$r,$t)}
}
Function Get-Result{
[CmdletBinding()]
Param(
[Parameter(ValueFromPipeline=$true)]$x,
[Parameter(Position=1)]$Cmdlet, #positional arguments here makes calling more readable
[Alias('args')] #careful, $args is a special variable
[Parameter(Position=2)]$Arguments=@()) #the default empty array is required for delegate style 1
PROCESS{
#invoke style 1 #works with delegate styles 1,2,3
iex "$x | $Cmdlet @Arguments"
#invoke style 2 #works with delegate styles 2,3
$x | . $Cmdlet @Arguments
}}
5,20 | Get-Result 'Get-Amount -r 0.05 -P 100' #delegate style 1
5,20 | Get-Result Get-Amount 0.05,100 #delegate style 2
5,20 | Get-Result Get-Amount @{r=0.05;P=100} #delegate style 3
结果是:
127.62815625
CommandNotFoundException
265.329770514442
CommandNotFoundException
127.62815625
127.62815625
265.329770514442
265.329770514442
127.62815625
127.62815625
265.329770514442
265.329770514442