about_Remote_Jobs

Descripción breve

Describe cómo ejecutar trabajos en equipos remotos.

Descripción detallada

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.
  • BackgroundJob - Los comandos y scripts se ejecutan en un proceso independiente en la máquina local. Para más información, consulte about_Jobs (Acerca de los trabajos).
  • 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.

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. Consulte la sección Procesos desasociados de este artículo.
  2. Use Start-Process para crear un nuevo proceso en lugar de un trabajo. Para obtener más información, vea Start-Process.

Trabajos remotos

Puede ejecutar trabajos en equipos remotos mediante tres métodos diferentes.

  • Inicie una sesión interactiva en un equipo remoto. A continuación, inicie un trabajo en la sesión interactiva. Los procedimientos son los mismos que ejecutar un trabajo local, aunque todas las acciones se realizan en el equipo remoto.

  • Ejecute un trabajo en un equipo remoto que devuelva sus resultados al equipo local. Use este método cuando quiera recopilar los resultados de los trabajos y mantenerlos en una ubicación central en el equipo local.

  • Ejecute un trabajo en un equipo remoto que mantenga sus resultados en el equipo remoto. Use este método cuando los datos del trabajo se mantengan de forma más segura en el equipo de origen.

Inicio de un trabajo en una sesión interactiva

Puede iniciar una sesión interactiva con un equipo remoto y, a continuación, iniciar un trabajo durante la sesión interactiva. Para obtener más información sobre las sesiones interactivas, consulte about_Remote y vea Enter-PSSession.

El procedimiento para iniciar un trabajo en una sesión interactiva es casi idéntico al procedimiento para iniciar un trabajo en segundo plano en el equipo local. Sin embargo, todas las operaciones se producen en el equipo remoto, no en el equipo local.

  1. Use el Enter-PSSession cmdlet para iniciar una sesión interactiva con un equipo remoto. Puede usar el parámetro ComputerName de Enter-PSSession para establecer una conexión temporal para la sesión interactiva. O bien, puede usar el parámetro Session para ejecutar la sesión interactiva en una sesión de PowerShell (PSSession).

    El comando siguiente inicia una sesión interactiva en el equipo Server01.

    C:\PS> Enter-PSSession -computername Server01
    

    El símbolo del sistema cambia para mostrar que ahora está conectado al equipo Server01.

    Server01\C:>
    
  2. Para iniciar un trabajo remoto en la sesión, use el Start-Job cmdlet . El siguiente comando ejecuta un trabajo remoto que obtiene los eventos del registro de eventos de Windows PowerShell en el equipo Server01. El Start-Job cmdlet devuelve un objeto que representa el trabajo.

    Este comando guarda el objeto de trabajo en la $job variable .

    Server01\C:> $job = Start-Job -scriptblock {
      Get-Eventlog "Windows PowerShell"
    }
    

    Mientras se ejecuta el trabajo, puede usar la sesión interactiva para ejecutar otros comandos, incluidos otros trabajos. Sin embargo, debe mantener abierta la sesión interactiva hasta que se complete el trabajo. Si finaliza la sesión, se interrumpe el trabajo y se pierden los resultados.

  3. Para averiguar si el trabajo está completo, muestre el valor de la $job variable o use el Get-Job cmdlet para obtener el trabajo. El siguiente comando usa el Get-Job cmdlet para mostrar el trabajo.

    Server01\C:> Get-Job $job
    
    SessionId  Name  State      HasMoreData  Location   Command
    ---------  ----  -----      -----------  --------   -------
    1          Job1  Complete   True         localhost  Get-Eventlog "Windows...
    

    La Get-Job salida muestra que el trabajo se ejecuta en el equipo "localhost" porque el trabajo se inició y se ejecuta en el mismo equipo (en este caso, Server01).

  4. Para obtener los resultados del trabajo, use el Receive-Job cmdlet . Puede mostrar los resultados en la sesión interactiva o guardarlos en un archivo en el equipo remoto. El comando siguiente obtiene los resultados del trabajo en la variable $job. El comando usa el operador de redireccionamiento (>) para guardar los resultados del trabajo en el archivo PsLog.txt en el equipo Server01.

    Server01\C:> Receive-Job $job > c:\logs\PsLog.txt
    
  5. Para finalizar la sesión interactiva, use el Exit-PSSession cmdlet . El símbolo del sistema cambia para mostrar que vuelve a la sesión original en el equipo local.

    Server01\C:> Exit-PSSession
    C:\PS>
    
  6. Para ver el contenido del PsLog.txt archivo en el equipo Server01 en cualquier momento, inicie otra sesión interactiva o ejecute un comando remoto. Este tipo de comando se ejecuta mejor en una PSSession (una conexión persistente) en caso de que quiera usar varios comandos para investigar y administrar los datos en el PsLog.txt archivo. Para obtener más información sobre PSSessions, consulte about_PSSessions.

    Los siguientes comandos usan el New-PSSession cmdlet para crear una PSSession conectada al equipo Server01 y usan el Invoke-Command cmdlet para ejecutar un Get-Content comando en PSSession para ver el contenido del archivo.

    $s = New-PSSession -computername Server01
    Invoke-Command -session $s -scriptblock {
      Get-Content c:\logs\pslog.txt}
    

