2016-08-19 8 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); 
        } 

       }; 

      }; 

各項目は.ps1ファイル自体のテキストです。

答えて

2

あなたがする必要があることは、Parallel.ForEach Asyncフレームワーク/クラスとメソッドを使用することだけです。 これは非常に簡単な解決方法です。Parallelは、あなたが提供する配列内の各項目について個々のスレッドを生成し、すべてのスレッドが実行を終了するまで戻りません。また、戻り値をチェックして、

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); 
        } 

       }; 
      }); 
     } 

は、今すぐあなたの結果のためにあなたは私が下に指定されたものを使用することになり3.0以降この1つは.NET Frameworkの一部となっている、スレッドセーフなコレクションが必要になります

+0

これはうまくいきますが、私が追加したホストごとに〜20秒遅くなります。 PowerShellファイルを特定のマシン上で同時に解凍したい。 –

+0

さて、あなたのコードをもう一度見ています。 begin invokeにコールバックを追加してからcallbackで呼び出しを終了するのは間違っています。invokeを開始しないで、invokeを同じメソッドを実行して終了します。 https://msdn.microsoft.com/en-us/library/dd182439(v=vs.85).aspx – JQluv

関連する問題