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

发布于 2024-10-05 05:30:35 字数 329 浏览 5 评论 0原文

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

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

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

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

一般来说,可以从另一个会话“附加”或查询另一个powershell会话吗? (假设监控会话不会产生工作会话)

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)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

你在看孤独的风景 2024-10-12 05:30:35

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

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

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

流年里的时光 2024-10-12 05:30:35

状态很容易监控:

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

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 }
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文