여러 컴퓨터에서 동시에 가지고 있는 PowerShell 스크립트를 실행하려고 합니다. 현재 저는 PowerShell 버전 5를 사용하고 있습니다.
로그에 대한 이해를 돕기 위해 백그라운드 프로세스 없이 실행할 수 있는지 알고 싶습니다.
$computers = @("Hostname1", "Hostname2", "Hostname3")
$scriptPath = "C:\Projects\Scripts\Environment\InstallEnvironment.ps1"
$scriptBlock = {
param (
[string]$scriptPath
)
try {
# Execute the script
& $scriptPath
}
catch {
Write-Host "Error occurred on $($env:COMPUTERNAME): $_"
}
}
foreach ($computer in $computers) {
Start-Job -ScriptBlock $scriptBlock -ArgumentList $scriptPath -Name $computer
}
while (Get-Job -State Running) {
Start-Sleep -Milliseconds 100
}
Get-Job | Receive-Job
Get-Job | Remove-Job
어떤 도움이라도 대단히 감사하겠습니다.
답변1
내 생각에는 세 가지 옵션이 있습니다.
- Jobs를 계속 진행하되 코드를 약간 리팩토링하세요.
ForEach-Object -Parallel
PowerShell 7에서 사용- 사용해 보세요워크플로우
foreach -Parallel ($a in $x) {}
PowerShell 5에서는 다른 종류의 골칫거리를 허용합니다.
Invoke-Command
다음은 작업을 생성하고 Wait-Job
기다리는 데 사용되는 코드 조각입니다 .
$computers = @("Hostname1", "Hostname2", "Hostname3")
$scriptPath = "C:\Projects\Scripts\Environment\InstallEnvironment.ps1"
$scriptBlock = {
try {
& $Using:scriptPath
}
catch {
Write-Host "Error occurred on $($env:COMPUTERNAME): $_"
}
}
$Jobs = Invoke-Command -ScriptBlock $scriptBlock -ComputerName $computers -AsJob
# Results (Logs) are stored in the $Result variable
$Result = $Jobs | Wait-Job | Receive-Job
$Jobs | Remove-Job
를 사용할 수 있는 방법은 다음과 같습니다. ForEach-Object -Parallel
하지만 주의하세요. 때로는 평소처럼 콘솔에 내용을 출력할 수 없으며 다른 종류의 골칫거리가 될 수 있습니다.
#Requires -Version 7
$computers = @("Hostname1", "Hostname2", "Hostname3")
$scriptPath = "C:\Projects\Scripts\Environment\InstallEnvironment.ps1"
$scriptBlock = {
try {
& $Using:scriptPath
}
catch {
Write-Host "Error occurred on $($env:COMPUTERNAME): $_"
}
}
$computers | ForEach-Object -Parallel {
Invoke-Command -ScriptBlock $scriptBlock -ComputerName $_
}
저는 Jobs에 계속 남아서 다음을 통해 로그를 받는 것을 절대적으로 권장합니다.Receive-Job