来自 C# 的异步 运行 多个 PowerShell 脚本
Asynchronously running multiple PowerShell scripts from C#
我正在尝试做的事情的简短描述:
我正在开发一个 .Net WinForm 应用程序,我试图在远程服务器上 运行 多个 PowerShell 脚本并在表单上显示结果。
此刻我正在同步执行脚本,这导致我遇到长 运行ning 脚本的问题。
知道如何让这个函数异步执行吗?
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();
}
如有任何建议,我们将不胜感激。谢谢!
将您的 NewPsSesson 方法更改为 async
和 return 和 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;
}
}
我正在尝试做的事情的简短描述:
我正在开发一个 .Net WinForm 应用程序,我试图在远程服务器上 运行 多个 PowerShell 脚本并在表单上显示结果。
此刻我正在同步执行脚本,这导致我遇到长 运行ning 脚本的问题。
知道如何让这个函数异步执行吗?
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();
}
如有任何建议,我们将不胜感激。谢谢!
将您的 NewPsSesson 方法更改为 async
和 return 和 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;
}
}