about_Jobs

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

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

Длинное описание

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

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

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

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

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

Важный

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

Существует два способа обойти эту ситуацию:

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

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

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

$job = Get-Process &

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

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

Get-Job

Объект задания содержит состояние задания, указывающее, завершено ли задание. Готовое задание имеет состояние Complete или Failed. Задание также может быть заблокированным или выполнение.

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.

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

Результаты отображаются в таблице. Состояние задания отображается в столбце state.

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...

В этом случае свойство состояния показывает, что задание 2 по-прежнему выполняется. Если вы использовали командлет Receive-Job для получения результатов задания сейчас, результаты будут неполными. Командлет можно многократно использовать Receive-Job для получения всех результатов. Используйте свойство State, чтобы определить, когда задание завершено.

Вы также Receive-Job -Wait можете выполнить команду. При использовании этого параметра командлет не возвращает командную строку, пока задание не будет завершено, и все результаты будут доступны.

Можно также использовать командлет 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:...

Проверьте свойство причины, чтобы найти ошибку, из-за которой задание завершилось сбоем.

$job.ChildJobs[0].JobStateInfo.Reason

В этом случае задание завершилось ошибкой, так как удаленный компьютер требует явных учетных данных для выполнения команды. Свойство "Причина" содержит следующее сообщение:

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

См. также