Monitoring jobs in a PowerShell session from another PowerShell session

◇◆丶佛笑我妖孽 提交于 2019-11-28 03:27:16

问题


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)


回答1:


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




回答2:


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 }


来源:https://stackoverflow.com/questions/4317438/monitoring-jobs-in-a-powershell-session-from-another-powershell-session

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!