2013-11-21 7 views
1

나는 이미 많은 연구를 해왔지만, 내가하고 싶은 것을 성취하는 방법을 여전히 알 수 없다.Powershell 병렬 작업 출력 파일

100 대의 Linux 서버에서 동일한 작업을 병렬로 수행하고자합니다. 여기

내 스크립트의 간단한 예입니다

$computer=Get-Content "serverList.txt" 
[email protected]() 
$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은 변수/개체를 반환하지 않습니다.

변수/개체를 반환하는 방법이 있습니까? 아니면 내가하고 싶은 것을 성취 할 수있는 또 다른 방법이 있습니까?

어떤 도움을 주셔서 감사합니다. 감사.

답변

0

모든 작업은 적어도 (AN 일반적으로 하나의) 하위 작업이 있습니다. 프로세스의 출력은 실제로 하위 작업의 개별 출력 버퍼에 보관되며 여기에서 액세스 할 수 있습니다. 당신은 출력 한 세트에 대한 쓰기 자세한 정보를 사용하고, 쓰기 경고 서로에 대한, 별도로 다시 자세한 정보에서 읽어 및 경고 스트림 할 수 있습니다

$computer=Get-Content "serverList.txt" 
[email protected]() 
$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 
} 

편집 : 모든 로컬 작업에 업데이트되었습니다.

+0

빠른 답장을 보내 주셔서 감사합니다. 다른 출력 스트림을 사용하는 것에 대해 생각해야합니다 ... 유일한 문제는 $ job.ChildJobs [0]입니다. 경고는 모든 메시지를 포함하는 개체를 반환합니다. 메시지 헤더를 제거하는 가장 좋은 방법은 무엇입니까? 쓰기 출력 $ 경고 | 메시지 | Format-Table -HideTableHeaders 그게 내가 지금하고있는 방식이야. 더 나은 해결책이 있습니까? – user3015914

+0

$ 경고 | 쓰기 출력이 작동하는 것 같습니다. – mjolinor

2

Receive-JobWrite-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 
} 
+0

답장을 보내 주셔서 감사합니다. SlitPipeline을 확실히 살펴볼 것이지만 지금은 다른 출력 스트림을 사용하는 것이 더 나은 해결책입니다. – user3015914

+0

예,보세요. Split-Pipeline은 병렬 처리에 대한 모든 일상 업무를 처리합니다. 동시에 병렬 처리가 사용되지 않는 것처럼 거의 동시에 출력이 처리됩니다. –