about_Jobs

Breve descrição

Fornece informações sobre como os trabalhos em segundo plano do PowerShell executam um comando ou expressão em segundo plano sem interagir com a sessão atual.

Descrição longa

O PowerShell executa comandos e scripts simultaneamente por meio de trabalhos. Há três tipos de trabalhos fornecidos pelo PowerShell para dar suporte à simultaneidade.

  • RemoteJob - Comandos e scripts são executados em uma sessão remota. Para obter informações, consulte about_Remote_Jobs.
  • BackgroundJob - Comandos e scripts são executados em um processo separado na máquina local.
  • PSTaskJob ou ThreadJob - Comandos e scripts são executados em um thread separado dentro do mesmo processo na máquina local. Para obter mais informações, consulte about_Thread_Jobs.

A execução de scripts remotamente, em uma máquina separada ou em um processo separado, proporciona um ótimo isolamento. Quaisquer erros que ocorram no trabalho remoto não afetam outros trabalhos em execução ou a sessão pai que iniciou o trabalho. No entanto, a camada de comunicação remota adiciona sobrecarga, incluindo serialização de objeto. Todos os objetos são serializados e desserializados à medida que são passados entre a sessão pai e a sessão remota (trabalho). A serialização de grandes objetos de dados complexos pode consumir grandes quantidades de recursos de computação e memória e transferir grandes quantidades de dados pela rede.

Os trabalhos baseados em threads não são tão robustos quanto os remotos e em segundo plano, porque são executados no mesmo processo em threads diferentes. Se um trabalho tiver um erro crítico que trave o processo, todos os outros trabalhos no processo serão encerrados.

No entanto, trabalhos baseados em threads exigem menos sobrecarga. Eles não usam a camada de comunicação remota ou serialização. Os objetos de resultado são retornados como referências a objetos dinâmicos na sessão atual. Sem essa sobrecarga, os trabalhos baseados em threads são executados mais rapidamente e usam menos recursos do que os outros tipos de trabalho.

Importante

A sessão pai que criou o trabalho também monitora o status do trabalho e coleta dados de pipeline. O processo filho do trabalho é encerrado pelo processo pai assim que o trabalho atinge um estado concluído. Se a sessão pai for encerrada, todos os trabalhos filho em execução serão encerrados juntamente com seus processos filho.

Há duas maneiras de contornar essa situação:

  1. Use Invoke-Command para criar trabalhos que são executados em sessões desconectadas. Para obter mais informações, consulte about_Remote_Jobs.
  2. Use Start-Process para criar um novo processo em vez de um trabalho. Para obter mais informações, consulte Start-Process.

Os cmdlets de trabalho

  • Start-Job - Inicia um trabalho em segundo plano em um computador local.
  • Get-Job - Obtém os trabalhos em segundo plano que foram iniciados na sessão atual.
  • Receive-Job - Obtém os resultados de trabalhos em segundo plano.
  • Stop-Job - Interrompe um trabalho em segundo plano.
  • Wait-Job - Suprime o prompt de comando até que um ou todos os trabalhos sejam concluídos.
  • Remove-Job - Exclui um trabalho em segundo plano.
  • Invoke-Command - O parâmetro AsJob cria um trabalho em segundo plano em um computador remoto. Você pode usar Invoke-Command para executar qualquer comando de trabalho remotamente, incluindo Start-Job.

Como iniciar um trabalho no computador local

Para iniciar um trabalho em segundo plano no computador local, use o Start-Job cmdlet.

Para escrever um Start-Job comando, coloque o comando de que o trabalho é executado em chaves ({}). Use o parâmetro ScriptBlock para especificar o comando.

O comando a seguir inicia um trabalho em segundo plano que executa um Get-Process comando no computador local.

Start-Job -ScriptBlock {Get-Process}

Quando você inicia um trabalho em segundo plano, o prompt de comando retorna imediatamente, mesmo que o trabalho demore muito tempo para ser concluído. Você pode continuar a trabalhar na sessão sem interrupção enquanto o trabalho é executado.

O Start-Job comando retorna um objeto que representa o trabalho. O objeto de trabalho contém informações úteis sobre o trabalho, mas não contém os resultados do trabalho.

Você pode salvar o objeto de trabalho em uma variável e, em seguida, usá-lo com os outros cmdlets Job para gerenciar o trabalho em segundo plano. O comando a seguir inicia um objeto de trabalho e salva o objeto de trabalho resultante na $job variável.

$job = Start-Job -ScriptBlock {Get-Process}

A partir do PowerShell 6.0, você pode usar o operador em segundo plano (&) no final de um pipeline para iniciar um trabalho em segundo plano. Para obter mais informações, consulte operador em segundo plano.

Usar o operador em segundo plano é funcionalmente equivalente ao uso do Start-Job cmdlet no exemplo anterior.

$job = Get-Process &

Obter objetos de trabalho

O Get-Job cmdlet retorna objetos que representam os trabalhos em segundo plano que foram iniciados na sessão atual. Sem parâmetros, Get-Job retorna todos os trabalhos que foram iniciados na sessão atual.

