Получение вывода из вызова Start-Job

У меня есть следующий код, который работает в том смысле, что он создает несколько заданий и запускает то, что находится внутри блока сценария, на всех компьютерах в массиве ($SMSMembers). Проблема в том, что он не дает никакого значимого вывода, который я мог бы использовать, чтобы определить, успешно ли выполнился код. Я пробовал около 100 различных вещей, которые я искал в Google, но ни одно из решений не сработало для меня. Это код, который я пытаюсь запустить, и я думал, что он должен работать в соответствии с другими сообщениями, которые я видел в StackOverflow.

$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

person Spencer A    schedule 06.09.2018    source источник


Ответы (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
person TheMadTechnician    schedule 07.09.2018
comment
Я попробовал запустить этот код, и мне больше нравится это решение, прикрепляющее переменную вместе с start-job. Единственная проблема заключается в том, что выходной массив не дает мне никакого вывода, когда он проходит через foreach. Насколько я могу судить, массив пустой. - person Spencer A; 07.09.2018
comment
Я смог заставить его работать с вашим решением. Оказывается, вам нужно вернуть результаты задания в виде строки, когда вы закончите работу со скриптовым блоком. Я пытался просто завершить блок сценария задания с помощью переменной, как в каком-то предложении, но это не сработало, ему специально нужна была строка в конце, как у вас. - person Spencer A; 10.09.2018

Посмотрите на приведенный ниже код, и я думаю, вы сможете понять это.

>  Get-job | Receive-Job 2>&1 >> c:\output.log

2>&1 >> со сбором всех выходных данных из Get-Job | Receive-Job должно работать аналогично для start-job

person Sudheej    schedule 07.09.2018