Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Monitoring jobs in a PowerShell session from another PowerShell session

A script is executing the following steps in a loop, assume both steps take a long time to complete:

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

Step 1 blocks the script and step 2 does not, of course. I can easily monitor the progress/state of the loop and step 1 through the console.

What I'd also like to do is monitor the job status of jobs started by step 2 while the batch is still executing.

In general, it is possible to 'attach' or query another powershell session from another session? (Assuming the monitoring session does not spawn the worker session)

like image 461
Serguei Avatar asked Nov 30 '10 19:11

Serguei


2 Answers

If I'm following you, then you cannot share state between two different console instances. That is to say, it's not possible in the way you want to do it. However, it's not true that you cannot monitor a job from the same session. You can signal with events from within the job:

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

Now you have the choice to either use Wait-Event [-SourceIdentifier Progress], Register-EngineEvent -SourceIdentifier Progress [-Action { ... }] or plain old interactive Get-Event to see and/or act on progress from the same session (or a different machine if you started the job on a remote server.)

It's also entirely possible you don't need the Jobs infrastructure if all work is being done on the local machine. Take a look at an old blog post of mine on the RunspaceFactory and PowerShell objects for a rudimentary script "threadpool" implementation:

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

Hope this helps,

-Oisin

like image 61
x0n Avatar answered Oct 16 '22 11:10

x0n


State is easy to monitor:

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

If you don't need to retrieve any output data from the function then you can write to output like so:

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

If you do need to capture the output, then you could use the progress stream I think:

$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 }
like image 32
Keith Hill Avatar answered Oct 16 '22 10:10

Keith Hill