我认为这是一种独特的情况。我有大约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文件本身的文本。
答案 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);
}
};
});
}