about_Jobs

Descripción breve

Proporciona información sobre cómo los trabajos en segundo plano de PowerShell ejecutan un comando o expresión en segundo plano sin interactuar con la sesión actual.

Descripción larga

PowerShell ejecuta comandos y scripts simultáneamente a través de trabajos. PowerShell proporciona tres tipos de trabajos para admitir la simultaneidad.

  • RemoteJob - Los comandos y scripts se ejecutan en una sesión remota. Para obtener información, consulte about_Remote_Jobs.
  • BackgroundJob - Los comandos y scripts se ejecutan en un proceso independiente en la máquina local.
  • PSTaskJob o ThreadJob bien: los comandos y los scripts se ejecutan en un subproceso independiente dentro del mismo proceso en el equipo local. Para obtener más información, consulte about_Thread_Jobs.

La ejecución de scripts de forma remota, en una máquina independiente o en un proceso independiente, proporciona un gran aislamiento. Los errores que se producen en el trabajo remoto no afectan a otros trabajos en ejecución ni a la sesión primaria que inició el trabajo. Sin embargo, la capa de comunicación remota agrega sobrecarga, incluida la serialización de objetos. Todos los objetos se serializan y deserializan a medida que se pasan entre la sesión primaria y la sesión remota (trabajo). La serialización de objetos de datos complejos de gran tamaño puede consumir grandes cantidades de recursos de proceso y memoria y transferir grandes cantidades de datos a través de la red.

Los trabajos basados en subprocesos no son tan sólidos como trabajos remotos y en segundo plano, ya que se ejecutan en el mismo proceso en subprocesos diferentes. Si un trabajo tiene un error crítico que bloquea el proceso, se finalizan todos los demás trabajos del proceso.

Sin embargo, los trabajos basados en subprocesos requieren menos sobrecarga. No usan la capa de comunicación remota ni la serialización. Los objetos de resultado se devuelven como referencias a objetos activos en la sesión actual. Sin esta sobrecarga, los trabajos basados en subprocesos se ejecutan más rápido y usan menos recursos que los otros tipos de trabajo.

Importante

La sesión primaria que creó el trabajo también supervisa el estado del trabajo y recopila datos de canalización. El proceso primario finaliza el proceso secundario del trabajo una vez que el trabajo alcanza un estado finalizado. Si se finaliza la sesión primaria, todos los trabajos secundarios en ejecución finalizan junto con sus procesos secundarios.

Hay dos maneras de solucionar esta situación:

  1. Use Invoke-Command para crear trabajos que se ejecutan en sesiones desconectadas. Para obtener más información, consulte about_Remote_Jobs.
  2. Use Start-Process para crear un nuevo proceso en lugar de un trabajo. Para obtener más información, vea Start-Process.

Cmdlets de trabajo

  • Start-Job - Inicia un trabajo en segundo plano en un equipo local.
  • Get-Job : obtiene los trabajos en segundo plano que se iniciaron en la sesión actual.
  • Receive-Job : obtiene los resultados de los trabajos en segundo plano.
  • Stop-Job - Detiene un trabajo en segundo plano.
  • Wait-Job - Suprime el símbolo del sistema hasta que se completen uno o todos los trabajos.
  • Remove-Job - Elimina un trabajo en segundo plano.
  • Invoke-Command : el parámetro AsJob crea un trabajo en segundo plano en un equipo remoto. Puede usar Invoke-Command para ejecutar cualquier comando de trabajo de forma remota, incluido Start-Job.

Cómo iniciar un trabajo en el equipo local

Para iniciar un trabajo en segundo plano en el equipo local, use el Start-Job cmdlet .

Para escribir un Start-Job comando, incluya el comando que el trabajo ejecuta entre llaves ({}). Use el parámetro ScriptBlock para especificar el comando .

El siguiente comando inicia un trabajo en segundo plano que ejecuta un Get-Process comando en el equipo local.

Start-Job -ScriptBlock {Get-Process}

Cuando se inicia un trabajo en segundo plano, el símbolo del sistema se devuelve inmediatamente, incluso si el trabajo tarda un tiempo prolongado en completarse. Puede seguir trabajando en la sesión sin interrupción mientras se ejecuta el trabajo.

El Start-Job comando devuelve un objeto que representa el trabajo. El objeto de trabajo contiene información útil sobre el trabajo, pero no contiene los resultados del trabajo.

Puede guardar el objeto de trabajo en una variable y, a continuación, usarlo con los otros cmdlets job para administrar el trabajo en segundo plano. El siguiente comando inicia un objeto de trabajo y guarda el objeto de trabajo resultante en la $job variable .

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

A partir de PowerShell 6.0, puede usar el operador en segundo plano (&) al final de una canalización para iniciar un trabajo en segundo plano. Para obtener más información, vea operador en segundo plano.

El uso del operador en segundo plano es funcionalmente equivalente al uso del Start-Job cmdlet en el ejemplo anterior.

$job = Get-Process &

Obtención de objetos de trabajo

