Powershell Invoke-Command 传递环境变量

Powershell Invoke-Command passing environment variables

我希望使用 Invoke-Command 将环境变量从调用机器传递到执行 Invoke-Command 的服务器。

我希望它能工作:

Invoke-Command -ComputerName MyServer-ScriptBlock {
    $env:VAR=$using:env:USERNAME
    Write-Host $env:VAR
}

但是这个命令的输出是空的。如果我不使用 $using 范围修饰符,而只是直接分配变量,我会得到预期的输出 ("VAR").

Invoke-Command -ComputerName MyServer -ScriptBlock {
   $env:VAR="VAR"
   Write-Host $env:VAR
}

那么,我可以将 $using 与环境变量一起使用吗?如果没有,是否有一种简单的方法可以将环境变量传递到 Invoke-Command 为 运行 的远程计算机?

一种选择是在调用之前将环境变量分配给标准变量:

$username = $env:USERNAME

Invoke-Command -ComputerName MyServer-ScriptBlock {
    $env:VAR=$using:userName
    Write-Host $env:VAR
}

请注意,在您的会话结束后,像这样 ($env:VAR=<value>) 分配环境变量将不会持续。使用 Environment.SetEnvironmentVariable() 方法来做到这一点。

我想你可以使用 -ArgumentList。参见 https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.core/invoke-command?view=powershell-6

Invoke-Command -ComputerName MyServer -ArgumentList $env:USERNAME -ScriptBlock {
    Param ($x)

    Write-Host $x
}

现有答案显示有用的解决方法

看起来你遇到了一个 bug,至少出现在 PowerShell 7.1:

$using: 作用域 - 在所有 外访问调用者作用域的变量值都是必需的运行空间 执行(参见) - should also support namespace variable notation (see )。

因此,您应该能够传递名称空间符号变量引用,例如 $env:USERNAME 作为 $using:env:USERNAME:

  • 确实,您 可以jobs 的上下文中(基于子进程的后台作业以 Start-Job and thread-based jobs started with Start-ThreadJob);例如:

    $env:FOO = 'bar'
    # Outputs 'bar', as expected.
    Start-Job { $using:env:FOO } | Receive-Job -Wait -AutoRemoveJob
    
  • 但是,从 PowerShell 7.1 开始,它不适用于 PowerShell remoting, such as Invoke-Command -ComputerName,就像您的情况一样。

潜在错误已在 GitHub issue #16019 中报告。