A script is executing the following steps in a loop, assume both steps take a long time to complete:
$x = DoSomeWork;
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)
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
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 }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With