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

如何通过System.Management.Automation传递PowerShell远程命令的警告与详细流

解决C#远程调用PowerShell时无法接收Verbose/Warning等流的问题

我之前也踩过这个坑,核心问题在于远程PowerShell会话默认不会自动把所有非输出类流(Verbose/Warning/Information等)转发回本地客户端——哪怕你在脚本块里设置了$VerbosePreference这类变量,也得显式配置流转发规则,同时调整输出缓冲模式才能让事件实时触发。

下面是具体的修复方案和修改后的代码:

关键修复点

  • 给Invoke-Command添加RemoteStreamOptions.ForwardAll参数,强制远程会话把所有类型的流都转发到本地
  • 设置命令的OutputBufferingMode为None,避免流被缓冲,确保DataAdded事件能实时触发
  • 通过SessionStateProxy提前配置远程会话的偏好变量,确保流输出规则在脚本执行前就生效

修改后的完整代码

namespace ConsoleApp2
{
    using System;
    using System.Linq;
    using System.Management.Automation;
    using System.Management.Automation.Runspaces;
    using System.Security;
    using System.Action;

    class Program
    {
        static void Main(string[] args)
        {
            var script = @"
                Write-Host "" ------- $env:computername ------- ""
                Write-Warning ""Write warning directly in warn script""
                Write-Error ""Write error directly in warn script""
                Write-Verbose ""Write verbose directly in warn script""
                Write-Host ""Write host directly in warn script""
                Write-Information ""Write Information in warn script""
            ";

            // 远程虚拟机调用
            Call(script, command => {
                SecureString password = new SecureString();
                "admin".ToCharArray().ToList().ForEach(c => password.AppendChar(c));
                command.Parameters.Add("Credential", new PSCredential("admin", password));
                command.Parameters.Add("VmName", new[] { "190104075839" });
            });

            // 本地调用对比
            Call(script);
        }

        private static void Call(string script, Action<Command> addtionalCommandSetup = null)
        {
            using (var shell = PowerShell.Create())
            {
                // 订阅所有流的日志事件
                shell.Streams.Information.DataAdded += LogProgress<InformationRecord>;
                shell.Streams.Warning.DataAdded += LogProgress<WarningRecord>;
                shell.Streams.Error.DataAdded += LogProgress<ErrorRecord>;
                shell.Streams.Verbose.DataAdded += LogProgress<VerboseRecord>;
                shell.Streams.Debug.DataAdded += LogProgress<DebugRecord>;

                var command = new Command("Invoke-Command");
                command.Parameters.Add("ScriptBlock", ScriptBlock.Create(script));

                // 核心修复1:开启所有远程流的转发
                command.Parameters.Add("RemoteStreamOptions", RemoteStreamOptions.ForwardAll);

                // 核心修复2:关闭输出缓冲,实时传递流数据
                command.OutputBufferingMode = OutputBufferingMode.None;

                // 提前配置远程会话的流偏好规则
                shell.Runspace.SessionStateProxy.SetVariable("VerbosePreference", ActionPreference.Continue);
                shell.Runspace.SessionStateProxy.SetVariable("WarningPreference", ActionPreference.Continue);
                shell.Runspace.SessionStateProxy.SetVariable("InformationPreference", ActionPreference.Continue);

                addtionalCommandSetup?.Invoke(command);

                shell.Commands.AddCommand(command);
                shell.Invoke();

                Console.WriteLine("=== 命令执行完成 ===");
                Console.ReadKey();
            }
        }

        private static void LogProgress<T>(object sender, DataAddedEventArgs e)
        {
            var data = (sender as PSDataCollection<T>)[e.Index];
            Console.WriteLine($"[{typeof(T).Name}] {Convert.ToString(data)}");
        }
    }
}

额外说明

  1. RemoteStreamOptions.ForwardAll:这是解决远程流不传递的核心设置,它会告诉远程PowerShell把Verbose、Warning、Debug、Information等所有类型的流都转发回本地客户端。
  2. OutputBufferingMode.None:默认情况下PowerShell会缓冲输出,直到命令执行完毕才一次性返回结果。设置为None后,流数据会实时发送,你的日志事件就能及时触发。
  3. SessionStateProxy配置偏好变量:虽然可以在脚本块里设置$VerbosePreference,但通过SessionStateProxy提前配置远程会话的变量,能确保规则在脚本执行前就生效,避免脚本内设置可能出现的延迟或不生效问题。

这样修改后,无论是通过-VmName连接虚拟机,还是-ComputerName连接网络计算机,所有的Verbose、Warning等流都能正常回传到本地日志了。

内容的提问来源于stack exchange,提问作者Michal Wozniak

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.11 08:40:49