Inicie un trabajo remoto que devuelva los resultados al equipo local (AsJob)

Para iniciar un trabajo en un equipo remoto que devuelva los resultados del comando al equipo local, use el parámetro AsJob de un cmdlet como el Invoke-Command cmdlet .

Cuando se usa el parámetro AsJob , el objeto de trabajo se crea realmente en el equipo local aunque el trabajo se ejecute en el equipo remoto. Cuando se completa el trabajo, los resultados se devuelven al equipo local.

Puede usar los cmdlets que contienen el nombre job (los cmdlets job) para administrar cualquier trabajo creado por cualquier cmdlet. Muchos de los cmdlets que tienen parámetros asJob no usan la comunicación remota de PowerShell, por lo que puede usarlos incluso en equipos que no están configurados para la comunicación remota y que no cumplen los requisitos para la comunicación remota.

  1. El comando siguiente usa el parámetro AsJob de Invoke-Command para iniciar un trabajo en el equipo Server01. El trabajo ejecuta un Get-Eventlog comando que obtiene los eventos en el registro del sistema. Puede usar el parámetro JobName para asignar un nombre para mostrar al trabajo.

    Invoke-Command -computername Server01 -scriptblock {
      Get-Eventlog system} -AsJob
    

    Los resultados del comando se asemejan a la siguiente salida de ejemplo.

    SessionId   Name   State    HasMoreData   Location   Command
    ---------   ----   -----    -----------   --------   -------
    1           Job1   Running  True          Server01   Get-Eventlog system
    

    Cuando se usa el parámetro AsJob , Invoke-Command devuelve el mismo tipo de objeto de trabajo que Start-Job devuelve. Puede guardar el objeto de trabajo en una variable o puede usar un Get-Job comando para obtener el trabajo.

    Tenga en cuenta que el valor de la propiedad Location muestra que el trabajo se ejecutó en el equipo Server01.

  2. Para administrar un trabajo iniciado mediante el parámetro AsJob del Invoke-Command cmdlet , use los cmdlets job. Dado que el objeto de trabajo que representa el trabajo remoto está en el equipo local, no es necesario ejecutar comandos remotos para administrar el trabajo.

    Para determinar si el trabajo está completo, use un Get-Job comando . El comando siguiente obtiene todos los trabajos que se iniciaron en la sesión actual.

    Get-Job
    

    Dado que el trabajo remoto se inició en la sesión actual, un comando local Get-Job obtiene el trabajo. La propiedad State del objeto de trabajo muestra que el comando se completó correctamente.

    SessionId   Name   State      HasMoreData   Location   Command
    ---------   ----   -----      -----------   --------   -------
    1           Job1   Completed  True          Server01   Get-Eventlog system
    
  3. Para obtener los resultados del trabajo, use el Receive-Job cmdlet . Dado que los resultados del trabajo se devuelven automáticamente al equipo donde reside el objeto de trabajo, puede obtener los resultados con un comando local Receive-Job .

    El siguiente comando usa el Receive-Job cmdlet para obtener los resultados del trabajo. Usa el identificador de sesión para identificar el trabajo. Este comando guarda los resultados del trabajo en la variable $results. También puede redirigir los resultados a un archivo.

    $results = Receive-Job -id 1
    

Iniciar un trabajo remoto que mantenga los resultados en el equipo remoto

Para iniciar un trabajo en un equipo remoto que mantiene los resultados del comando en el equipo remoto, use el Invoke-Command cmdlet para ejecutar un Start-Job comando en un equipo remoto. Puede usar este método para ejecutar trabajos en varios equipos.

