PowerShell Invoke-Command supports three different ways to run commands and scripts in remote sessions. You can use the -InDisconnectedSession parameter, the -AsJob parameter, or the Start-Job cmdlet. I will discuss these three options and explain the differences.

-InDisconnectedSession ^

The example at the end of my previous post illustrated how you can receive the results from a task running in a remote computer from an interactive session. If you want to read the results in a script, you could do it like this:

Invoke-Command -ComputerName $RemoteComputer -ScriptBlock {Get-Process} -InDisconnectedSession -SessionName mySession
$Job = Receive-PSSession -ComputerName $RemoteComputer -Name mySession
$Result = Receive-Job -Job $Job

Adding the -ComputerName parameter has the same effect as using -OutTarget Job—that is, Receive-PSSession returns a job object instead of passing the results to the host application. It is interesting to note that the returned job object is not serialized. In my post about Invoke-Command, I mentioned that that the cmdlet returns only static objects that lack all interesting methods. This does not apply to Receive-PSSession.

In the above example, the job object will be created in your current session. Thus, you can apply the background job cmdlets and you can use the job’s methods. For instance, Get-Job will list the job in your current session, and you can stop the job with $Job.StopJob().

However, you should be aware that only the job object will reside in your current session. The commands that the job executes are still running on the remote computer. The moment you load the job object with Receive-PSSession into your current session, the job will automatically transfer all data that the commands on the remote computer produce to the job object in your current session.

The next example demonstrates what consequences this can have (be careful because your host might hang):

Invoke-Command -ComputerName $RemoteComputer -ScriptBlock {for ($i = 1..1000) {$i}} -InDisconnectedSession -SessionName mySession
$Job = Receive-PSSession -ComputerName $RemoteComputer -Name mySession
Receive-Job -Job $Job

Receiving job results of a disconnected session

Receiving job results of a disconnected session

If you are testing in a virtual environment, you will notice that your virtual NIC will suddenly blink like wild while the output of the remote job is crawling over your screen. The CPU load on your test machine should also be noticeable. Thus, be careful before you load job objects that are connected to remote sessions into your current session.

-AsJob ^

Let’s have a look at the second method I mentioned in the beginning. The -AsJob parameter of Invoke-Command works a little differently from -InDisconnectedSession:

Invoke-Command -ComputerName $RemoteComputer -ScriptBlock {Get-Process} -AsJob -JobName myJob

In contrast to the method with -InDisconnectedSession, the job object is created in your current session right from the beginning. Thus, you can work with it like a normal background job. But you also have to keep in mind that you are dealing with a remote job. Just as with the -InDisconnectedSession parameter, the remote machine will send all output of your commands to the job object in your current session.

Using the -AsJob parameter

Using the -AsJob parameter

Start-Job ^

The third method to run a remote job behaves differently here:

$Session = New-PSSession -ComputerName $RemoteComputer
Invoke-Command -Session $Session -ScriptBlock {Start-Job -ScriptBlock {Get-Process} -Name myJob}

The New-PSSession cmdlet creates a PSSession on the remote machine, which we then fill with our job. Start-Job is usually used to create local background jobs. But, in combination with Invoke-Command, you can use it to create a remote job. The main difference between doing it this way and using the method with the -AsJob parameter is that the job object is created on the remote machine. This is why Get-Job delivers no results in the above example. Thus, if you want to retrieve the output of the job, you again need Invoke-Command to access the job object on the remote machine:

$Result = Invoke-Command -Session $Session -ScriptBlock {Receive-Job -Name myJob -Keep}

Executing a remote job with Start-Job

Executing a remote job with Start-Job

The -Keep parameter in the example ensures that the job result will stay on the remote machine after we collect it. This allows you to read the result a second time or from another machine.

The differences ^

The method with the -InDisconnectedSession parameter is different in that, whenever you collect your job result with Receive-PSSession, the output data is always removed from the remote session. However, you could keep the results in a local job object.

Another difference is that you need Invoke-Command to get the result, which always returns a serialized object. Thus, the -InDisconnectedSession method gives you more flexibility because it allows you to transfer a full-blown job object with all its methods to your current session. However, as demonstrated above, this can cause performance issues.

The method with Start-Job and the method with the -InDisconnectedSession parameter have one thing in common: you can easily access the job results from another machine where you launched the job.

Because the -AsJob parameter creates the job object in your local session, you can only access the job from the computer where you launched the job. This can also be an advantage if security is an issue. You should also take into account that, if you close your PowerShell console, the job is destroyed because its object lives in the current session. This won’t happen with the other two methods because their job objects live in PSSessions on the remote machine.

The table below summarizes the differences between the three methods. Note that “Start-Job” refers to the method in combination with Invoke-Command.

Original job object locationRemoteLocalRemote
Creates a serialized local job object when reading resultsNoNoYes
Results can be kept in the job object after retrievalLocalLocalRemote
Results can be accessed from other machinesYesNoYes
Object of uncompleted remote job is destroyed after originating console is closedNoYesNo

Please let me know if I missed a difference.

  1. ciril 5 years ago

    Great article! Makes things clear. Appreciate that!

  2. Renaud 5 years ago

    Thank you for this clear article. However I don’t understand the first sentence : “PowerShell Invoke-Command supports three different ways to run commands and scripts in disconnected remote sessions” ; shouldn’t we rather say “PowerShell Invoke-Command supports three different ways to run commands in background in remote sessions” ? If I understand well, the only case when session is disconnected is the first one (=with the “-InDisconnectedSession” parameter). In the second one (=”-Asjob”), if the connection to the remote server is lost (due to a network problem for instance). Am I right ?

    • Author
      Michael Pietroforte 5 years ago

      You are right, the sentence is a bit misleading. I removed “disconnected” from the sentence. The thing is, in theory if you start a remote session with -AsJob, you can lose the connection for up to 4 minutes. In practice, this will usually cause problems, in particular, if you run Receive-Job while the connection is broken. If you have an unstable internet connection to the remote host, -InDisconnectedSession is the better choice.

  3. Renaud 5 years ago

    I dropped the end of my last sentence sorry, I meant “In the second one (=”-Asjob”), if the connection to the remote server is lost (due to a network problem for instance), then the results of the command are lost

  4. Renaud 5 years ago

    @Michael Pietroforte : thank you for this update and for the additional information in your comment.

  5. Norbert 3 years ago

    Thank you for these explanations ! Very informative.

Leave a reply

Your email address will not be published.


© 4sysops 2006 - 2022


Please ask IT administration questions in the forums. Any other messages are welcome.


Log in with your credentials


Forgot your details?

Create Account