about_Jobs
Краткое описание
Предоставляет сведения о том, как фоновые задания PowerShell выполняют команду или выражение в фоновом режиме без взаимодействия с текущим сеансом.
Подробное описание
PowerShell параллельно выполняет команды и скрипты с помощью заданий. Существует три типа заданий, предоставляемых PowerShell для поддержки параллелизма.
RemoteJob
— команды и скрипты выполняются в удаленном сеансе. Дополнительные сведения см. в разделе about_Remote_Jobs.BackgroundJob
— Команды и скрипты выполняются в отдельном процессе на локальном компьютере.PSTaskJob
илиThreadJob
— команды и скрипты выполняются в отдельном потоке в рамках одного процесса на локальном компьютере. Дополнительные сведения см. в разделе about_Thread_Jobs.
Удаленное выполнение скриптов на отдельном компьютере или в отдельном процессе обеспечивает большую изоляцию. Ошибки, возникающие в удаленном задании, не влияют на другие выполняемые задания или родительский сеанс, который запустил задание. Однако уровень удаленного взаимодействия добавляет дополнительные затраты, включая сериализацию объектов. Все объекты сериализуются и десериализуются по мере их прохождения между родительским сеансом и удаленным сеансом (задание). Сериализация больших сложных объектов данных может потреблять большие объемы вычислительных ресурсов и ресурсов памяти и передавать большие объемы данных по сети.
Задания на основе потоков не так надежны, как удаленные и фоновые задания, так как они выполняются в одном процессе в разных потоках. Если одно задание имеет критическую ошибку, которая завершает процесс, все остальные задания в процессе завершаются.
Однако задания на основе потоков требуют меньше накладных расходов. Они не используют уровень удаленного взаимодействия или сериализацию. Результируемые объекты возвращаются в виде ссылок на динамические объекты в текущем сеансе. Без этих накладных расходов потоковые задания выполняются быстрее и используют меньше ресурсов, чем другие типы заданий.
Важно!
Родительский сеанс, создавший задание, также отслеживает состояние задания и собирает данные конвейера. Дочерний процесс задания завершается родительским процессом после того, как задание достигнет состояния завершения. Если родительский сеанс завершается, все выполняемые дочерние задания завершаются вместе с дочерними процессами.
Существует два способа обойти эту ситуацию:
- Используйте
Invoke-Command
для создания заданий, которые выполняются в отключенных сеансах. Дополнительные сведения см. в разделе about_Remote_Jobs. - Используйте
Start-Process
для создания нового процесса, а не задания. Дополнительные сведения см. в статье Start-Process.
Командлеты заданий
Start-Job
— запускает фоновое задание на локальном компьютере.Get-Job
— возвращает фоновые задания, которые были запущены в текущем сеансе.Receive-Job
— получает результаты фоновых заданий.Stop-Job
— останавливает фоновое задание.Wait-Job
— подавляет командную строку до завершения одного или всех заданий.Remove-Job
— удаляет фоновое задание.Invoke-Command
— Параметр AsJob создает фоновое задание на удаленном компьютере. Вы можете использовать дляInvoke-Command
удаленного выполнения любой команды задания, включаяStart-Job
.
Запуск задания на локальном компьютере
Чтобы запустить фоновое задание на локальном компьютере, используйте Start-Job
командлет .
Чтобы написать Start-Job
команду, заключите команду, выполняемую заданием, в фигурные скобки ({}
). Используйте параметр ScriptBlock , чтобы указать команду.
Следующая команда запускает фоновое задание, которое выполняет Get-Process
команду на локальном компьютере.
Start-Job -ScriptBlock {Get-Process}
При запуске фонового задания командная строка возвращается немедленно, даже если задание занимает длительное время. Пока задание выполняется, можно продолжать работу с данным сеансом.
Команда Start-Job
возвращает объект, представляющий задание. Объект job содержит полезные сведения о задании, но не содержит результаты задания.
Вы можете сохранить объект задания в переменной, а затем использовать его с другими командлетами Job для управления фоновым заданием. Следующая команда запускает объект задания и сохраняет результирующий объект задания в переменной $job
.
$job = Start-Job -ScriptBlock {Get-Process}
Начиная с PowerShell 6.0, вы можете использовать фоновый оператор (&
) в конце конвейера для запуска фонового задания. Дополнительные сведения см. в разделе Оператор фона.
Использование фонового оператора функционально эквивалентно использованию командлета Start-Job
в предыдущем примере.
$job = Get-Process &
Получение объектов заданий
Командлет Get-Job
возвращает объекты, представляющие фоновые задания, которые были запущены в текущем сеансе. Без параметров возвращает все задания, Get-Job
запущенные в текущем сеансе.
Get-Job
Объект job содержит состояние задания, которое указывает, завершено ли задание. Завершенное задание имеет состояние Завершено или Сбой. Задание также может быть заблокировано или запущено.
Id Name PSJobTypeName State HasMoreData Location Command
-- ---- ------------- ----- ----------- -------- -------
1 Job1 BackgroundJob Complete True localhost Get-Process
Вы можете сохранить объект задания в переменной и использовать его для представления задания в следующей команде. Следующая команда получает задание с идентификатором 1 и сохраняет его в переменной $job
.
$job = Get-Job -Id 1
Получение результатов задания
При выполнении фонового задания результаты отображаются не сразу. Чтобы получить результаты фонового задания, используйте Receive-Job
командлет .
В следующем примере Receive-Job
командлет получает результаты задания с помощью объекта job в переменной $job
.
Receive-Job -Job $job
Handles NPM(K) PM(K) WS(K) VM(M) CPU(s) Id ProcessName
------- ------ ----- ----- ----- ------ -- -----------
103 4 11328 9692 56 1176 audiodg
804 14 12228 14108 100 101.74 1740 CcmExec
668 7 2672 6168 104 32.26 488 csrss
...
Результаты задания можно сохранить в переменной. Следующая команда сохраняет результаты задания в переменной $job
в переменную $results
.
$results = Receive-Job -Job $job
Получение и сохранение частичных результатов задания
Командлет Receive-Job
получает результаты фонового задания. Если задание завершено, Receive-Job
получает все результаты задания. Если задание по-прежнему выполняется, Receive-Job
получает результаты, созданные на данный момент. Вы можете снова выполнить Receive-Job
команды, чтобы получить оставшиеся результаты.
По умолчанию удаляет результаты из кэша, Receive-Job
в котором хранятся результаты задания. При повторном запуске Receive-Job
вы получите только новые результаты, полученные после первого запуска.
Следующие команды показывают результаты Receive-Job
выполнения команд до завершения задания.
C:\PS> Receive-Job -Job $job
Handles NPM(K) PM(K) WS(K) VM(M) CPU(s) Id ProcessName
------- ------ ----- ----- ----- ------ -- -----------
103 4 11328 9692 56 1176 audiodg
804 14 12228 14108 100 101.74 1740 CcmExec
C:\PS> Receive-Job -Job $job
Handles NPM(K) PM(K) WS(K) VM(M) CPU(s) Id ProcessName
------- ------ ----- ----- ----- ------ -- -----------
68 3 2632 664 29 0.36 1388 ccmsetup
749 22 21468 19940 203 122.13 3644 communicator
905 7 2980 2628 34 197.97 424 csrss
1121 25 28408 32940 174 430.14 3048 explorer
Используйте параметр Keep , чтобы предотвратить Receive-Job
удаление возвращаемых результатов задания. Следующие команды показывают эффект использования параметра Keep для задания, которое еще не завершено.
C:\PS> Receive-Job -Job $job -Keep
Handles NPM(K) PM(K) WS(K) VM(M) CPU(s) Id ProcessName
------- ------ ----- ----- ----- ------ -- -----------
103 4 11328 9692 56 1176 audiodg
804 14 12228 14108 100 101.74 1740 CcmExec
C:\PS> Receive-Job -Job $job -Keep
Handles NPM(K) PM(K) WS(K) VM(M) CPU(s) Id ProcessName
------- ------ ----- ----- ----- ------ -- -----------
103 4 11328 9692 56 1176 audiodg
804 14 12228 14108 100 101.74 1740 CcmExec
68 3 2632 664 29 0.36 1388 ccmsetup
749 22 21468 19940 203 122.13 3644 communicator
905 7 2980 2628 34 197.97 424 csrss
1121 25 28408 32940 174 430.14 3048 explorer
Ожидание результатов
При выполнении команды, которая занимает много времени, можно использовать свойства объекта задания, чтобы определить, когда задание будет завершено. Следующая команда использует объект для Get-Job
получения всех фоновых заданий в текущем сеансе.
Get-Job
Результаты отображаются в таблице. Состояние задания отображается в столбце Состояние .
Id Name PSJobTypeName State HasMoreData Location Command
-- ---- ------------- ----- ----------- -------- -------
1 Job1 BackgroundJob Complete True localhost Get-Process
2 Job2 BackgroundJob Running True localhost Get-EventLog -Log ...
3 Job3 BackgroundJob Complete True localhost dir -Path C:\* -Re...
В этом случае свойство State показывает, что задание 2 по-прежнему выполняется. Если вы используете Receive-Job
командлет , чтобы получить результаты задания сейчас, результаты будут неполными. Командлет можно использовать Receive-Job
несколько раз, чтобы получить все результаты. Используйте свойство State , чтобы определить, когда задание будет завершено.
Можно также использовать параметр Wait командлета Receive-Job
. При использовании этого параметра командлет не возвращает командную строку, пока задание не будет завершено и не будут доступны все результаты.
Командлет также можно использовать Wait-Job
для ожидания любых или всех результатов задания. Wait-Job
позволяет ждать одного или нескольких конкретных заданий или всех заданий.
Следующая команда использует Wait-Job
командлет для ожидания задания с идентификатором 10.
Wait-Job -ID 10
В результате запрос PowerShell подавляется до завершения задания.
Вы также можете подождать заранее определенный период времени. Эта команда использует параметр Timeout , чтобы ограничить время ожидания до 120 секунд. По истечении времени командная строка возвращается, но задание продолжает выполняться в фоновом режиме.
Wait-Job -ID 10 -Timeout 120
Остановка задания
Чтобы остановить фоновое задание, используйте Stop-Job
командлет . Следующая команда запускает задание для получения каждой записи в системном журнале событий. Объект задания сохраняется в переменной $job
.
$job = Start-Job -ScriptBlock {Get-EventLog -Log System}
Следующая команда останавливает задание. Он использует оператор конвейера (|
) для отправки задания в переменной $job
в Stop-Job
.
$job | Stop-Job
Удаление задания
Чтобы удалить фоновое задание, используйте Remove-Job
командлет . Следующая команда удаляет задание в переменной $job
.
Remove-Job -Job $job
Исследование задания, завершилось сбоем
Задания могут завершиться сбоем по многим причинам. объект задания содержит свойство Reason , содержащее сведения о причине сбоя.
В следующем примере запускается задание без необходимых учетных данных.
$job = Start-Job -ScriptBlock {New-Item -Path HKLM:\Software\MyCompany}
Get-Job $job
Id Name PSJobTypeName State HasMoreData Location Command
-- ---- ------------- ----- ----------- -------- -------
1 Job1 BackgroundJob Failed False localhost New-Item -Path HKLM:...
Проверьте свойство Reason , чтобы найти ошибку, которая привела к сбою задания.
$job.ChildJobs[0].JobStateInfo.Reason
В этом случае задание завершилось сбоем, так как удаленному компьютеру требовались явные учетные данные для выполнения команды. Свойство Reason содержит следующее сообщение:
Не удалось подключиться к удаленному серверу со следующим сообщением об ошибке: "Доступ запрещен".