一次在多台计算机上运行PowerShell脚本列表

时间:2016-08-19 17:25:06

标签: c# powershell

我认为这是一种独特的情况。我有大约15个PowerShell脚本,我想对计算机列表运行,并让脚本返回每个主机上每个脚本的输出。

我的工作原理,但它似乎没有同时在每个主机上运行脚本,而且速度很慢。任何帮助表示赞赏。

 for (int i = 0; i < hosts.Length; i++)
            {
                var remoteComputer = new Uri(String.Format("{0}://{1}:5985/wsman", "http", hosts[i]));
                var connection = new WSManConnectionInfo(remoteComputer);
                var runspace = RunspaceFactory.CreateRunspace(connection);
                runspace.Open();

                for (int ii = 0; ii < powerShellfiles.ToArray().Length; ii++)
                {
                    using (PowerShell ps = PowerShell.Create())
                    {
                        ps.Runspace = runspace;
                        //ps.AddScript(powerShellfiles[ii]);
                        ps.AddScript(powerShellfiles[ii]);
                        IAsyncResult async = ps.BeginInvoke();
                        List<string> aa = ps.EndInvoke(async).SelectMany(x => x.Properties.Where(y => y.Name == "rec_num").Select(z => z.Value.ToString())).ToList();
                        keysFromhost.AddRange(aa);
                    }

                };

            };

powerShellfiles中的每个项目都是.ps1文件本身的文本。

1 个答案:

答案 0 :(得分:2)

您需要做的就是使用Parallel.ForEach异步框架/类和方法。 这是一个非常简单的解决方案Parallel将为您提供的数组中的每个项生成单独的线程,并且在所有线程完成执行之前不会返回,您还可以检查返回值并查看是否所有任务都成功完成。

现在为了你的结果,你需要一个线程安全的集合,这个已经成为.net框架的一部分,因为3.0我将使用我在下面指定的那个:

System.Collections.Generic.SynchronizedCollection<T>

示例:

        private void RunPowerShell(string[] hosts)
        {
            Parallel.ForEach(hosts, (host) => {
                var remoteComputer = new Uri(String.Format("{0}://{1}:5985/wsman", "http", hosts));
                var connection = new WSManConnectionInfo(remoteComputer);
                var runspace = RunspaceFactory.CreateRunspace(connection);
                runspace.Open();

                for (int ii = 0; ii < powerShellfiles.ToArray().Length; ii++)
                {
                    using (PowerShell ps = PowerShell.Create())
                    {
                        ps.Runspace = runspace;
                        //ps.AddScript(powerShellfiles[ii]);
                        ps.AddScript(powerShellfiles[ii]);
                        IAsyncResult async = ps.BeginInvoke();
                        List<string> aa = ps.EndInvoke(async).SelectMany(x => x.Properties.Where(y => y.Name == "rec_num").Select(z => z.Value.ToString())).ToList();
                        keysFromhost.AddRange(aa);
                    }

                };
            });
        }