来自管道的Powershell Array参数

时间:2014-07-09 18:16:01

标签: powershell

我正在尝试复制一个典型的powershell -Computername参数,该参数可以从管道中获得,并使用CmdletBindingValueFromPipeline作为普通参数。我的挑战是,我在指定参数与管道中的值时会得到不同的结果。

我的代码如下所示:

[CmdletBinding()]
param(
    [parameter(Mandatory=$true, ValueFromPipeline=$true)] [string[]]$ComputerName
 )

BEGIN {  "Begin script`n-----" }

PROCESS { 
    "  `$ComputerName '$ComputerName'"
    "  `$_ '$_'"
    "  +++ Count: " + $ComputerName.Count
    foreach($computer in $ComputerName) {
        "    `$computer '$computer'"
    }
    "  -----"
}

END { "Complete" }

当我使用管道运行时,我得到了这个:

PS> (1, 2, 3) | .\BPEParamTest.ps1
Begin script
-----
  $ComputerName '1'
  $_ '1'
  +++ Count: 1
    $computer '1'
  -----
  $ComputerName '2'
  $_ '2'
  +++ Count: 1
    $computer '2'
  -----
  $ComputerName '3'
  $_ '3'
  +++ Count: 1
    $computer '3'
  -----
Complete

然而,当使用参数运行时,我会得到不同的结果:

PS> .\BPEParamTest.ps1 -ComputerName (1, 2, 3)
Begin script
-----
  $ComputerName '1 2 3'
  $_ ''
  +++ Count: 3
    $computer '1'
    $computer '2'
    $computer '3'
  -----
Complete

2 个答案:

答案 0 :(得分:2)

我总是使用以下结构。这适用于参数和管道中的数组:

[CmdletBinding()]
param(
    [parameter(Mandatory=$true, ValueFromPipeline=$true)] [string[]]$ComputerName
 )

process {
  foreach($computer in $computername){
      #do the stuff
  }

完整说明:为流水线中的每个项目运行一次流程块,以便它如何处理流水线上的列表(即$ computername依次设置为每个项目)。如果将值作为参数传递,则$ computername将设置为列表,这就是循环的原因。

答案 1 :(得分:0)

.\BPEParamTest.ps1 -ComputerName (1, 2, 3)不使用管道而是使用单个输入(3个元素的数组)。相反,(1, 2, 3) | .\BPEParamTest.ps1使用管道(3个独立的输入)。

要解决此问题,您可以检查绑定参数并确定是否存在管道输入。这是一个简短的例子:

function out-item {
  [CmdletBinding()]
  param(
    [Parameter(ValueFromPipeline=$TRUE)]
      $item
  )
  begin {
    $PipelineInput = -not $PSBoundParameters.ContainsKey("item")
    write-host "Pipeline input? $PipelineInput"
    $n = 0
  }
  process {
    if ($PipelineInput) {
      $_
      $n++
    }
    else {
      $item | foreach-object {
        $_
        $n++
      }
    }
  }
  end {
    write-host "Output $n item(s)"
  }
}

使用此功能,1,2,3 | out-itemout-item 1,2,3都会产生相同的输出("管道输入除外?"部分除外)。