El Get-Job cmdlet devuelve objetos que representan los trabajos en segundo plano que se iniciaron en la sesión actual. Sin parámetros, Get-Job devuelve todos los trabajos que se iniciaron en la sesión actual.

Get-Job

El objeto de trabajo contiene el estado del trabajo, que indica si el trabajo ha finalizado. Un trabajo finalizado tiene un estado Completo o Erróneo. Un trabajo también puede estar bloqueado o en ejecución.

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

Puede guardar el objeto de trabajo en una variable y usarlo para representar el trabajo en un comando posterior. El siguiente comando obtiene el trabajo con el identificador 1 y lo guarda en la $job variable .

$job = Get-Job -Id 1

Obtención de los resultados de un trabajo

Al ejecutar un trabajo en segundo plano, los resultados no aparecen inmediatamente. Para obtener los resultados de un trabajo en segundo plano, use el Receive-Job cmdlet .

En el ejemplo siguiente, el Receive-Job cmdlet obtiene los resultados del trabajo mediante el objeto job en la $job variable .

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

Puede guardar los resultados de un trabajo en una variable. El comando siguiente guarda los resultados del trabajo en la $job variable en la $results variable .

$results = Receive-Job -Job $job

Obtención y mantenimiento de resultados de trabajos parciales

El Receive-Job cmdlet obtiene los resultados de un trabajo en segundo plano. Si el trabajo está completo, Receive-Job obtiene todos los resultados del trabajo. Si el trabajo sigue en ejecución, Receive-Job obtiene los resultados que se han generado hasta ahora. Puede volver a ejecutar Receive-Job comandos para obtener los resultados restantes.

De forma predeterminada, Receive-Job elimina los resultados de la memoria caché donde se almacenan los resultados del trabajo. Cuando vuelva a ejecutarse Receive-Job , obtendrá solo los nuevos resultados que llegaron después de la primera ejecución.

Los comandos siguientes muestran los resultados de los comandos ejecutados antes de Receive-Job que se complete el trabajo.

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 el parámetro Keep para evitar Receive-Job que elimine los resultados del trabajo que se devuelven. Los comandos siguientes muestran el efecto de usar el parámetro Keep en un trabajo que aún no se ha completado.

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

Esperando los resultados

Si ejecuta un comando que tarda mucho tiempo en completarse, puede usar las propiedades del objeto de trabajo para determinar cuándo se ha completado el trabajo. El siguiente comando usa el Get-Job objeto para obtener todos los trabajos en segundo plano de la sesión actual.

Get-Job

Los resultados aparecen en una tabla. El estado del trabajo aparece en la columna 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...

En este caso, la propiedad State revela que el trabajo 2 todavía se está ejecutando. Si usara el Receive-Job cmdlet para obtener los resultados del trabajo ahora, los resultados estarían incompletos. Puede usar el Receive-Job cmdlet repetidamente para obtener todos los resultados. Use la propiedad State para determinar cuándo se ha completado el trabajo.

También puede usar el parámetro Wait del Receive-Job cmdlet . Cuando se usa este parámetro, el cmdlet no devuelve el símbolo del sistema hasta que se completa el trabajo y todos los resultados están disponibles.

También puede usar el Wait-Job cmdlet para esperar cualquiera o todos los resultados del trabajo. Wait-Job permite esperar a uno o varios trabajos específicos o a todos los trabajos. El siguiente comando usa el cmdlet para esperar un trabajo con el Wait-Job identificador 10.

Wait-Job -ID 10

Como resultado, el símbolo del sistema de PowerShell se suprime hasta que se completa el trabajo.

También puede esperar un período predeterminado de tiempo. Este comando usa el parámetro Timeout para limitar la espera a 120 segundos. Cuando expire el tiempo, el símbolo del sistema devuelve, pero el trabajo continúa ejecutándose en segundo plano.

Wait-Job -ID 10 -Timeout 120

Detener un trabajo

Para detener un trabajo en segundo plano, use el Stop-Job cmdlet . El comando siguiente inicia un trabajo para obtener cada entrada en el registro de eventos del sistema. Guarda el objeto de trabajo en la $job variable .

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

El comando siguiente detiene el trabajo. Usa un operador de canalización (|) para enviar el trabajo de la $job variable a Stop-Job.

$job | Stop-Job

Eliminación de un trabajo

Para eliminar un trabajo en segundo plano, use el Remove-Job cmdlet . El siguiente comando elimina el trabajo de la $job variable .

Remove-Job -Job $job

Investigación de un trabajo con errores

Los trabajos pueden producir errores por muchas razones. el objeto de trabajo contiene una propiedad Reason que contiene información sobre la causa del error.

En el ejemplo siguiente se inicia un trabajo sin las credenciales necesarias.

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

Inspeccione la propiedad Reason para encontrar el error que provocó un error en el trabajo.

$job.ChildJobs[0].JobStateInfo.Reason

En este caso, se produjo un error en el trabajo porque el equipo remoto requería credenciales explícitas para ejecutar el comando . La propiedad Reason contiene el mensaje siguiente:

Conectar en el servidor remoto no se pudo realizar con el siguiente mensaje de error: "Acceso denegado".

Consulte también