2010-11-30 16 views
7

Una secuencia de comandos se ejecuta los siguientes pasos en un bucle, asumir ambos pasos tardan mucho tiempo en completarse:monitoreo de trabajos en una sesión de PowerShell desde otra sesión de PowerShell

  1. $x = DoSomeWork;
  2. Start-Job -Name "Process $x" { DoSomeMoreWork $x; };

El paso 1 bloquea el script y el paso 2 no, por supuesto. Puedo controlar fácilmente el progreso/estado del ciclo y el paso 1 a través de la consola.

Lo que también me gustaría hacer es supervisar el estado de trabajo de los trabajos iniciados en el paso 2 mientras el lote todavía se está ejecutando.

En general, ¿es posible "adjuntar" o consultar otra sesión de powershell desde otra sesión? (Suponiendo que la sesión de supervisión no desova la sesión de trabajo)

+1

You es una chico malo usando la sintaxis de llamada de método en tu ejemplo. Las funciones de PowerShell no usan paréntesis y son un error de análisis en el modo estricto de análisis en v2 (que no está activado de manera predeterminada). – x0n

+0

@ x0n, buen truco. En mi defensa, originalmente estaba invocando los métodos en objetos .NET, pero decidí simplificar en el ejemplo (¡a costa de la corrección!) =) – Serguei

+0

Np, y he respondido a continuación para usted. – x0n

Respuesta

4

Si te sigo, no puedes compartir el estado entre dos instancias de consola diferentes. Es decir, no es posible en la forma en que quieres hacerlo. Sin embargo, no es cierto que no pueda supervisar un trabajo de la misma sesión. Se puede señalar con eventos desde dentro del empleo:

Start-Job -Name "bgsignal" -ScriptBlock { 

    # forward events named "progress" back to job owner 
    # this even works across machines ;-) 
    Register-EngineEvent -SourceIdentifier Progress -Forward 

    $percent = 0 
    while ($percent -lt 100) { 
     $percent += 10 

     # raise a new progress event, redirecting to $null to prevent 
     # it ending up in the job's output stream 
     New-Event -SourceIdentifier Progress -MessageData $percent > $null 

     # wait 5 seconds 
     sleep -Seconds 5 
    } 
} 

Ahora usted tiene la opción de o bien utilizar Wait-Event [-SourceIdentifier Progress], Register-EngineEvent -SourceIdentifier Progress [-Action { ... }] o el viejo y simple interactiva Get-Event para ver y/o actuar sobre el progreso de la misma sesión (o una máquina diferente si comenzó el trabajo en un servidor remoto)

También es muy posible que no necesite la infraestructura de Jobs si todo el trabajo se realiza en la máquina local. Echar un vistazo a una vieja entrada del blog de la mina en la RunspaceFactory y objetos PowerShell para un script rudimentaria "subprocesos" aplicación:

http://www.nivot.org/2009/01/22/CTP3TheRunspaceFactoryAndPowerShellAccelerators.aspx

Espero que esto ayude,

-Oisin

+0

Gracias por recordarme que tengo que leer su publicación. Aún en la cola 'para leer', aumentará la prioridad :) – stej

2

Estado es fácil de controlar:

$job = Start-Job -Name "Process $x" { DoSomeMoreWork $x } 
$job.state 

Si no es necesario recuperar los datos de salida de la función entonces se puede escribir en la salida como por lo que:

$job = Start-Job {$i=0; while (1) { "Step $i"; $i++; Start-Sleep -sec 1 }} 
while ($job.State -eq 'Running') 
{ 
    Receive-Job $job.id 
} 

Si necesita capturar la salida, entonces se podría utilizar la corriente de los progresos que pienso:

$job = Start-Job {$i=0; while (1) { 
        Write-Progress Activity "Step $i"; $i++; Start-Sleep -sec 1 }} 
while ($job.State -eq 'Running') { 
    $progress=$job.ChildJobs[0].progress; 
    $progress | %{$_.StatusDescription}; 
    $progress.Clear(); Start-Sleep 1 } 
+1

Sí, pero el quid de la cuestión es cómo llenar la variable $ job de otra sesión de powershell. (por ejemplo, otra ventana de Powershell) No puedo supervisar el estado de la misma sesión porque está bloqueado por la ejecución de {$ x = DoSomeWork();} de la siguiente iteración. – Serguei

Cuestiones relacionadas