PowerShell嵌套Invoke-Command使用$using传递变量为空问题咨询
问题根因
$using: 作用域修饰符仅支持穿透一层远程会话边界,只会从当前脚本块的直接调用方会话中查找变量,不支持跨多层远程会话递归查找变量。
当前代码中$WaitSeconds定义在最外层本地会话,第一层Invoke-Command连接到$remote节点后,该节点的远程会话中不存在$WaitSeconds变量;第二层嵌套的Invoke-Command执行时,$using:waitseconds会尝试从第一层远程会话中读取变量,读取不到就会返回空值。
修复方案
二选一即可:
方案1:逐层透传
$using变量
在第一层远程脚本块中,先通过$using:把本地的目标变量读取为当前会话的本地变量,第二层脚本块再通过$using:读取第一层会话中存储的变量即可。
修正后代码:$WaitSeconds = 1234 Invoke-Command -ComputerName $remote -Credential $cred -ScriptBlock { # 先将本地变量拉取到第一层远程会话存储 $waitSec = $using:WaitSeconds $computer = dsquery computer "DC=domain,DC=local" -o rdn $computers = $computer -replace ('"', '') Write-Host $computers foreach ($computer in $computers) { if ($computer -notmatch "AZUREADSSOACC") { Invoke-Command -ComputerName $computer -Credential $using:cred -ScriptBlock { # 从第一层远程会话读取变量值 shutdown -s -t $using:waitSec } } } }方案2:通过
-ArgumentList参数显式传参
每层远程调用时,把需要传递的变量放入-ArgumentList参数列表,在对应脚本块中通过param声明接收参数,该方式不受$using的作用域穿透层数限制,嵌套层级较多时稳定性更高。
修正后代码:$WaitSeconds = 1234 Invoke-Command -ComputerName $remote -Credential $cred -ArgumentList $WaitSeconds, $cred -ScriptBlock { param($waitSec, $remoteCred) $computer = dsquery computer "DC=domain,DC=local" -o rdn $computers = $computer -replace ('"', '') Write-Host $computers foreach ($computer in $computers) { if ($computer -notmatch "AZUREADSSOACC") { Invoke-Command -ComputerName $computer -Credential $remoteCred -ArgumentList $waitSec -ScriptBlock { param($shutdownWaitSec) shutdown -s -t $shutdownWaitSec } } } }
注意:PowerShell 所有版本中,$using:作用域均不支持跨两层及以上远程会话自动传值,嵌套远程调用场景必须逐层传递变量。
内容的提问来源于stack exchange,提问作者Anton Struhli
相关产品推荐
相关产品推荐

