You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.25 15:24:05