“HasMoreData” is true even after Receive-Job


I create a simple background job in Powershell:

I check with Get-Job:

Next, I simply receive the output, and run Get-Job again

I can see that “HasMoreData” is now false, because I didn’t specify the -keep parameter.

HOWEVER: it seems that whenever I start a job, not with Start-Job or Invoke-Command, that this “HasMoreData” parameter does not change to False.


Can I bypass this (wrong) behaviour, so that the property HasMoreData switches to False, unless I specify -keep?


Update: it seems to be for all calls made with the -AsJob parameter. If you run

it works (“HasMoreData” becomes False after Receive-Job), but

does not.


Short answer:

It’s a bug in PowerShell 2.0.

It works fine for Blaine because he’s using PowerShell 3, I’d put money on it.

Long answer:

The Start-Job cmdlet and the -AsJob switch work differently. Documentation usually explains that Start-Job is intended to run background jobs locally whereas -AsJob is intended to start jobs with commands that run on remote computers but creates the job object locally. While that’s generally true, -AsJob can also be used to run jobs locally, and depending on the command, it’s sometimes not even capable of running the command on a remote computer. For example, Get-WMIObject invoked with -AsJob and -ComputerName runs the command on the specified remote computer, whereas Test-Connection invoked with -AsJob and -Computername runs the command locally and pings the specified computer.

I’ve also seen documentation that explains that Start-Job works by local IPC, whereas -AsJob makes a connection to the WinRM service of the specified computer, even if it’s the localhost, and that PSRemoting must be enabled on the local and target computer(s). Again, it’s not quite that straightforward. I’ve found that I can run jobs with the -AsJob switch on the localhost with WinRM and PSRemoting both disabled.

In any case, PowerShell starts jobs as one of two JobTypes, PSWmiJob or PSRemotingJob. This is counter-intuitive, because Start-Job, which runs background jobs locally, always creates a PSRemotingJob, whereas -AsJob usually creates a PSWmiJob, except when it’s used with Invoke-Command, which always starts a PSRemoting job regardless of whether the command is invoked on a remote computer or the localhost.

Take a look at the following session transcript, in which I created jobs in the varying ways. I tested with three commands: Get-WMIObject, which runs on a remote computer when invoked with -AsJob and ComputerName; Test-Connection, which always runs locally when invoked with -AsJob (-ComputerName specifies which computer to ping, not where to run the command); and Get-ChildItem, which doesn’t have an -AsJob parameter. I started jobs for each one using Start-Job, Invoke-Command -AsJob on both a remote computer and the local machine, and the native -AsJob switch (for commands that have it).

The purpose of the | %{$_.Name = '<the command preceding the pipe symbol>'} at the end of each command is to name each job as the command that created it, so it’s easier to see in the output which job corresponds to each command. It has no effect on the operation of the jobs, it just renames each job to a more meaningful name immediately after creating it.

What you’ll see is that after all the jobs are received (rcjb * 2>&1|Out-Null receives them all at once and suppresses output), the HasMoreData property of PSRemotingJob objects is set to False whether they were created by Start-Job or -AsJob, but the HasMoreData property of PSWmiJob objects remains True. Beyond the examples I’ve reproduced here, I’ve found that this holds true consistently.

Bottom line: The bug is in the PSWmiJob object. Regardless of which way the job was created, and regardless of whether the command runs locally or remotely, after a Receive-Job the HasMoreData property is set to False if the JobType is PSRemotingJob, but remains True if the JobType is PSWmiJob.

As far as I can tell, there is no way to set HasMoreData to False on a PSWmiJob. Stop-Job won’t do it, restarting WinRM won’t do it, and the property is read-only.


“HasMoreData” is true even after Receive-Job by licensed under CC BY-SA | With most appropriate answer!

Leave a Reply