0

我正在尝试找出一种为 20-30 个文件异步调用 Powershell cmdlet 的有效方法。尽管下面的代码可以正常工作,但 Import-Module 步骤会针对每个处理的文件运行。不幸的是,这个模块需要 3 到 4 秒才能导入。

在网上搜索我可以找到对 RunspacePools 和 InitialSessionState 的引用,但在尝试创建 CreateRunspacePool 重载中所需的 PSHost 对象时遇到了问题。

任何帮助,将不胜感激。

谢谢

加文

.

.

我的应用程序中的代码示例:

我正在使用 Parallel ForEach 在线程之间分配文件。

Parallel.ForEach(files, (currentFile) => 
{
    ProcessFile(currentfile);
});



private void ProcessFile(string filepath)
{
    // 
    // Some non powershell related code removed for simplicity
    //


    // Start PS Session, Import-Module and Process file
    using (PowerShell PowerShellInstance = PowerShell.Create())
    {
        PowerShellInstance.AddScript("param($path) Import-Module MyModule; Process-File -Path $path");
        PowerShellInstance.AddParameter("path", filepath);
        PowerShellInstance.Invoke();
    }
}
4

1 回答 1

0

正如评论中已经解释的那样,这将不起作用,PSJobs因为对象是序列化的,并且作业本身在单独的进程中运行。

你可以做的是创建一个RunspacePool导入InitialSessionState了模块的:

private RunspacePool rsPool;

public void ProcessFiles(string[] files)
{
    // Set up InitialSessionState 
    InitialSessionState initState = InitialSessionState.Create();
    initState.ImportPSModule(new string[] { "MyModule" });
    initState.LanguageMode = PSLanguageMode.FullLanguage;

    // Set up the RunspacePool
    rsPool = RunspaceFactory.CreateRunspacePool(initialSessionState: initState);
    rsPool.SetMinRunspaces(1);
    rsPool.SetMaxRunspaces(8);
    rsPool.Open();

    // Run ForEach()
    Parallel.ForEach(files, ProcessFile);
}

private void ProcessFile(string filepath)
{
    // Start PS Session and Process file
    using (PowerShell PowerShellInstance = PowerShell.Create())
    {
        // Assign the instance to the RunspacePool
        PowerShellInstance.RunspacePool = rsPool;

        // Run your script, MyModule has already been imported
        PowerShellInstance.AddScript("param($path) Process-File @PSBoundParameters").AddParameter("path", filepath);
        PowerShellInstance.Invoke();
    }
}
于 2016-06-12T21:44:06.087 回答