关于传递函数有几个很好的答案
function pass_function([scriptblock] $func, [int] $a){
func.invoke($a)
}
你如何通过接受管道输入的Cmdlet?我的解决方案很差
function pass_through([scriptblock]$command){
$command.invoke()
}
1,2,3,4 | pass_through { $input | Where { $_ -gt 1} }
输出2,3,4。
从技术上讲,那里有足够的工具,但它们需要实施。我更愿意将Where和{$ _ -gt 1}作为单独的参数传递。
如果对此没有很好的支持,这种语言解决类似问题的方式是什么?
答案 0 :(得分:2)
所以问题是不同的cmdlet会有不同的方式来调用它们。例如,将1,2,3,4传递给Where
子句是好的,它喜欢几乎所有的数组,但你不能将它传递给Format-Table
因为它根本不需要一个字符串数组,它需要一个对象数组。
对于Where
目的,您可以执行以下操作:
Function Pass_Through {
Param(
[string]$Cmd,
[string]$Arguments
)
Process{[scriptblock]::Create("`$input|$cmd $arguments").Invoke()}
}
然后我们这样做:
1,2,3,4 | pass_through 'Where' '{ $_ -gt 1}'
按预期响应2,3,4。 但是当你想传递一个对象而不是一个字符串时会发生什么?
Get-ADUser $env:USERNAME | Pass_Through 'Format-Table' 'Name,DistinguishedName'
不会发生,因为它试图推断每个属性并将每个字符串传递给Format-Table
cmdlet,而这只是不起作用。
答案 1 :(得分:2)
看起来您正在寻找一种在管道中间更改命令而无需编写另一个管道副本的方法。您可以通过将ScriptBlock
调用为SteppablePipeline
来实现此目的。好的是,如果满足以下所有条件,Invoke-Command
cmdlet可以为您做到这一点:
Invoke-Command
期待管道输入。ScriptBlock
没有直接引用$input
。ScriptBlock
可转换为SteppablePipeline
。这是Pass_Through
函数:
function Pass_Through {
param(
[ScriptBlock]$MiddleCommand
)
$input|
Pre-Command|
Invoke-Command $MiddleCommand|
Post-Command
}
你可以像这样调用它:
1..10|Pass_Through {Where { $_ -gt 1}}