2016-08-19 64 views
0

我有我认为是独特的情况。我有大约15个PowerShell脚本,我想在一系列计算机上运行,​​并让脚本返回每个主机上每个脚本的输出。一次在多台机器上运行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文件本身的文本。

回答

2

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

现在你的结果,你需要一个线程安全的集合,这个一直是.NET Framework的一部分,因为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); 
        } 

       }; 
      }); 
     } 
+0

这是有效的,但是对于我添加代码的每个主机来说,速度慢了20秒。我想让PowerShell文件在给定的机器上同时被关闭。 –

+0

现在我再次查看您的代码。 这是一种错误,你应该加入一个回调到你的开始调用,然后在回调中你结束调用不会开始调用和结束调用在相同的方法执行。 https://msdn.microsoft.com/en-us/library/dd182439(v=vs.85).aspx – JQluv

相关问题