Get-Job

O objeto de trabalho contém o estado do trabalho, que indica se o trabalho foi concluído. Um trabalho concluído tem um estado de Concluído ou Reprovado. Um trabalho também pode estar bloqueado ou em execução.

Id  Name  PSJobTypeName State      HasMoreData  Location   Command
--  ----  ------------- -----      -----------  --------   -------
1   Job1  BackgroundJob Complete   True         localhost  Get-Process

Você pode salvar o objeto de trabalho em uma variável e usá-lo para representar o trabalho em um comando posterior. O comando a seguir obtém o trabalho com ID 1 e o salva na $job variável.

$job = Get-Job -Id 1

Obter os resultados de um trabalho

Quando você executa um trabalho em segundo plano, os resultados não aparecem imediatamente. Para obter os resultados de um trabalho em segundo plano, use o Receive-Job cmdlet.

No exemplo a seguir, o Receive-Job cmdlet obtém os resultados do trabalho usando o objeto job na $job variável.

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

Você pode salvar os resultados de um trabalho em uma variável. O comando a seguir salva os resultados do trabalho na $job variável para a $results variável.

$results = Receive-Job -Job $job

Obter e manter resultados parciais do trabalho

O Receive-Job cmdlet obtém os resultados de um trabalho em segundo plano. Se o trabalho estiver concluído, Receive-Job obterá todos os resultados do trabalho. Se o trabalho ainda estiver em execução, Receive-Job obtém os resultados que foram gerados até agora. Você pode executar Receive-Job comandos novamente para obter os resultados restantes.

Por padrão, Receive-Job exclui os resultados do cache onde os resultados do trabalho são armazenados. Quando você corre Receive-Job novamente, você obtém apenas os novos resultados que chegaram após a primeira execução.

Os comandos a seguir mostram os resultados dos comandos executados antes da conclusão do Receive-Job trabalho.

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

Use o parâmetro Keep para impedir Receive-Job a exclusão dos resultados do trabalho retornados. Os comandos a seguir mostram o efeito do uso do parâmetro Keep em um trabalho que ainda não foi concluído.

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

À espera dos resultados

Se você executar um comando que leva muito tempo para ser concluído, poderá usar as propriedades do objeto de trabalho para determinar quando o trabalho será concluído. O comando a seguir usa o Get-Job objeto para obter todos os trabalhos em segundo plano na sessão atual.

Get-Job

Os resultados aparecem numa tabela. O status do trabalho aparece na coluna Estado .

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

Neste caso, a propriedade do Estado revela que o Job 2 ainda está em execução. Se você usasse o Receive-Job cmdlet para obter os resultados do trabalho agora, os resultados seriam incompletos. Você pode usar o Receive-Job cmdlet repetidamente para obter todos os resultados. Use a propriedade State para determinar quando o trabalho será concluído.

Você também pode usar o parâmetro Wait do Receive-Job cmdlet. Quando usar esse parâmetro, o cmdlet não retorna o prompt de comando até que o trabalho seja concluído e todos os resultados estejam disponíveis.

Você também pode usar o Wait-Job cmdlet para aguardar qualquer um ou todos os resultados do trabalho. Wait-Job permite aguardar por um ou mais trabalhos específicos ou por todos os trabalhos. O comando a seguir usa o Wait-Job cmdlet para aguardar um trabalho com ID 10.

Wait-Job -ID 10

Como resultado, o prompt do PowerShell é suprimido até que o trabalho seja concluído.

Você também pode esperar por um período de tempo predeterminado. Este comando usa o parâmetro Timeout para limitar a espera a 120 segundos. Quando o tempo expira, o prompt de comando retorna, mas o trabalho continua a ser executado em segundo plano.

Wait-Job -ID 10 -Timeout 120

Parar um trabalho

Para interromper um trabalho em segundo plano, use o Stop-Job cmdlet. O comando a seguir inicia um trabalho para obter todas as entradas no log de eventos do sistema. Ele salva o objeto de trabalho na $job variável.

$job = Start-Job -ScriptBlock {Get-EventLog -Log System}

O comando a seguir interrompe o trabalho. Ele usa um operador de pipeline (|) para enviar o trabalho na $job variável para Stop-Job.

$job | Stop-Job

Excluir um trabalho

Para excluir um trabalho em segundo plano, use o Remove-Job cmdlet. O comando a seguir exclui o trabalho na $job variável.

Remove-Job -Job $job

Investigando um trabalho com falha

Os trabalhos podem falhar por muitas razões. o objeto job contém uma propriedade Reason que contém informações sobre a causa da falha.

O exemplo a seguir inicia um trabalho sem as credenciais necessárias.

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

Inspecione a propriedade Reason para localizar o erro que causou a falha do trabalho.

$job.ChildJobs[0].JobStateInfo.Reason

Nesse caso, o trabalho falhou porque o computador remoto exigiu credenciais explícitas para executar o comando. A propriedade Reason contém a seguinte mensagem:

A ligação ao servidor remoto falhou com a seguinte mensagem de erro: "Acesso negado".

Consulte também