Cuando se ejecuta un Start-Job comando de forma remota, el objeto de trabajo se crea en el equipo remoto y los resultados del trabajo se mantienen en el equipo remoto. Desde la perspectiva del trabajo, todas las operaciones son locales. Solo está ejecutando comandos de forma remota para administrar un trabajo local en el equipo remoto.

  1. Use el Invoke-Command cmdlet para ejecutar un Start-Job comando en un equipo remoto.

    Este comando requiere una PSSession (una conexión persistente). Si usa el parámetro ComputerName de Invoke-Command para establecer una conexión temporal, el Invoke-Command comando se considera completado cuando se devuelve el objeto de trabajo. Como resultado, se cierra la conexión temporal y se cancela el trabajo.

    El siguiente comando usa el New-PSSession cmdlet para crear una PSSession que esté conectada al equipo Server01. El comando guarda la PSSession en la $s variable .

    $s = New-PSSession -computername Server01
    

    El siguiente comando usa el Invoke-Command cmdlet para ejecutar un Start-Job comando en PSSession. El Start-Job comando y el Get-Eventlog comando se incluyen entre llaves.

    Invoke-Command -session $s -scriptblock {
      Start-Job -scriptblock {Get-Eventlog system}}
    

    Los resultados se asemejan a la siguiente salida de ejemplo.

    Id       Name    State      HasMoreData     Location   Command
    --       ----    -----      -----------     --------   -------
    2        Job2    Running    True            Localhost  Get-Eventlog system
    

    Al ejecutar un Start-Job comando de forma remota, Invoke-Command devuelve el mismo tipo de objeto de trabajo que Start-Job devuelve. Puede guardar el objeto de trabajo en una variable o puede usar un Get-Job comando para obtener el trabajo.

    Tenga en cuenta que el valor de la propiedad Location muestra que el trabajo se ejecutó en el equipo local, conocido como "LocalHost", aunque el trabajo se ejecutó en el equipo Server01. Dado que el objeto de trabajo se crea en el equipo Server01 y el trabajo se ejecuta en el mismo equipo, se considera que es un trabajo en segundo plano local.

  2. Para administrar un trabajo remoto, use los cmdlets job . Dado que el objeto de trabajo está en el equipo remoto, debe ejecutar comandos remotos para obtener, detener, esperar o recuperar los resultados del trabajo.

    Para ver si el trabajo está completo, use un Invoke-Command comando para ejecutar un Get-Job comando en la PSSession que está conectada al equipo Server01.

    Invoke-Command -session $s -scriptblock {Get-Job}
    

    El comando devuelve un objeto de trabajo. La propiedad State del objeto de trabajo muestra que el comando se completó correctamente.

    SessionId   Name  State      HasMoreData   Location   Command
    ---------   ----  -----      -----------   --------   -------
    2           Job2  Completed  True          LocalHost   Get-Eventlog system
    
  3. Para obtener los resultados del trabajo, use el Invoke-Command cmdlet para ejecutar un Receive-Job comando en la PSSession que está conectada al equipo Server01.

    El siguiente comando usa el Receive-Job cmdlet para obtener los resultados del trabajo. Usa el identificador de sesión para identificar el trabajo. Este comando guarda los resultados del trabajo en la $results variable . Usa el parámetro Keep de Receive-Job para mantener el resultado en la memoria caché del trabajo en el equipo remoto.

    $results = Invoke-Command -session $s -scriptblock {
      Receive-Job -SessionId 2 -Keep
    }
    

    También puede redirigir los resultados a un archivo en el equipo local o remoto. El siguiente comando usa un operador de redireccionamiento para guardar los resultados en un archivo en el equipo Server01.

    Invoke-Command -session $s -command {
      Receive-Job -SessionId 2 > c:\logs\pslog.txt
    }
    

Ejecución como un proceso desasociado

Como se mencionó anteriormente, cuando finaliza la sesión primaria, todos los trabajos secundarios en ejecución se finalizan junto con sus procesos secundarios. Puede usar la comunicación remota en el equipo local para ejecutar trabajos que no están conectados a la sesión actual de PowerShell.

Cree una nueva sesión de PowerShell en el equipo local. Use Invoke-Command para iniciar un trabajo en esta sesión. Invoke-Command permite desconectar una sesión remota y finalizar la sesión primaria. Más adelante, puede iniciar una nueva sesión de PowerShell y conectarse a la sesión desconectada anteriormente para reanudar la supervisión del trabajo. Sin embargo, los datos que se devolvieron a la sesión original de PowerShell se pierden cuando se finaliza esa sesión. Solo se devuelven nuevos objetos de datos generados después de la desconexión cuando se vuelven a conectar.

# Create remote session on local machine
PS> $session = New-PSSession -cn localhost

# Start remote job
PS> $job = Invoke-Command -Session $session -ScriptBlock { 1..60 | % { sleep 1; "Output $_" } } -AsJob
PS> $job

Id     Name     PSJobTypeName   State         HasMoreData     Location      Command
--     ----     -------------   -----         -----------     --------      -------
1      Job1     RemoteJob       Running       True            localhost     1..60 | % { sleep 1; ...

# Disconnect the job session
PS> Disconnect-PSSession $session

Id Name         Transport ComputerName    ComputerType    State         ConfigurationName     Availability
-- ----         --------- ------------    ------------    -----         -----------------     ------------
1 Runspace1     WSMan     localhost       RemoteMachine   Disconnected  Microsoft.PowerShell          None

PS> $job

Id     Name     PSJobTypeName   State         HasMoreData     Location      Command
--     ----     -------------   -----         -----------     --------      -------
1      Job1     RemoteJob       Disconnected  True            localhost     1..60 | % { sleep 1;

# Reconnect the session to a new job object
PS> $jobNew = Receive-PSSession -Session $session -OutTarget Job
PS> $job | Wait-Job | Receive-Job
Output 9
Output 10
Output 11
...

En este ejemplo, los trabajos se siguen adjuntando a una sesión primaria de PowerShell. Sin embargo, la sesión primaria no es la sesión original de PowerShell donde Invoke-Command se ejecutó.

Consulte también