当变量值为$ null时运行ForEach-Object循环

时间:2018-02-21 11:47:25

标签: powershell foreach null

在PowerShell(5.1.14393.1944)中,当我有一个值为$null的varibale时,ForEach-Object循环会尝试迭代该对象,从而导致意外结果。

在这个例子中,我试图从一组数据中重新获得最高的最大结果。但是,如果没有数据,则应返回-1

function Get-MaximumResult
{
    param(
        [parameter(Mandatory,Position=0)]
        [AllowNull()]
        [object]$MetricsData
    )
    if (-not($MetricsData)) { Write-Host "Debug: Variable is null" }
    [int]$maximum = -1
    $MetricsData | ForEach-Object {
       if ([int]$_.maximum -gt $maximum) { $maximum = [int]$_.maximum }
       Write-Host "Debug: Maximum: $maximum"
    }
    return $maximum
}
Get-MaximumResult -MetricsData $null

生成的输出如下 -

  

调试:变量为空
  调试:最大值:0
  0

我期望看到的是这个 -

  

调试:变量为空
  -1

我在几年前发现了几个类似的问题,但是答案表明这个错误在版本3中得到修复。还有其他人遇到过这个错误吗?

1 个答案:

答案 0 :(得分:2)

根据评论,问题出现是因为您正在使用ForEach-Object cmdlet,它通过管道处理项目。

如果您使用foreach语句,那么它将不会对$null有价值的集合执行递归(显然从PS版本3开始)。您可以通过此示例看到该行为:

$null | ForEach-Object { write-host 'In feo' }

foreach ($thing in $null) {
    write-host 'in fe'
}

我认为这是因为foreach语句在执行任何操作之前对其工作进行了一些前期评估,如果它发现该集合为空,则它不会执行其操作。

另一方面,

ForEach-Object只是从管道中获取输入,一次处理一个输入并向管道发送任何输出,无论输入是否有值。我可以看到这可能有意义的场景,因为您可能不一定希望管道因$null值而停止。