2015-11-04 32 views
2

大约有路过的功能通Cmdlet的作为参数传递给函数

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}作为单独的参数。

如果没有很好的支持,这种语言的解决类似问题的风格是什么?

+2

能不能细说你为什么做这种方式?元编程很有趣,但我很好奇。为什么你不能制作一个专用的函数来接受你想要的参数......处理并继续处理管道。 – Matt

+0

为简单起见,我们选择了这个例子。但是假设我有一个“日志记录”工具,用于测试CmdLet对管道输入的影响。因此,我们可能有 “input | remember | chosenCmdLet | difference” 其中“remember”可能以某种方式标记值,并且当流中的元素被删除或更改时,“差异”会发出信号。如果我可以调用Test chosenCmdLet而不是在这两个Cmdlet之间调用它,那将会很好。 – Polymer

+1

@Polymer函数测试{param([ScriptBlock] $ Command)输入|记住| Invoke-Command $ Command | difference}''Test {Where {$ _ -gt 1}}' – PetSerAl

回答

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}} 
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的,那是行不通的。

+0

我认为这是正确的,因为它完全解决了一般问题。虽然,因为我是新手,但我不确定如何从奇怪的命名空间指定CmdLet。 你不想让进程结束吗? 而且,您将如何亲自解决这些问题?因为这感觉有点被迫。 – Polymer

+1

你应该在脚本块中转义'$ input':''''$ input | $ cmd $ arguments“''。试试这个:''dir'| Pass_Through foreach'{$ _}''。它不会打印'dir',而是'dir'命令的结果。 – PetSerAl

+0

@PetSerAl优秀的建议!我在我的回答中做出了改变。 – TheMadTechnician

相关问题