Отслеживание заданий в сеансе PowerShell из другого сеанса PowerShell
Сценарий выполняет следующие шаги в цикле, предположим, что оба шага занимают много времени:
$x = DoSomeWork;
Start-Job -Name "Process $x" { DoSomeMoreWork $x; };
Шаг 1 блокирует скрипт, а шаг 2, конечно, нет. Я могу легко контролировать ход / состояние цикла и шаг 1 через консоль.
Я также хотел бы отслеживать состояние заданий, запущенных на шаге 2, пока пакет еще выполняется.
В общем, можно "присоединить" или запросить другой сеанс powershell из другого сеанса? (Предполагая, что сеанс мониторинга не порождает рабочий сеанс)
2 ответа
Если я следую за вами, вы не можете разделить состояние между двумя разными экземплярами консоли. То есть, это не так, как вы хотите. Однако это не правда, что вы не можете контролировать работу из одного сеанса. Вы можете сигнализировать с событиями изнутри работы:
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
Состояние легко контролировать:
$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 }