我正在尝试复制一个典型的powershell -Computername参数,该参数可以从管道中获得,并使用CmdletBinding
和ValueFromPipeline
作为普通参数。我的挑战是,我在指定参数与管道中的值时会得到不同的结果。
我的代码如下所示:
[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
答案 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-item
和out-item 1,2,3
都会产生相同的输出("管道输入除外?"部分除外)。