2010-11-30 78 views
7

一个脚本执行在一个循环中执行以下步骤监视作业的PowerShell会话,假设这两个步骤需要很长的时间才能完成:从另一个PowerShell会话

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

第1步阻止脚本,第2步当然不会。 我可以通过控制台轻松地监视循环的进度/状态和步骤1。

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

通常,可以从另一个会话“附加”或查询另一个PowerShell会话? (假设监控会话不产卵工人会话)

+1

你是一个在你的例子中使用方法调用语法的坏男孩。 PowerShell函数不使用圆括号,并且在v2中的严格模式解析下出现分析错误(默认情况下,该函数未打开。) – x0n 2010-12-01 02:38:47

+0

@ x0n,nice catch!在我的辩护中,我最初调用.NET对象上的方法,但决定在示例中简化(以正确性为代价!)=) – Serguei 2010-12-01 02:44:45

+0

Np,我已在下面为您解答。 – x0n 2010-12-01 02:57:37

回答

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从同一个会话(或在不同的机器看到和/或行为上的进步如果您在远程服务器上启动作业)。

如果在本地计算机上完成所有工作,则完全可能不需要作业基础结构。看看我的老博客帖子上RunspaceFactory和PowerShell对象进行一个初步的剧本“线程池”的实施:

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

希望这有助于

-Oisin

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 }