C# 使用System.Management.Automation调用powershell时,如何从远程命令传递警告和详细流?
我正在尝试使用C#中的PowerShell远程调用命令(在本地虚拟机上或使用网络)。我正在使用来自的System.Management.Automation库 由于我不知道的原因,不会重新记录警告和详细消息 在C#中本地调用commnd时,它工作正常 我尝试过各种与流相关的设置($verbosepreference,$warningpreference),但我认为它们并不相关——从控制台调用PowerShell时,不存在此问题 我检查了与虚拟机的远程连接(-Invoke命令的VmName参数)和网络中的计算机(-Invoke命令的ComputerName参数)-两者都存在该问题 我曾尝试在PowerShell Invoke()中找到一些可以传递这些流的神奇开关-我找到了一个名为RemoteStreamOptions()的东西,但设置它并没有帮助 我能做些什么使它工作吗C# 使用System.Management.Automation调用powershell时,如何从远程命令传递警告和详细流?,c#,powershell,virtual-machine,C#,Powershell,Virtual Machine,我正在尝试使用C#中的PowerShell远程调用命令(在本地虚拟机上或使用网络)。我正在使用来自的System.Management.Automation库 由于我不知道的原因,不会重新记录警告和详细消息 在C#中本地调用commnd时,它工作正常 我尝试过各种与流相关的设置($verbosepreference,$warningpreference),但我认为它们并不相关——从控制台调用PowerShell时,不存在此问题 我检查了与虚拟机的远程连接(-Invoke命令的VmName参数)
namespace ConsoleApp2
{
using System;
using System.Linq;
using System.Management.Automation;
using System.Management.Automation.Runspaces;
using System.Security;
class Program
{
static void Main(string[] args)
{
var script = @"
$VerbosePreference='Continue' #nope, it's not about these settings
$WarningPreference = 'Continue'
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"" -verbose
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));
addtionalCommandSetup?.Invoke(command);
shell.Commands.AddCommand(command);
shell.Invoke();
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)}");
}
}
}
namespace ConsoleApp2
{
使用制度;
使用System.Linq;
使用系统、管理、自动化;
使用System.Management.Automation.Runspaces;
使用系统安全;
班级计划
{
静态void Main(字符串[]参数)
{
变量脚本=@“
$VerbosePreference='Continue'#不,这与这些设置无关
$WarningPreference='Continue'
写入主机“”--$env:computername------------
写入警告“”直接在警告脚本中写入警告“”
写入错误“”直接在警告脚本中写入错误“”
写入详细信息“”直接在警告脚本“”中写入详细信息“”-详细信息
写入主机“”在警告脚本中直接写入主机“”
写入信息“”在警告脚本中写入信息“”
";
调用(脚本,命令=>
{
SecureString密码=新SecureString();
“admin.tocharray().ToList().ForEach(c=>password.AppendChar(c));
添加(“凭证”,新PSCredential(“管理员”,密码));
Add(“VmName”,new[]{“190104075839”});
}
);
呼叫(脚本);
}
私有静态无效调用(字符串脚本,Action addationalcommandsetup=null)
{
使用(var shell=PowerShell.Create())
{
shell.Streams.Information.DataAdded+=LogProgress;
shell.Streams.Warning.DataAdded+=LogProgress;
shell.Streams.Error.DataAdded+=LogProgress;
shell.Streams.Verbose.DataAdded+=LogProgress;
shell.Streams.Debug.DataAdded+=LogProgress;
var命令=新命令(“调用命令”);
command.Parameters.Add(“ScriptBlock”,ScriptBlock.Create(script));
AddationalCommandSetup?.Invoke(命令);
shell.Commands.AddCommand(command);
shell.Invoke();
Console.ReadKey();
}
}
私有静态void LogProgress(对象发送方、DataAddedEventArgs e)
{
var数据=(发送方作为PSDataCollection)[e.Index];
WriteLine($“[{typeof(T.Name}]{Convert.ToString(data)}”);
}
}
}
我认为问题可能是您正在使用var shell=PowerShell.Create()
创建本地PowerShell会话,然后使用Invoke命令创建一个单独的远程会话,并且流没有正确传递。如果您直接创建远程会话,它可以正常工作。以下是使用远程运行空间的代码的简化版本:
namespace ConsoleApp2
{
using System;
using System.Linq;
using System.Management.Automation;
using System.Management.Automation.Runspaces;
using System.Security;
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"" -verbose
Write-Host ""Write host directly in warn script""
Write-Information ""Write Information in warn script""
";
SecureString password = new SecureString();
"Password".ToCharArray().ToList().ForEach(c => password.AppendChar(c));
PSCredential credentials = new PSCredential("UserName", password);
WSManConnectionInfo connectionInfo = new WSManConnectionInfo();
connectionInfo.ComputerName = "TargetServer";
connectionInfo.Credential = credentials;
using (var shell = PowerShell.Create())
{
using (var runspace = RunspaceFactory.CreateRunspace(connectionInfo))
{
runspace.Open();
shell.Runspace = runspace;
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>;
shell.AddScript(script);
shell.Invoke();
}
}
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)}");
}
}
}
namespace ConsoleApp2
{
使用制度;
使用System.Linq;
使用系统、管理、自动化;
使用System.Management.Automation.Runspaces;
使用系统安全;
班级计划
{
静态void Main(字符串[]参数)
{
变量脚本=@“
写入主机“”--$env:computername------------
写入警告“”直接在警告脚本中写入警告“”
写入错误“”直接在警告脚本中写入错误“”
写入详细信息“”直接在警告脚本“”中写入详细信息“”-详细信息
写入主机“”在警告脚本中直接写入主机“”
写入信息“”在警告脚本中写入信息“”
";
SecureString密码=新SecureString();
“Password.tocharray().ToList().ForEach(c=>Password.AppendChar(c));
PSCredential credentials=新的PSCredential(“用户名”,密码);
WSManConnectionInfo connectionInfo=新的WSManConnectionInfo();
connectionInfo.ComputerName=“TargetServer”;
connectionInfo.Credential=凭证;
使用(var shell=PowerShell.Create())
{
使用(var runspace=RunspaceFactory.CreateRunspace(connectionInfo))
{
Open();
shell.Runspace=运行空间;
shell.Streams.Information.DataAdded+=LogProgress;
shell.Streams.Warning.DataAdded+=LogProgress;
shell.Streams.Error.DataAdded+=LogProgress;
shell.Streams.Verbose.DataAdded+=LogProgress;
shell.Streams.Debug.DataAdded+=LogProgress;
shell.AddScript(脚本);
shell.Invoke();
}
}
Console.ReadKey();
}
私有静态void LogProgress(对象发送方、DataAddedEventArgs e)
{
var数据=(发送方作为PSDataCollection)[e.Index];
WriteLine($“[{typeof(T.Name}]{Convert.ToString(data)}”);
}
}
}
Hi,您是否尝试在脚本变量中添加这些相关变量集:$DebugPreference=SilentlyContinue$ErrorActionPreference=SilentlyContinue和其他:$VerbosePreference=SilentlyContinue$WarningPreference=