簡體   English   中英

Powershell並行作業輸出文件

[英]Powershell parallel jobs output file

我已經做了很多研究,但仍然不知道如何完成我想做的事情。

我想在100台Linux服務器上並行執行相同的任務。

這是我的腳本的簡化示例:

$computer=Get-Content "serverList.txt"
$jobArray=@()
$script={
    $cpuThresh=70
    $cpuUsage=<Get CPU usage of the host>
    Write-Host "CPU Usage: $cpuUsage %"
    if ($cpuUsage -ge $cpuThresh) {
        Write-Host "Unexpected CPU Usage" -ForegroundColor Red
    }
}
foreach ($system in $computer) {
    $jobArray += Start-Job -ScriptBlock $script -ArgumentList $system
    While ((Get-Job -State 'Running').Count -ge 10) {
        Start-Sleep -Milliseconds 10
    }
}
foreach ($job in $jobArray) {
    While ($job.State -eq 'Running') {
        Start-Sleep -Milliseconds 10
    }
    Receive-Job -Job $job
    Remove-Job -Job $job
}

我遇到的問題是我想將某些消息(例如,意外的CPU使用率)寫入一個單獨的文件,並且多個作業試圖同時寫入該文件。

我的想法是將所有消息保存到數組中,並將腳本末尾的內容(第二個foreach循環)寫入文件。

但是Receive-Job不會返回任何變量/對象。

有沒有辦法返回變量/對象? 還是有另一種方式可以實現我想做的事情?

我將不勝感激任何幫助。 謝謝。

Receive-Job不會獲得任何結果,因為使用的不是標准輸出的Write-Host 將行Write-Host "Unexpected CPU Usage" -ForegroundColor Red替換為"Unexpected CPU Usage"並且Receive-Job應該開始接收消息。 處理Receive-Job時,在腳本的最后使用Write-Host -ForegroundColor Red

另外,我建議您看看專門為此類任務設計的模塊SplitPipeline 您的腳本可以使用命令Split-Pipeline ,其代碼將減少到最少:

Get-Content "serverList.txt" | Split-Pipeline -Count 10 {process{
    $cpuThresh=70
    $cpuUsage = ... # Get CPU usage of the host, use $_ as the current input server
    "CPU Usage: $cpuUsage %" # standard output
    if ($cpuUsage -ge $cpuThresh) {
        "Unexpected CPU Usage" # "warning" to be analysed later
        # or even better, Split-Pipeline takes care of warnings:
        Write-Warning "Unexpected CPU Usage"
    }
}} | % {
    # process output here, e.g. normal messages goes to a log file
    # and warnings are processed as
    Write-Host "Unexpected CPU Usage" -ForegroundColor Red

    # or if you used Write-Warning above this is not even needed
}

每個工作至少有(通常只有一個)子工作。 進程的輸出實際上保存在子作業的單獨輸出緩沖區中,並且可以從那里訪問。 您可以將Write-Verbose用於一組輸出,將Write-Warning用於另一組輸出,然后分別從Verbose和Warning流中讀回它:

$computer=Get-Content "serverList.txt"
$jobArray=@()
$script={
    $VerbosePreference = 'Continue'
    $Args[0]
    $cpuThresh=70
    $cpuUsage=<Get CPU usage of the host>
    Write-Verbose "CPU Usage: $cpuUsage %"
    if ($cpuUsage -ge $cpuThresh) {
        Write-Warning "Unexpected CPU Usage" 
    }
$Results  = @{}
$Warnings = @{}
$Outputs  = @{}
}
foreach ($system in $computer) {
    $jobArray += Start-Job -ScriptBlock $script -ArgumentList $system
    While ((Get-Job -State 'Running').Count -ge 10) {
        Start-Sleep -Milliseconds 10
    }
}
foreach ($job in $jobArray) {
    While ($job.State -eq 'Running') {
        Start-Sleep -Milliseconds 10
    }
     $Server = $Job.ChildJobs[0].Output[0]
     $Results[$Server] = $Job.ChildJobs[0].Verbose
     $Warnings[$Server] = $Job.ChildJobs[0].Warning
     $Outputs[$Server]   = $Job.ChildJobs[0].Output

    Remove-Job -Job $job
}

編輯:更新為所有本地作業。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM