为什么我的参数只处理一个值

时间:2016-11-14 21:23:14

标签: powershell

我玩了参数,遇到了问题。

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 个答案:

答案 0 :(得分:3)

这是因为你没有将功能体分成块:beginprocessend

  • 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 {}块来处理每个项目。

默认情况下,如果没有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
    }
}

这确保您始终在最内层循环中处理单个脚本,无论脚本是通过管道还是参数指定的。