PowerShell两层嵌套Invoke-Command如何将$computers和$tasks返回到本地
PowerShell嵌套Invoke-Command返回值获取方案
核心问题原因
Write-Host仅会输出内容到当前会话的控制台,不会作为返回值传递给上层调用方- 第二层
Invoke-Command的执行结果没有被上层变量接收,也未随第一层调用返回本地 - 嵌套远程会话存在Kerberos双跳权限问题,且额外增加了结果传递的复杂度
推荐方案:扁平化远程调用(无嵌套,易维护)
直接在本地执行两层逻辑,避免嵌套会话带来的各类问题:
# 1. 本地先连域控获取所有域内计算机列表 $domainSession = New-PSSession -ComputerName $remote -Credential $cred $computers = Invoke-Command -Session $domainSession -ScriptBlock { return dsquery computer "DC=kanzlei,DC=local" -o rdn } Remove-PSSession $domainSession # 打印域内计算机列表 Write-Host "In dieser Domäne gibt es die folgenden Server:" Write-Host $computers # 2. 本地逐个对目标计算机执行计划任务启用操作,收集结果 $tasks = @() foreach($computer in $computers) { $computerSession = New-PSSession -ComputerName $computer -Credential $cred $computerTasks = Invoke-Command -Session $computerSession -ScriptBlock { Write-Host "Tasks for $env:computername gonna be activated" # 注意:如果后续需要处理$tasks的属性,不要提前加Format-List,本地展示时再格式化即可 return Get-ScheduledTask -TaskPath "\RA-MICRO_Update_Routine\" | Enable-ScheduledTask | Select-Object Taskname,State } $tasks += $computerTasks Remove-PSSession $computerSession } # 本地可直接使用两个变量做后续处理 $computers | Out-File .\computers.txt $tasks | Format-List | Out-File .\tasks.txt
兼容方案:保留嵌套结构时的结果返回方法
如果必须保留原有的嵌套远程调用结构,需要将两层的结果封装为结构化对象统一返回:
$session = New-PSSession -ComputerName $remote -Credential $cred # 接收第一层返回的结构化对象 $remoteResult = Invoke-Command -Session $session -ScriptBlock { # 提前声明结果对象 $result = [PSCustomObject]@{ Computers = @() Tasks = @() } # 收集计算机列表 $result.Computers = dsquery computer "DC=kanzlei,DC=local" -o rdn Write-Host ("In dieser Domäne gibt es die folgenden Server:") write-host $result.Computers foreach($computer in $result.Computers) { $session3 = New-PSSession -ComputerName $computer -Credential $using:cred $currentTasks = Invoke-Command -Session $session3 -ScriptBlock { write-host "Tasks for $env:computername gonna be activated" return Get-ScheduledTask -TaskPath "\RA-MICRO_Update_Routine\" | Enable-ScheduledTask | Select-Object Taskname,State } $result.Tasks += $currentTasks Remove-PSSession $session3 } # 统一返回结构化结果 return $result } Remove-PSSession $session # 本地拆解结果即可拿到两个变量 $computers = $remoteResult.Computers $tasks = $remoteResult.Tasks # 后续自定义处理逻辑
注意事项
- 不要提前用
Format-List(FL)处理返回结果,格式化后的对象无法用于后续的属性读取、筛选等操作,本地需要展示时再调用格式化方法即可 - 所有远程会话使用完成后需调用
Remove-PSSession释放资源,避免会话泄漏 - 嵌套远程调用需额外处理权限双跳问题,推荐优先使用扁平化调用方案
内容的提问来源于stack exchange,提问作者Anton Struhli
相关产品推荐
相关产品推荐

