来自 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;

        }
}