【问题标题】:Powershell 7 ForEach-Object Parallel breaks automatic variable when passed to invoke-commandPowershell 7 ForEach-Object Parallel 在传递给调用命令时会中断自动变量
【发布时间】:2020-06-17 03:08:28
【问题描述】:

请告知,任何关于我需要做什么才能成功传递变量的见解将不胜感激。

这可以成功运行,但一次只能在管道列表中的每个 FQDN 上运行。我有 100 多台服务器,所以这可能需要比人们想象的更长的时间。每台服务器大约 1-6 秒


    Write-Host "Confirm correct OS is installed" -ForegroundColor Yellow -BackgroundColor Black

    $FQDNs | ForEach-Object {
        Invoke-Command -ComputerName $_ -Credential $Credentials -ScriptBlock { 
            $OS = (Get-CimInstance -ClassName CIM_OperatingSystem).Caption
            Write-Host "$Using:_`: $OS" -ForegroundColor Green -BackgroundColor Black
            Write-Output "$Using:_`: $OS"
        }
    }
} 

如果我添加 -Parallel 参数,它会立即失败并出现以下错误。如果自动变量是我看到 foreach-object 管道它们的唯一方式,我还应该如何提供变量? (我希望那是错误的)

ForEach-Object: C:\Scripts\Checklist.ps1:53
Line |
  53 |      $FQDNs | ForEach-Object -Parallel {
     |               ~~~~~~~~~~~~~~~~~~~~~~~~~~
     | The value of the using variable '$using:_' cannot be retrieved because
     | it has not been set in the local session.

这是插入 Parallel 参数的脚本,以准确显示我正在执行该操作的位置


    Write-Host "Confirm correct OS is installed" -ForegroundColor Yellow -BackgroundColor Black

    $FQDNs | ForEach-Object -Parallel {
        Invoke-Command -ComputerName $_ -Credential $Credentials -ScriptBlock { 
            $OS = (Get-CimInstance -ClassName CIM_OperatingSystem).Caption
            Write-Host "$Using:_`: $OS" -ForegroundColor Green -BackgroundColor Black
            Write-Output "$Using:_`: $OS"
        }
    }
}

【问题讨论】:

    标签: powershell foreach parallel.foreach


    【解决方案1】:

    调用命令计算机名 comp1、comp2、comp3 已并行运行。

    # elevated prompt
    start-service winrm
    invoke-command localhost,localhost,localhost { sleep 10 } 
    (get-history)[-1] | fl
    
    Id                 : 3
    CommandLine        :     invoke-command localhost,localhost,localhost { sleep 10 }
    ExecutionStatus    : Completed
    StartExecutionTime : 6/19/2020 10:05:02 AM
    EndExecutionTime   : 6/19/2020 10:05:13 AM  # 11 seconds for all three
    

    【讨论】:

      【解决方案2】:

      问题显然是 PowerShell 并不总是能正确处理 嵌套上下文,在这种情况下,因为添加 -Parallel 参数会为每个并行运行的脚本块实例创建一个独立的运行空间, $Using: 现在评估该运行空间上下文,而不是之前执行它的远程会话上下文没有参数。

      如果您交替使用Invoke-Command-ThrottleLimit 并将一组计算机名称传递给-ComputerName 以利用并行性而不是ForEach-Object-Parallel,那么实际上您会遇到同样的问题。

      要解决此问题,请尝试使用[scriptblock]::Create() 构建您的脚本块,以便使用正确的上下文,如this answer 中所述。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2022-07-07
        • 1970-01-01
        • 2020-09-08
        • 1970-01-01
        • 1970-01-01
        • 2012-11-07
        相关资源
        最近更新 更多