• Skip to primary navigation
  • Skip to main content
  • Skip to footer

Stephanos Constantinou Blog

PowerShell Scripting

  • Home
  • Blogs
    • PowerShell Tutorials
    • PowerShell Scripts
    • PowerShell Modules
      • Modules Cmdlets
    • Software Reviews
  • About
  • Contact
You are here: Home / PowerShell Tutorials / PowerShell Jobs

PowerShell Jobs

06/09/2018 by Stephanos 2 Comments

PowerShell Jobs

In this tutorial we will see about PowerShell Jobs. Jobs in PowerShell are running in the background. When you start a background job in PowerShell, it will return immediately to the console. Background jobs run commands and expressions asynchronously. You are able to run cmdlets, functions, scripts and command-based tasks. Background jobs are designed to run commands that take long time to be completed, but you are allowed to run anything. Running commands in PowerShell, you run them synchronously. If the command is run synchronously the PowerShell command prompt is suppressed until the command that you run is completed. A background job does not suppresss the PowerShell prompt.

You are able to continue working in the same session until the background job will finish the job process. Results of the jobs are not provide automatically to the console. You will need to retrieve them manually when they are needed. We will see later in this post how we are able to achieve this. You can also run commands to stop the job, to wait for the job to be completed, and to delete the job. To make the timing of a background job independent of other commands, each background job runs in its own PowerShell environment (a “session”). However, this can be a temporary connection that is created only to run the job and is then destroyed, or it can be a persistent session (a PSSession) that you can use to run several related jobs or commands.

You are able to run background jobs on both local and remote computers. First we need to see the cmdlets that are related to PowerShell jobs in order to help us understand the next sections better.

PowerShell Jobs related cmdlets

Below we will see the cmdlets that are related to PowerShell Jobs along with its description as provided by Microsoft:

  • Start-Job – Starts a background job on a local computer.
  • Get-Job – Gets the background jobs that were started in the current session.
  • Receive-Job – Gets the results of background jobs.
  • Stop-Job – Stops a background job.
  • Wait-Job – Suppresses the command prompt until one or all jobs are complete.
  • Remove-Job – Deletes a background job.
  • Invoke-Command  – The AsJob parameter runs any command as a background job on a remote computer. You can also use Invoke-Command  to run any job command remotely, including a Start-Job  command.

[adinserter name=”In Article”]

Start a job on local computer

In order to be able to start a background job on our local computer we will need to use Start-Job cmdlet. The basic syntax of the command that we have to use is the below:

Code:

Start-Job -ScriptBlock {<Commands>}

When we will run the above command, a background job will be created. When we start a job, a job object is created and Start-Job returns the object to console. The object contains information about the job itself but it does not contain the results of the job.

In the examples below we are running Get-NetAdapter cmdlet as a background job.

Example 1

Code:

Start-Job -ScriptBlock {Get-NetAdapter}

Output:

PowerShell Jobs - Example 1

We are able also to save the object in a variable in order to use this job in other commands.

Example 2

Code:

$MyJob = Start-Job -ScriptBlock {Get-NetAdapter}

Output:

PowerShell Jobs - Example 2

[adinserter name=”In Article”]

Get the current jobs of the session

We are able to get the job object by using Get-Job cmdlet. If we use Get-Job cmdlet without any parameters we will retrieve all jobs. You are also able to get the job object only for a specific job. The object can be saved again in a variable to be used in other commands. You can specify a job by Id,Name or Job (variable).

Example 3

Code:

Start-Job -ScriptBlock {Get-NetAdapter}
Start-Job -ScriptBlock {Get-Date}
Get-Job
$MyJob3 = Get-Job -Id 3
$MyJob3

Output:

PowerShell Jobs - Example 3

[adinserter name=”In Article”]

Get the background jobs results

In order to get the results from the job we need to use Receive-Job cmdlet. Check the below example on how you are able to get the results of the jobs. The below example is based on Example 3

Example 4

Code:

Start-Job -ScriptBlock {Get-NetAdapter}
Start-Job -ScriptBlock {Get-Date}
Get-Job
$MyJob3 = Get-Job -Id 3
$MyJob3
Receive-Job -Id 1
$Job3Results = Receive-Job -Job $MyJob3
$Job3Results

Output:

PowerShell Jobs - Example 4

PowerShell Jobs - Example 4-1

Note that when you use Receive-Job you get the results of the job whether is completed or not. If the background job is not completed, you will get only the current results of the job until that moment. By default, Receive-Job cmdlet deletes the results from the memory when they have been received. If the command was not completed and you run Receive-Job again it will get the rest of the results only. You are able to keep the results that have been received in the memory by using -Keep parameter. 

