从另一个PowerShell会话监视PowerShell会话中的作业

时间:2010-11-30 19:03:52

标签: powershell powershell-v2.0

脚本在循环中执行以下步骤,假设两个步骤都需要很长时间才能完成:

  1. $x = DoSomeWork;
  2. Start-Job -Name "Process $x" { DoSomeMoreWork $x; };
  3. 步骤1阻止脚本,当然步骤2没有。 我可以通过控制台轻松监控循环的进度/状态和步骤1.

    我还想做的是在批处理仍在执行时监控步骤2启动的作业的作业状态。

    通常,可以从另一个会话“附加”或查询另一个PowerShell会话吗? (假设监视会话没有产生工作者会话)

2 个答案:

答案 0 :(得分:4)

如果我关注你,那么你就无法在两个不同的控制台实例之间共享状态。也就是说,你想要的方式是不可能的。但是,您无法从同一会话中监视作业。您可以通过工作中的事件发出信号:

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

现在您可以选择使用Wait-Event [-SourceIdentifier Progress]Register-EngineEvent -SourceIdentifier Progress [-Action { ... }]或普通的交互式Get-Event来查看和/或处理来自同一会话的进度(或者如果您使用其他计算机)在远程服务器上启动了这项工作。)

如果在本地计算机上完成所有工作,那么完全有可能您不需要Jobs基础结构。在RunspaceFactory和PowerShell对象上查看我的一篇旧博客文章,获取基本脚本“threadpool”实现:

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

希望这有帮助,

-Oisin

答案 1 :(得分:2)

状态易于监控:

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

如果您不需要从函数中检索任何输出数据,那么您可以像这样写入输出:

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

如果您确实需要捕获输出,那么您可以使用我认为的进度流:

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