Поделиться через


Сведения о заданиях

Краткое описание

Предоставляет сведения о том, как фоновые задания PowerShell выполняют команду или выражение в фоновом режиме без взаимодействия с текущим сеансом.

Подробное описание

PowerShell параллельно выполняет команды и скрипты с помощью заданий. Существует три типа заданий, предоставляемых PowerShell для поддержки параллелизма.

  • RemoteJob — команды и скрипты выполняются в удаленном сеансе. Дополнительные сведения см. в разделе about_Remote_Jobs.
  • BackgroundJob — Команды и скрипты выполняются в отдельном процессе на локальном компьютере.
  • PSTaskJob или ThreadJob — команды и скрипты выполняются в отдельном потоке в рамках одного процесса на локальном компьютере. Дополнительные сведения см. в разделе about_Thread_Jobs.

Удаленный запуск скриптов на отдельном компьютере или в отдельном процессе обеспечивает большую изоляцию. Ошибки, возникающие в удаленном задании, не влияют на другие выполняемые задания или родительский сеанс, который запустил задание. Однако уровень удаленного взаимодействия добавляет дополнительные расходы, включая сериализацию объектов. Все объекты сериализуются и десериализуются по мере их прохождения между родительским сеансом и удаленным сеансом (задания). Сериализация больших сложных объектов данных может потреблять большие объемы вычислительных ресурсов и памяти, а также передавать большие объемы данных по сети.

Задания на основе потоков не так надежны, как удаленные и фоновые задания, так как они выполняются в одном процессе в разных потоках. Если в одном задании возникает критическая ошибка, которая завершает работу процесса, все остальные задания в процессе завершаются.

Однако задания на основе потоков требуют меньше накладных расходов. Они не используют уровень удаленного взаимодействия или сериализацию. Результирующий объект возвращается в виде ссылок на динамические объекты в текущем сеансе. Без этих издержек потоковые задания выполняются быстрее и используют меньше ресурсов, чем задания других типов.

Важно!

Родительский сеанс, создавший задание, также отслеживает состояние задания и собирает данные конвейера. Дочерний процесс задания завершается родительским процессом, когда задание достигает завершенного состояния. Если родительский сеанс завершается, все выполняемые дочерние задания завершаются вместе с дочерними процессами.

Обойти это ограничение можно двумя способами:

  1. Используйте для Invoke-Command создания заданий, которые выполняются в отключенных сеансах. Дополнительные сведения см. в разделе about_Remote_Jobs.
  2. Используйте 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 = Start-Job -ScriptBlock {Get-Process}

Начиная с PowerShell 6.0, для запуска фонового задания можно использовать фоновый оператор (&) в конце конвейера. Дополнительные сведения см. в разделе Оператор background.

Использование фонового оператора функционально эквивалентно использованию командлета Start-Job в предыдущем примере.

$job = Get-Process &

Получение объектов заданий

Командлет Get-Job возвращает объекты, представляющие фоновые задания, запущенные в текущем сеансе. Без параметров возвращает все задания, Get-Job запущенные в текущем сеансе.

Get-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 содержит следующее сообщение:

Не удалось подключиться к удаленному серверу со следующим сообщением об ошибке: "Доступ запрещен".

См. также раздел