2016-11-14 107 views
1

我在參數中玩過,而且遇到了問題。爲什麼我的參數只能處理一個值

function sign-script { 
param(
    [Parameter(
     ValueFromPipeline = $true, 
     ValueFromPipelineByPropertyName = $true, 
     Position = 0, 
     Mandatory = $true   
    )] 
    [ValidateNotNullOrEmpty()] 
    [Alias('FullName')] 
    [string[]]$scripts, 
    [string]$certname = "codesigning", 
    [string]$certstore = "Cert:\LocalMachine\My" 
) 

Write-Host $scripts.count 

} 

如果我運行這個功能是這樣的:

"Z:\test\test-sign.ps1","Z:\test\test-sign - Kopie (7).ps1" | sign-script 

$scripts.count返回1,而不是2,爲什麼呢?函數是不是處理所有的值,還是隻接受一個值?

回答

2

因爲您需要一個Process {}塊來對每個項目執行操作。

默認情況下,沒有BeginEndProcess塊,你只有一個End,所以你只有在通過了最後一項工作。

function sign-script { 
param(
    [Parameter(
     ValueFromPipeline = $true, 
     ValueFromPipelineByPropertyName = $true, 
     Position = 0, 
     Mandatory = $true   
    )] 
    [ValidateNotNullOrEmpty()] 
    [Alias('FullName')] 
    [string[]]$scripts, 
    [string]$certname = "codesigning", 
    [string]$certstore = "Cert:\LocalMachine\My" 
) 

Process { 
    Write-Host $scripts.count 
} 

} 

如果你做這種方式,你會看到1返回兩次。這是預料之中的,因爲每個項目調用一次過程塊。

而如果你這樣稱呼它:

sign-script "Z:\test\test-sign.ps1","Z:\test\test-sign - Kopie (7).ps1" 

然後,它會返回2

我通常要處理這個問題的方法是在過程塊使用foreach

Process { 
    foreach ($script in $scripts) { 
     Write-Host $script 
    } 
} 

這將確保你總是有一個簡單的腳本處理最內層循環是否通過管道或參數指定的腳本。

3

這是因爲您沒有將功能主體分成塊:begin,processend。第一個項目是從管道

  • process塊在流水線執行
  • end塊最後一個項目是從管道收到後對每個項目執行到達之前執行

    • begin塊。

    如果沒有定義塊,則函數體隱式設置爲end bblock。結果,你只會看到最後一個項目在流水線中。爲了解決這個問題,我會建議重寫劇本如下:

    function sign-script { 
    param(
        [Parameter(
         ValueFromPipeline = $true, 
         ValueFromPipelineByPropertyName = $true, 
         Position = 0, 
         Mandatory = $true   
        )] 
        [ValidateNotNullOrEmpty()] 
        [Alias('FullName')] 
        [string[]]$scripts, 
        [string]$certname = "codesigning", 
        [string]$certstore = "Cert:\LocalMachine\My" 
    ) 
        process { 
         Write-Host $scripts.count 
        } 
    } 
    

    你只要把一個應該在管道的每個項目處理成process的代碼塊。當您運行腳本時,您將看到1兩次,因爲process塊將爲每個項目重新啓動。

  • 相關問題