在PowerShell中并行保存到数组/列表

时间:2017-01-07 15:35:58

标签: powershell

我想在我的PS脚本中并行收集信息。

我的脚本通常按照

的方式执行
foreach ($system in $systemlist) {
    $system = Add-InformationToServerObj $system 
}

因此$ systemlist会填充更多信息,以后会被使用。

如何将需要将输出保存到一个共享列表/数组的任务并行化?

2 个答案:

答案 0 :(得分:1)

使用它:

-

答案 1 :(得分:1)

Start-Job是一个选项,但它在处理时间上的开销非常高,因为每个作业都会启动新进程,并且必须在父进程和作业进程之间序列化数据。

改为使用运行空间:

# Create initial sessionstate object for the runspaces
$InitialSessionState = [initialsessionstate]::Create()
# Import module that contains Add-InformationToServerObj
$InitialSessionState.ImportPSModule("InformationModule")

# Create and open the runspacepool
$RunspacePool = [runspacefactory]::CreateRunspacePool($InitialSessionState)
$RunspacePool.Open()

# Create a new PowerShell instance per "job", collect these along with the IAsyncResult handle (we'll need it later)
$Jobs = foreach($system in $systemlist)
{
    $PSInstance = [powershell]::Create()
    [void]$PSInstance.AddCommand('Add-InformationToServerObj').AddArgument($system)

    New-Object psobject -Property @{
        Instance = $PSInstance
        IAResult = $PSInstance.BeginInvoke()
    }
}

# Wait for runspaces to complete
while($InProgress = @($Jobs |Where-Object {-not $_.IAResult.IsCompleted})){
    # Here you could also use Write-Progress
    Write-Host "$($InProgress.Count) jobs still in progress..."
    Start-Sleep -Milliseconds 500
}

# Collect the output
$systemlist = foreach($Job in $Jobs)
{
    $Job.Instance.EndInvoke($Job.IAResult)
}

# Dispose of the runspacepool
$RunspacePool.Dispose()

以上是一个非常基本的示例,并且没有错误处理 - 请考虑使用类似Invoke-ParallelPoshRSJobs的内容(也可以在the gallery找到PoshRSJobs)