簡體   English   中英

在Powershell函數中處理管道和參數輸入

[英]Handling pipeline and parameter input in a Powershell function

我對在一個月的午餐中學習PowerShell一書中看到的東西感到困惑。 在第21章中,當作者討論通過參數綁定或管道接受輸入的函數時,他給出了兩種模式。

第一個如下

function someworkerfunction {
# do some work
}
function Get-SomeWork {
   param ([string[]]$computername)
   BEGIN {
      $usedParameter = $False
      if($PSBoundParameters.ContainsKey('computername')) {
         $usedParameter = $True
      }   
   }
   PROCESS {
      if($usedParameter) {
         foreach($computer in $computername) {
            someworkerfunction -computername $comptuer
         }
      } else {
         someworkerfunction -comptuername $_
      }
   }

   END {}
}

第二個是這樣的

function someworkerfunction {
# do stuff
}
function Get-Work {
   [CmdletBinding()]
   param(
      [Parameter(Mandatory=$True,
      ValueFromPipelineByPropertyName=$True)]
      [Alias('host')]
      [string[]]$computername
   )
   BEGIN {}
   PROCESS {
      foreach($computer in $computername) {
         someworkerfunction -comptuername $computer
      }
   }
   END {}
}

我知道第二個樣本是標准的Powershell 2.0 Advanced功能。 我的問題是Powershell 2.0對cmdletbinding指令的支持你是否想要使用第一個模式。 這只是Powershell 1.0的遺產嗎? 基本上有一段時間使用Powershell 2.0我想要第一個模式,第二個模式更清潔。

任何見解將不勝感激。

謝謝。

如果要在函數中處理管道輸入但不想添加所有參數屬性或想要向后兼容,請使用cmdletbinding less方法。

如果要使用PowerShell腳本cmdlet的其他功能(如參數屬性,參數集等),請使用第二個功能。

如果有人希望對如何從管道輸入讀取的非常非常簡單的解釋看到

你如何編寫一個從管道輸入中讀取的powershell函數?

如果我有這個問題時存在這個^ ,我會節省很多時間,因為這個線程非常復雜,並沒有真正解釋如何處理流水線輸入到函數中。

不,第一個例子不僅僅是遺產。 為了創建一個使用數組參數並接受管道輸入的PowerShell函數,您必須做一些工作。

我甚至會說第二個例子不起作用。 至少我無法讓它發揮作用。

以這個例子為例......

function PipelineMadness()
{
   [cmdletbinding()]
    param (
        [Parameter(Mandatory = $true, ValueFromPipeline=$true)]
        [int[]] $InputArray
    )

    Write-Host ('$InputArray.Count {0}' -f $InputArray.Count)
    Write-Host $InputArray

    Write-Host ('$input.Count {0}' -f $input.Count)
    Write-Host $input

    if($input) { Write-Host "input is true" }
    else { Write-Host "input is false" }
}

結果......

PS C:\Windows\system32> 1..5 | PipelineMadness
$InputArray.Count 1
5
$input.Count 5
1 2 3 4 5
input is true

PS C:\Windows\system32> PipelineMadness (1..5)
$InputArray.Count 5
1 2 3 4 5
$input.Count 1

input is false

請注意,當使用管道時, $InputArray變量的單個值為5 ...

現在使用BEGIN和PROCESS塊

function PipelineMadnessProcess()
{
    [cmdletbinding()]
    param (
        [Parameter(Mandatory = $true, ValueFromPipeline=$true)]
        [int[]] $InputArray
    )

    BEGIN
    {
        Write-Host 'BEGIN'
        Write-Host ('$InputArray.Count {0}' -f $InputArray.Count)
        Write-Host $InputArray

        Write-Host ('$input.Count {0}' -f $input.Count)
        Write-Host $input

        if($input) { Write-Host "input is true" }
        else { Write-Host "input is false" }
    }

    PROCESS
    {
        Write-Host 'PROCESS'
        Write-Host ('$InputArray.Count {0}' -f $InputArray.Count)
        Write-Host $InputArray

        Write-Host ('$input.Count {0}' -f $input.Count)
        Write-Host $input

        if($input) { Write-Host "input is true" }
        else { Write-Host "input is false" }
    }
}

現在這是奇怪的地方

PS C:\Windows\system32> 1..5 | PipelineMadnessProcess
BEGIN
$InputArray.Count 0

$input.Count 0

input is false
PROCESS
$InputArray.Count 1
1
$input.Count 1
1
input is true
PROCESS
$InputArray.Count 1
2
$input.Count 1
2
input is true

...

PROCESS
$InputArray.Count 1
5
$input.Count 1
5
input is true

BEGIN塊根本沒有任何數據。 並且進程塊運行良好,但是如果你有一個類似於示例的foreach它實際上可以工作,但它將運行foreach ,1次輸入X次。 或者,如果您傳入數組,它將使用完整集運行foreach一次。

所以我從技術上說這個例子可行,但它可能不會像你期望的那樣工作。

另請注意,即使BEGIN塊沒有數據,該函數也會通​​過語法驗證。

要回答你的問題,我會說第一個模式只是來自PowerShell 1.0的遺產,你也可以在沒有Process腳本塊的經典函數中使用$input 至於你只是為PowerShell 2.0編寫代碼,你可以忘記它。

關於管道功能,在powerShell V1.0中,可以使用filters處理它們。

你必須知道,當你從網上采集樣本或者你必須調試舊的Powerhell代碼時,它已經完成了。

我個人仍然在我的模塊中使用舊functionsfilters我保留cmdletbinding用於導出函數或配置文件函數。

Powershell有點像樂高積木,你可以用很多不同的方式做很多事情。

第一種形式是將一個或多個計算機名稱作為參數列表或管道的字符串參數。

第二種形式是期望來自參數列表的字符串參數數組,或者來自管道的具有計算機名稱作為屬性的輸入對象。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM