2015-05-28 2 views
0

Могу ли я использовать Start-Job внутри ScheduledJob?Не удается получить результат с работы

Вот история: Я использую PowerShell Remoting из моего приложения, используя классы .Net от System.Management.Automation, Remoting и Runspaces. Я запускаю скрипт, который создает ScheduledJob на удаленном хосте, который делает некоторые базовые вещи с Hyper-V, скажем, Restart-Vm. Само действие выполняется так, как ожидалось, так же, как если бы я запускал его в консоли на этом удаленном хосте.

Хотя есть одно отличие - если бы я положил его на консоль, я сразу получил бы результаты операции. Например, если виртуальная машина отключена, я бы получил: «Операция не может быть выполнена, пока виртуальная машина находится в ее текущем состоянии». В случае с SJ, когда запускается какой-либо SJ-триггер и запускается SJ, у меня нет возможности получить результаты моей команды Restart-Vm сразу же после ее получения. Вместо этого я должен проверить соответствующий BackgroundJob, который создается, когда SJ запускается, и проверяет его состояние и получает его результаты. Это не нормально, потому что мое приложение должно записывать события такого типа в EventLog на удаленном компьютере. Даже если операция Restart-Vm не удалась, никакое исключение не выбрасывается, и я не могу явно записать в EventLog в теле моей запланированной работы.

Я думал, что решение может быть примерно таким: создайте новое задание внутри запланированного задания, сделайте это задание выполнимым целевым действием и привяжите обработчик к событию изменения состояния этого задания, которое будет записываться в EventLog.

Однако, когда я реализую это

Start-Job -ScriptBlock { params($guid) Get-Vm $guid | Restart-Vm -Force; } -ArgumentList $id; 

он терпит неудачу. Вот как это происходит: SJ запускается, создается соответствующее задание, я проверяю его состояние - оно завершено и оно HasMoreData. Когда я Receive-Job я получаю эту ошибку

Receive-Job : Parameter set cannot be resolved using the specified named parameters. 
At line:1 char:8 
+ $res | receive-job 
+  ~~~~~~~~~~~ 
    + CategoryInfo   : InvalidArgument: (System.Manageme...n.PSRemotingJob:PSObject) [Receive-Job], ParameterBindingEx 
    ception 
    + FullyQualifiedErrorId : AmbiguousParameterSet,Microsoft.PowerShell.Commands.ReceiveJobCommand 

Я попытался запустить Restart-Vm действие с -AsJob переключателем, передавая полномочия, но ничего не работает.

UPDATE 5 июня 2015

На самом деле, эта проблема возникла из моей необходимости перехватывать исключения по Restart-Vm. Тот факт, что до недавнего времени я не понимал, что должен указывать либо -ErrorAction Stop, либо -ErrorVariable при вызове Restart-Vm, так что я могу получить контроль над его исполнением. Таким образом, нет необходимости в каких-либо хаках, таких как работа с гнездом больше.

+2

Как получить '$ res'? –

+0

$ res - это данные, полученные от задания, инициированного моей запланированной работой, и это тоже работа. Его состояние - «Бег». Я получаю его так: $ res = Get-Job | Receive-Job.И я убеждаюсь, что Get-Job - это только одна работа, которая только что началась. –

+1

Я не думаю, что вы можете «Получить-Job» дважды –

ответ

1

После выполнения заявления $res = Get-Job | Receive-Job Значение $res является результатом , полученным от работы. Этот результат не является вакансии, который может быть снова отправлен в Receive-Job.

Демонстрация:

PS C:\>Start-Job -ScriptBlock { 'foo' } 

Id Name PSJobTypeName State HasMoreData Location Command 
-- ---- ------------- ----- ----------- -------- ------- 
6 Job6 BackgroundJob Running True   localhost 'foo' 

PS C:\>$res = Get-Job | Receive-Job 
PS C:\>$res 
foo 
PS C:\>$res | Receive-Job 
Receive-Job : The input object cannot be bound to any parameters for the command 
either because the command does not take pipeline input or the input and its 
properties do not match any of the parameters that take pipeline input. 
At line:1 char:8 
+ $res | Receive-Job 
+  ~~~~~~~~~~~ 
    + CategoryInfo   : InvalidArgument: (foo:PSObject) [Receive-Job], ... 
    + FullyQualifiedErrorId : InputObjectNotBound,Microsoft.PowerShell.Comman...

Вы должны сохранить объект задания (или его идентификатор), если вы хотите получить несколько раз:

PS C:\>$job = Start-Job -ScriptBlock { 'foo' } 
PS C:\>$job | Receive-Job 
foo 
PS C:\>$job | Receive-Job 
PS C:\>Get-Job -Id $job.Id | Receive-Job 
PS C:\> _
+0

Хорошо, спасибо, так что, похоже, нужно отказаться от идеи такого эзотерического лова завершения работы. –

+0

@VarvaraKalinina Используйте ['Wait-Job'] (https://technet.microsoft.com/en-us/library/hh849735.aspx), если вы хотите дождаться завершения задания. –

+0

Да, я бы сделал, как вы говорите, если еще есть необходимость в этом, см. Мое обновление для сообщения. Больше нет необходимости в вложенных работах. –

Смежные вопросы