Example 5

Code:

Start-Job -ScriptBlock {Get-Process}
$MyJob = Get-Job -Id 1
Receive-Job -Job $MyJob

Output:

PowerShell Jobs - Example 5

Example 6

Code:

Start-Job -ScriptBlock {Get-Process}
$MyJob = Get-Job -Id 1
Receive-Job -Job $MyJob -Keep

Output:

PowerShell Jobs - Example 6

[adinserter name=”In Article”]

Get the results after the background job finished

As you saw above, I have used Receive-Job multiple times to get the results. We are able to wait for the job to finish until we will receive the results from the job. By using Wait-Job, Receive-Job cmdlet wait for the job to be completed and then it will get the results.

Example 7

Code:

Start-Job -ScriptBlock {Get-NetAdapter}
$MyJob = Get-Job -Id 1
Receive-Job -Job $MyJob

Output:

PowerShell Jobs - Example 7

Code:

Start-Job -ScriptBlock {Get-NetAdapter}
$MyJob = Get-Job -Id 1
Wait-Job -Job $MyJob
Receive-Job -Job $MyJob

Output:

PowerShell Jobs - Example 7-1

As jobs may take a lot of time to complete, we are able to set a limit of the wait time. You can limit the wait time by using -Limit parameter. The value that you set in -Limit parameter is in seconds. When you will reach the time limit, the Receive-Job will retrieve the current results at the moment even if the job has not been completed. It does not matter if you have received the results or if the time limit has been reached, the job will continue to run until it is completed.

[adinserter name=”In Article”]

Delete a background job

In order to delete a background job you need to use Remove-Job cmdlet. You can specify the job either by Id, Name, job variable.

Example 8

Code:

Start-Job -Name JobNetAdapter -ScriptBlock {Get-NetAdapter}
Start-Job -Name JobDate -ScriptBlock {Get-Date}
Get-Job
Remove-Job -Name JobNetAdapter
Get-Job

Output:

PowerShell Jobs - Example 8

[adinserter name=”In Article”]

Investigation of failed jobs

Sometimes jobs may fail for various reason. If you want to find the reason of the failure, you need to use Reason sub-property of the job object. Lets see the below example to better understand.

Example 9

Code:

$SecurityLogsJob = Start-Job -Name SecurityLogs -ScriptBlock {Get-NetAdapters}
Get-Job
$SecurityLogsJob.ChildJobs[0].JobStateInfo.Reason

Output:

PowerShell Jobs - Example 9

[adinserter name=”In Article”]

Child Jobs

When we are running background jobs, each job has one or more child jobs. If the job is started using Start-Job or Invoke-Command -AsJob , the parent job will not run any commands that are included in the script block. Child jobs will run the commands. The parent job has an executive role. This might not happen if you start a job using any other cmdlet. The child jobs are stored in the ChildJobs property of the parent job object. The ChildJobs property can contain one or many child job objects. The child job objects have a name, ID, and instance ID that differ from the parent job so that you can manage the parent and child jobs individually or as a unit.

If we want to get the parent job and the child jobs we need to use -IncludeChildJobs parameter of Get-Job cmdlet. If you want to get the child jobs only then you need to use Childjobs property of the job object. You are also able to select the Child jobs based on their state, by using -ChildJobState parameter of Get-Job cmdlet. Both -IncludeChildJobs and ChildJobState parameters have been introduced in Windows PowerShell 3.0.

Example 10

Code:

$SecurityLogsJob = Start-Job -Name SecurityLogs -ScriptBlock {Get-NetAdapters}
Get-Job
Get-Job -IncludeChildJob
$SecurityLogsJob.ChildJobs
Get-Job -Name Job2

Output:

PowerShell Jobs - Example 10

The next explanation for the configuration of the child job is provided by Microsoft:

The configuration of the child job depends on the command that you use to start the job.

  • When you use Start-Job to start a job on a local computer, the job consists of an executive parent job and a child job that runs the command.
  • When you use the AsJob parameter of Invoke-Command to start a job on one or more computers, the job consists of an executive parent job and a child job for each job run on each computer.
  • When you use Invoke-Command to run a Start-Job command on one or more remote computers, the result is the same as a local command run on each remote computer. The command returns a job object for each computer. The job object consists of an executive parent job and one child job that runs the command.

The parent job represents all of the child jobs. When you manage a parent job, you also manage the associated child jobs. For example, if you stop a parent job, all child jobs are stopped. If you get the results of a parent job, you get the results of all child jobs.

