从 C# 异步运行多个 PowerShell 脚本
Posted
技术标签:
【中文标题】从 C# 异步运行多个 PowerShell 脚本【英文标题】:Asynchronously running multiple PowerShell scripts from C# 【发布时间】:2021-08-16 17:45:24 【问题描述】:简要说明我正在尝试做的事情:
我正在开发一个 .Net WinForm 应用程序,我试图在远程服务器上运行多个 PowerShell 脚本并在表单上显示结果。
此时我正在同步执行脚本,这给我带来了长时间运行脚本的问题。
知道如何让这个函数异步执行吗?
public string NewPsSession(string ServerName, string command)
Runspace runspace = RunspaceFactory.CreateRunspace();
runspace.Open();
PowerShell psSession = PowerShell.Create();
psSession.Commands.AddScript("$sessions = New-PSSession -ComputerName " + ServerName + Environment.NewLine
+ "Invoke-Command -session $sessions -ScriptBlock " + command + "" + Environment.NewLine
+ "Remove-PSSession -Session $sessions" + Environment.NewLine);
psSession.Commands.AddCommand("Out-String");
Collection<PSObject> results = new Collection<PSObject>();
try
results = psSession.Invoke();
catch (Exception ex)
results.Add(new PSObject((object)ex.Message));
runspace.Close();
StringBuilder stringBuilder = new StringBuilder();
foreach (PSObject obj in results)
stringBuilder.AppendLine(obj.ToString());
return stringBuilder.ToString();
任何建议将不胜感激。谢谢!
【问题讨论】:
【参考方案1】:将您的 NewPsSesson 方法更改为 async
并返回 Task<string>
。然后将您的代码移动到 Task<string>.Run()
块中并等待它。然后您可以等待您的NewPsSession()
方法,或者像我在Main()
中所做的那样将其作为一项任务进行监控
class Program
public static void Main(string[] args)
Task<string> task = NewPsSession("", "");
while (!task.IsCompleted)
Task.Delay(500).Wait();
Console.WriteLine("Waiting...");
Console.WriteLine(task.Result);
Console.WriteLine("Done");
public static async Task<string> NewPsSession(string ServerName, string command)
var result = await Task<string>.Run(() =>
Runspace runspace = RunspaceFactory.CreateRunspace();
runspace.Open();
PowerShell psSession = PowerShell.Create();
psSession.Commands.AddScript("$sessions = New-PSSession -ComputerName " + ServerName + Environment.NewLine
+ "Invoke-Command -session $sessions -ScriptBlock " + command + "" + Environment.NewLine
+ "Remove-PSSession -Session $sessions" + Environment.NewLine);
psSession.Commands.AddCommand("Out-String");
Collection<PSObject> results = new Collection<PSObject>();
try
results = psSession.Invoke();
catch (Exception ex)
results.Add(new PSObject((object)ex.Message));
runspace.Close();
StringBuilder stringBuilder = new StringBuilder();
foreach (PSObject obj in results)
stringBuilder.AppendLine(obj.ToString());
return stringBuilder.ToString();
);
return result;
【讨论】:
不客气。请注意,您正在创建一个运行空间,但并未实际使用它。如果你想使用运行空间,你必须将它连接到你的 psSession (psSession.Runspace = runspace;
)。现在,当您执行psSession.Invoke()
时,每次都会创建一个新的运行空间,这很好,因为您只执行一次调用。您可以删除处理运行空间的 3 行。如果您多次调用 pssession,我建议将 psSession 连接到更持久的运行空间。以上是关于从 C# 异步运行多个 PowerShell 脚本的主要内容,如果未能解决你的问题,请参考以下文章
如何从 C# 中的 powershell 脚本中捕获退出代码
如何在整个 Azure 管理组上运行 powershell 脚本以跨越多个订阅?