2013-01-05 231 views
3

爲列表中的每個服務器運行作業。我只想要一次運行5個作業。作業完成後,應該在列表中的下一臺服務器上開始一項新工作。這裏是我到目前爲止,但我不能讓它開始新工作後的第一晚五組的工作已經跑:PowerShell作業隊列

$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 
} 
+0

這就是我最終做的......我認爲這是爲我工作的.. $ list = Get-Content「。\ list.csv」 $ queue = [System.Collections.Queue] ::同步((新物體System.Collections.Queue)) 的ForEach($在$列表項) { 寫主機 「添加$項目排隊」 $ Queue.Enqueue($項目) } $ Server = $ queue.Dequeue() foreach($ server in $ list){ $ running = Get-Job |位置對象{$ _ JobStateInfo.State -eq '跑步'。} 如果($ running.Count -le 2) { ..腳本這裏.. } 其他 {$ 運行| Wait-Job } } –

回答

4

PowerShell的你,如果你使用Invoke-Command會做到這一點。例如:

Invoke-Command -ComputerName $serverArray -ScriptBlock { .. script here ..} -ThrottleLimit 5 -AsJob 

順便說一句我不認爲你使用.NET Queue會起作用,因爲Start-Job啓動另一個PowerShell進程來執行作業。

+0

感謝您的信息。 Invoke-Command的一點是它希望你在另一臺計算機上調用該命令。 –

+1

Invoke-Command也適用於本地 –

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會話中的幾個運行空間中運行。