However, you can also manage child jobs individually. This is most useful when you want to investigate a problem with a job or get the results of only one of a number of child jobs started by using the AsJob parameter of Invoke-Command.

[adinserter name=”In Article”]

Remote Background Jobs

As we have mentioned above, you are not able not only to run job on local computers but also on remote computers. You are able to run jobs on remote computers by using any of the following methods.

  • Start an interactive session with a remote computer, and start a job in the interactive session. The procedures are the same as running a local job, although all actions are performed on the remote computer.
  • Run a background job on a remote computer that returns its results to the local computer. Use this method when you want to collect the results of background jobs and maintain them in a central location on the local computer.
  • Run a background job on a remote computer that maintains its results on the remote computer. Use this method when the job data is more securely maintained on the originating computer.

By using the first and the third method, the results of the job will remain on the remote computer. In order to get the results and view them from the remote computer to local computer you need to save them in a file and read the content from the file.

Lets see below on how we are able to run background job using those methods.

Using Interactive session

Example 11

Code:

Enter-PSSession -ComputerName Remote-Computer
$JobNetAdapter = Start-Job -Name JobNetAdapter -ScriptBlock {Get-NetAdapter}
Get-Job -Name JobNetAdapter
Receive-Job -Job $JobNetAdapter > C:\TestFolder\NetAdapter.txt
Exit-PSSession
$Session = New-PSSession -ComputerName Remote-Computer
$ResultOnLocal = Invoke-Command -Session $Session -ScriptBlock {Get-Content -Path "C:\TestFolder\NetAdapter.txt"}
Remove-PSSession -Session $Session
$ResultOnLocal

Output:

PowerShell Jobs - Example 11

Results to be returned on local computer

Example 12

Code:

Invoke-Command -ComputerName RemoteComputer -ScriptBlock {Get-NetAdapter} -AsJob
$Result = Receive-Job -Name Job1
$Result

Output:

PowerShell Jobs - Example 12

[adinserter name=”In Article”]

Results remain on remote computer

Example 13

Code:

$Session = New-PSSession -ComputerName RemoteComputer
Invoke-Command -Session $Session -ScriptBlock {Start-Job -Name JobNetAdapter -ScriptBlock {Get-NetAdapter}}
Invoke-Command -Session $Session -ScriptBlock {Get-Job -Name JobNetAdapter}
$ResultOnLocal = Invoke-Command -Session $Session -ScriptBlock {Receive-Job -Name JobNetAdapter -Keep}
$ResultOnLocal
Invoke-Command -Session $Session -ScriptBlock {Receive-Job -Name JobNetAdapter > C:\TestFolder\NetAdapter.txt}
$ResultOnLocal = Invoke-Command -Session $Session -ScriptBlock {Get-Content -Path "C:\TestFolder\NetAdapter.txt"}
$ResultOnLocal

Output:

PowerShell Jobs - Example 13

PowerShell Jobs - Example 13-1

[adinserter name=”In Article”]

Job Types

PowerShell is able to run different types of jobs. You can use other types of job based on the task that you want to perform. From Windows PowerShell 3.0 and on, developers can write “job source adapters” that add new job types to PowerShell and include the job source adapters in modules. When you import the module, you can use the new job type in your session. For example, the PSScheduledJob module adds scheduled jobs and the PSWorkflow module adds workflow jobs.

Custom jobs types might differ significantly from standard Windows PowerShell background jobs. For example, scheduled jobs are saved on disk; they do not exist only in a particular session. Workflow jobs can be suspended and resumed. The cmdlets that you use to manage custom jobs depend on the job type. For some, you use the standard job cmdlets, such as Get-Job and Start-Job. Others come with specialized cmdlets that manage only a particular type of job. For detailed information about custom job types, see the help topics about the job type. To find the job type of a job, use the Get-Job cmdlet. Get-Job returns different job objects for different types of jobs. The value of the PSJobTypeName property of the job objects that Get-Job returns indicates the job type.

The above information has been taken from Microsoft. Below is the list of different job types that come with Windows PowerShell.

Job Types List
  • BackgroundJob – Started by using the Start-Job cmdlet.
  • RemoteJob – Started by using the -AsJob parameter of the Invoke-Command cmdlet.
  • PSWorkflowJob – Started by using the -AsJob parameter of a workflow.
  • PSScheduledJob – An instance of a scheduled job started by a job trigger.
  • CIMJob – Started by using the -AsJob parameter of a cmdlet from a CDXML module.
  • WMIJob – Started by using the -AsJob parameter of a cmdlet from a WMI module.
  • PSEventJob – Created by running Register-ObjectEvent  and specifying an action with the Action parameter.

