2015-11-04 61 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

相關問題