Получение вывода из вызова Start-Job
У меня есть следующий код, который работает в том, что он создает несколько заданий и выполняет то, что находится внутри блока сценария на всех компьютерах в массиве ($SMSMembers
). Проблема заключается в том, что он не дает какого-либо значимого вывода обратно, который я могу использовать, чтобы определить, был ли код выполнен успешно или нет. Я перепробовал около 100 различных вещей, которые у меня есть, Google, но ни одно из решений, казалось, не работает для меня. Это код, который я пытаюсь запустить, который, как я думал, должен работать в соответствии с другими постами, которые я видел в Stackru.
$SMSMembers = @("computer1","computer2","computer3")
$output = @()
foreach ($compName in $SMSMembers) {
$scriptblock = {
$file = {"test"}
$filepath = "\\$using:compName\c$\scripts\NEWFILE.txt"
$file | Out-File -FilePath $filepath
Start-Sleep -Seconds 5
Remove-Item $filepath
}
$output += Start-Job -ScriptBlock $scriptblock | Get-Job | Receive-Job
}
Get-Job | Wait-Job
foreach ($item in $output) {
Write-Host $item
}
Этот скрипт ничего не делает, кроме как скопировать файл на удаленный компьютер и затем удалить его. Я просто хотел бы получить результат, если работа была успешной или нет. Как я уже сказал, этот код работает так, как должен, я просто не получаю обратной связи.
Моя конечная цель состоит в том, чтобы иметь возможность отправить команду на массив компьютеров ($SMSMembers
) и запросить текущего пользователя с этим кодом и получить ввод имени пользователя обратно:
$user = gwmi Win32_ComputerSystem -Comp $compName |
select Username -ExpandProperty Username
2 ответа
Вы создаете задание, получаете информацию о задании, а затем получаете задание вплотную, прежде чем задание может быть завершено. Вместо этого соберите информацию о задании, затем за пределами цикла дождитесь завершения задания и получите вывод, когда задания завершены.
$SMSMembers = @("computer1","computer2","computer3")
$scriptblock = {
$file = {"test"}
$filepath = "\\$using:compName\c$\scripts\NEWFILE.txt"
$file | out-file -FilePath $filepath
Start-Sleep -Seconds 5
remove-item $filepath
}
$Jobs = foreach($compName in $SMSMembers){
Start-Job -ScriptBlock $scriptblock
}
Wait-Job $Jobs
$Output = Receive-Job $Jobs
foreach ($item in $output){
write-host $item
}
Изменить: Слегка изменил сценарий, чтобы я не копировал файлы случайным образом, но он все равно должен функционировать. Затем проверил это с ожидаемыми результатами:
$SMSMembers = @("computer1","computer2","computer3")
$scriptblock = {
$RndDly=Get-Random -Minimum 10 -Maximum 45
start-sleep -Seconds $RndDly
"Slept $RndDly, then completed for $using:compname"
}
$Jobs = foreach($compName in $SMSMembers){
Start-Job -ScriptBlock $scriptblock
}
Wait-Job $Jobs
$Output = Receive-Job $Jobs
foreach ($item in $output){
write-host $item
}
Id Name PSJobTypeName State HasMoreData Location Command
-- ---- ------------- ----- ----------- -------- -------
1 Job1 BackgroundJob Completed True localhost ...
3 Job3 BackgroundJob Completed True localhost ...
5 Job5 BackgroundJob Completed True localhost ...
Slept 30, then completed for computer1
Slept 27, then completed for computer2
Slept 11, then completed for computer3
Посмотрите на приведенный ниже код, и я думаю, вы сможете понять это.
> Get-job | Receive-Job 2>&1 >> c:\output.log
2>&1 >>
с собирать всю продукцию из Get-Job | Receive-Job
это должно работать аналогично для start-job