如何在.NET Framework应用中执行PowerShell 7脚本?
在.NET Framework中调用PowerShell 7的可行方案
方案1:使用PowerShell 7 SDK直接嵌入调用
PowerShell 7官方提供了可嵌入的SDK包,支持在.NET Framework应用中直接调用,能满足参数传递、输出捕获和凭据注入的需求,步骤如下:
- 安装NuGet包:
Microsoft.PowerShell.SDK(建议选择兼容.NET Framework的LTS版本,如7.2.x系列) - 调用代码示例:
using System; using System.Collections.ObjectModel; using System.Management.Automation; using System.Management.Automation.Runspaces; // 初始化PowerShell 7运行空间配置 var config = RunspaceConfiguration.Create(); using var runspace = RunspaceFactory.CreateRunspace(config); runspace.Open(); // 创建PowerShell实例 using var ps = PowerShell.Create(); ps.Runspace = runspace; // 传入变量与凭据 var securePassword = new System.Security.SecureString(); // 此处填充密码逻辑 var credential = new PSCredential("targetUser", securePassword); ps.AddCommand("Set-Variable").AddParameter("Name", "TargetCred").AddParameter("Value", credential); ps.AddCommand("Set-Variable").AddParameter("Name", "TargetDir").AddParameter("Value", "D:\\WorkDir"); // 添加要执行的脚本逻辑 ps.AddScript(@" Write-Host ""当前处理目录:$TargetDir"" # 示例:使用传入的凭据执行操作 # Get-ChildItem -Path $TargetDir -Credential $TargetCred "); // 执行并捕获输出 Collection<PSObject> output = ps.Invoke(); // 处理标准输出 foreach (var item in output) { Console.WriteLine(item.ToString()); } // 处理错误信息 if (ps.HadErrors) { foreach (var error in ps.Streams.Error) { Console.WriteLine($"错误:{error.ToString()}"); } }
- 注意:确保运行环境已安装PowerShell 7,SDK会自动关联本地运行时;若部署到无PowerShell 7的环境,可打包便携版PowerShell 7,并通过
RunspaceConfiguration指定运行时路径。
方案2:增强版进程调用(无SDK依赖)
如果不想引入SDK依赖,可通过Process类精细化控制pwsh.exe的调用,实现参数传递、输出捕获和凭据注入:
- 核心思路:通过
ProcessStartInfo配置命令行参数、重定向输入输出流,支持指定凭据启动进程 - 代码示例:
using System; using System.Diagnostics; using System.Security; var scriptPath = @"D:\Scripts\YourScript.ps1"; var targetDir = "D:\\WorkDir"; var securePassword = new SecureString(); // 此处填充密码逻辑 var credential = new System.Net.NetworkCredential("targetUser", securePassword); // 配置进程启动信息 var psi = new ProcessStartInfo { FileName = "pwsh.exe", // 传递脚本路径与位置参数,禁用配置文件、绕过执行策略 Arguments = $"-NoProfile -ExecutionPolicy Bypass -File ""{scriptPath}"" -TargetDir ""{targetDir}""", RedirectStandardOutput = true, RedirectStandardError = true, UseShellExecute = false, CreateNoWindow = true, // 指定执行凭据 UserName = credential.UserName, Password = credential.SecurePassword }; // 启动进程并捕获输出 using var process = Process.Start(psi); process.WaitForExit(); // 读取输出与错误信息 string output = process.StandardOutput.ReadToEnd(); string error = process.StandardError.ReadToEnd(); Console.WriteLine("脚本输出:"); Console.WriteLine(output); if (!string.IsNullOrEmpty(error)) { Console.WriteLine("脚本错误:"); Console.WriteLine(error); }
- 复杂变量传递技巧:若需传递复杂对象,可将对象序列化为JSON字符串通过命令行参数传入,在PowerShell脚本中用
ConvertFrom-Json反序列化使用;也可通过标准输入传递数据。
方案3:绕开远程执行bug的替代远程调用(若需远程)
如果必须远程执行,可尝试以下方式绕开已知bug:
- 使用
Invoke-Command时指定-ConfigurationName Microsoft.PowerShell.Core配置; - 通过SSH协议远程调用PowerShell 7(PowerShell 7原生支持SSH),在.NET Framework中借助SSH库(如SSH.NET)执行
pwsh -Command "..."命令并捕获输出。
内容的提问来源于stack exchange,提问作者Merlin Schumacher
相关产品推荐
相关产品推荐

