1

すでに多くの調査を行っていますが、やりたいことを達成する方法がまだわかりません。

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 使用率など) を別のファイルに書き込みたいのですが、複数のジョブがこのファイルに同時に書き込もうとしていることです。

私の考えは、すべてのメッセージを配列に保存し、スクリプトの最後 (2 番目の foreach ループ) の内容をファイルに書き込むことです。

しかし、Receive-Job は変数/オブジェクトを返しません。

変数/オブジェクトを返す方法はありますか? または、私がやりたいことを達成する別の方法はありますか?

助けていただければ幸いです。ありがとう。

4

2 に答える 2

2

Receive-JobWrite-Host標準出力ではない が使用されているため、結果は得られません。Write-Host "Unexpected CPU Usage" -ForegroundColor Red行を"Unexpected CPU Usage"and に置き換えてReceive-Job、メッセージの受信を開始する必要があります。Write-Host -ForegroundColor Redを処理するときに、スクリプトの最後で使用しますReceive-Job

また、このようなタスク用に特別に設計されたモジュール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
}
于 2013-11-21T08:54:29.957 に答える
0

すべてのジョブには、少なくとも (通常は 1 つだけ) 子ジョブがあります。プロセスの出力は、実際には子ジョブの個別の出力バッファーに保持され、そこからアクセスできます。出力の 1 つのセットに 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
}

編集:すべてのローカルジョブについて更新。

于 2013-11-21T11:37:44.840 に答える