PowerShell作业队列

时间:2013-01-05 11:43:07

标签: powershell queue start-job

为列表中的每个服务器运行作业。我一次只想要5个工作。作业完成后,它应该在列表中的下一个服务器上启动新作业。这是我到目前为止所拥有的,但是在前5个工作岗位开始后我无法开始新工作:

   $MaxJobs = 5
   $list = Get-Content ".\list.csv"
   $Queue = New-Object System.Collections.Queue
   $CurrentJobQueue = Get-Job -State Running
   $JobQueueCount = $CurrentJobQueue.count

   ForEach($Item in $list)
  {
  Write-Host "Adding $Item to queue"
  $Queue.Enqueue($Item)
  }

 Function Global:Remote-Install
 {
 $Server = $queue.Dequeue()
 $j = Start-Job -Name $Server -ScriptBlock{

        If($JobQueueCount -gt 0)
        {
        Test-Connection $Server -Count 15
        }##EndIf
    }##EndScriptBlock

  }

For($i = 0 ;$i -lt $MaxJobs; $i++) 
{
Remote-Install
}

2 个答案:

答案 0 :(得分:4)

如果您使用Invoke-Command例如:

,PowerShell会为您执行此操作
Invoke-Command -ComputerName $serverArray -ScriptBlock { .. script here ..} -ThrottleLimit 5 -AsJob

BTW我不认为您使用.NET Queue会起作用,因为Start-Job会启动另一个PowerShell进程来执行该作业。

答案 1 :(得分:3)

您可以查看模块SplitPipeline的cmdlet Split-Pipeline。 代码如下:

Import-Module SplitPipeline
$MaxJobs = 5
$list = Get-Content ".\list.csv"
$list | Split-Pipeline -Count $MaxJobs -Load 1,1 {process{
    # process an item from $list represented by $_
    ...
}}

-Count $MaxJobs限制并行作业的数量。 -Load 1,1告诉管道 每项工作只有1项。

这种方法的优点是代码本身是同步调用的 并且它输出作业的结果,好像所有都被顺序调用(甚至 可以使用开关Order)保存输出顺序。

但这种方法不使用远程处理。该代码在当前PowerShell会话中可在多个运行空间中运行。