我玩了参数,遇到了问题。
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,为什么?函数是不处理所有值,还是只接受一个值?
答案 0 :(得分:3)
这是因为你没有将功能体分成块:begin
,process
和end
。
begin
块在第一个项目从管道process
块end
块。如果未定义任何块,则将函数体隐式设置为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
块。
答案 1 :(得分:2)
因为您需要Process {}
块来处理每个项目。
默认情况下,如果没有Begin
,End
或Process
阻止,则只有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
}
}
这确保您始终在最内层循环中处理单个脚本,无论脚本是通过管道还是参数指定的。