Can I use Start-Job inside a ScheduledJob at all?
Here's the story: I'm using PowerShell Remoting from inside of my app using .Net classes from System.Management.Automation
, Remoting, and Runspaces.
I run a script that creates a ScheduledJob on the remote host that does some basic stuff with Hyper-V, let's say, Restart-Vm
. The action itself performs as expected, just as though I had run it in the console on this remote host.
Although there is one difference - if I did put it to the console I would get the results of the operation immediately. For example, if the VM is Disabled I would receive 'The operation cannot be performed while the virtual machine is in its current state'. In case with SJs, when some SJ trigger gets activated and the SJ runs, I have no possibility to get the results of my Restart-Vm
command immediately after it has been received. Instead, I have to check up on the corresponding BackgroundJob that is created when the SJ gets triggered and check its state and receive its results. It's not OK because my application must write events of this kind to EventLog on the remote machine. Even if the Restart-Vm
operation does not succeed no exception gets thrown, and I can't obviously write to the EventLog in the body of my scheduled job.
I thought the solution could be something like this: create a new job inside the scheduled job, make this job perform the target action and bind a handler to the state change event of this job which would write to EventLog.
However, when I implement this
Start-Job -ScriptBlock { params($guid) Get-Vm $guid | Restart-Vm -Force; } -ArgumentList $id;
it fails. Here's how it happens: the SJ gets fired, the corresponding Job is created, I check its state - it is Completed and it HasMoreData
. When I do Receive-Job
I get this error
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
I've tried running the Restart-Vm
action with -AsJob
switch, passing credentials, but nothing works.
UPDATE 5 June, 2015
In fact, this problem has arisen from my need to catch exceptions thrown by Restart-Vm
. The fact I did not realize until recently was that I must specify either -ErrorAction Stop
or -ErrorVariable
parameters when calling Restart-Vm
, so that I can get a control over its execution. So there's no need in any hacks like nesting jobs anymore.
After executing the statement $res = Get-Job | Receive-Job
The value of $res
is the output received from the job. That output is not a job that could be fed into Receive-Job
again.
Demonstration:
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...
You need to keep the job object (or its ID) if you want to receive multiple times:
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:\> _