I hope the tutorial about PowerShell Jobs is helpful.

Please let me know your comments and thoughts.

You feedback is appreciated.

[adinserter name=”In Article”]

Related Links

  • PowerShell Tutorials
  • PowerShell Scripts
  • about_Jobs | Microsoft Docs
  • about_Remote_Jobs | Microsoft Docs
  • About Job Details – Microsoft Docs
  • Start-Job – Microsoft Docs
  • Get-Job – Microsoft Docs
  • Receive-Job – Microsoft Docs
  • Stop-Job – Microsoft Docs
  • Wait-Job – Microsoft Docs
  • Remove-Job – Microsoft Docs
  • Invoke-Command – Microsoft Docs
  • Get-NetAdapter – Microsoft Docs
  • Get-Date – Microsoft Docs
  • Get-Process – Microsoft Docs
  • Get-ScheduledJob – Microsoft Docs
  • New-JobTrigger – Microsoft Docs
  • Register-ScheduledJob – Microsoft Docs

[adinserter name=”Matched-Content”]

Summary
PowerShell Jobs
Article Name
PowerShell Jobs
Description
PowerShell Jobs. In this tutorial you will find information about PowerShell Jobs and their use. Stephanos Constantinou Blog
Author
Stephanos
Publisher Name
Stephanos Constantinou Blog
Publisher Logo
Stephanos Constantinou Blog

Filed Under: PowerShell Tutorials Tagged With: Get-Date, Get-Job, Get-NetAdapter, Get-Process, Get-ScheduledJob, Invoke-Command, New-JobTrigger, Receive-Job, Register-ScheduledJob, Remove-Job, Start-Job, Stop-Job, Wait-Job

Reader Interactions

Comments

  1. David S says

    29/10/2021 at 21:41

    Fav’d…

    I have a start-job command, which kicks off OK and completes properly. However, i need it to wait until completion, after kicking off a certain number of jobs…That’s easy enough, if x == 100 etc then get-job | wait-job, right? Well when i run that, it actually returns the job completion for the 100 (or 10000) jobs i have running. I need it to wait minus the return of the job being Completed bit. I thought i had to put get-job | wait-job | receive-job to have it return info, but apparently not.

    #just pseudo code mostly…
    $count=0
    $x = all my computers in a list
    Foreach ($computer in $x)
    {
    $count++
    if $count == 100 {get-job | wait-job}
    start-job -name PingComputer -scriptblock {
    param ($computer)
    ping $computer
    }
    }

    Reply
  2. David S says

    29/10/2021 at 23:07

    | Out-null is the winner…

    No output:
    get-job | wait-job | out-null

    Will also work for start-job by itself…start-job …. | out-null

    Reply

Leave a Reply Cancel reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.

Footer

Recent Posts

  • ICS Cube Product Review 26/04/2019
  • PowerShell Module SysInfo v1.2.0 15/03/2019
  • PowerShell Module SysInfo v1.1.2 13/11/2018
  • PowerShell Module SysInfo 24/10/2018
  • Get-VoltageProbe 24/10/2018
  • Get-VideoController 24/10/2018
  • Get-USBController 24/10/2018
  • Get-TrackPoint 24/10/2018
  • Get-TrackBall 24/10/2018
  • Get-TouchScreen 24/10/2018
Planet PowerShell

Categories

  • Modules Cmdlets (57)
  • PowerShell Modules (5)
  • PowerShell Scripts (38)
  • PowerShell Tutorials (35)
  • Software Reviews (2)

Archives

  • April 2019 (1)
  • March 2019 (1)
  • November 2018 (1)
  • October 2018 (56)
  • September 2018 (13)
  • August 2018 (9)
  • July 2018 (6)
  • June 2018 (8)
  • May 2018 (7)
  • April 2018 (9)
  • March 2018 (4)
  • February 2018 (6)
  • January 2018 (12)
  • December 2017 (4)
Top 10 PowerShell 2018

Blogroll

  • Planet PowerShell
  • Reddit – PowerShell
  • PowerShell Magazine
  • PowerShell.org
  • PowerShell Team Blog
  • Hey, Scripting Guy! Blog
  • Mike F Robbins
  • PowerShell Explained with Kevin Marquette
  • Mike Kanakos – Network Admin
  • The Lonely Administrator
  • AskME4Tech
PowerShell Blogs Sysadmin Blogs Banners for Top 20 Programming Blogs

© 2023 · Stephanos Constantinou Blog

  • Home
  • Blogs
  • About
  • Contact