PowerShell jobs — because you have better things to do than wait

It is easy to think of PowerShell as being a real-time environment. When an administrator enters a command into the PowerShell interface, that command usually executes right away. The same thing goes for PowerShell scripts. Most administrators probably launch a script and then wait for it to complete. There is certainly nothing wrong with using PowerShell in this way. In fact, entering a command or running a script is the normal way of doing things. Sometimes though, waiting for a command or a script can be inconvenient. For example, a long-running script may prevent you from doing anything else until the script completes. While you can open another PowerShell window, each window is a separate session. This means that the variables that you have assigned within the PowerShell window that you have been using won’t be recognized in any new windows that you open. If you need to run a script or a command that is going to take a while to complete, but you don’t want to tie up the current session, then you might consider creating a job. PowerShell jobs allow a script or a command to run in the background. The session remains available for use while the job continues to run. (You can also use PowerShell jobs with Azure cmdlets.)

To show you how jobs work in PowerShell, I have created a very simple script that I named Delay.ps1. The script contains a single command that forces PowerShell to wait for three minutes (180 seconds). The command contained within the script is:

Start-sleep 180

As you can see in the screenshot below, once I run the script, I can’t do anything else within my PowerShell session until the script completes. Incidentally, you can often break out of a long-running script by pressing Ctrl+C.

PowerShell jobsTreating a command as a job

So, let’s take a look at how using a job might improve the situation. As previously mentioned, PowerShell lets you run scripts as jobs, but you can also run an individual command as a job. If you want to treat a command as a job, then just enter the Start-Job cmdlet, followed by the ScriptBlock parameter, and the command that you want to run. If for example, I wanted to run the Start-Sleep cmdlet as a job, the command used for doing so would look like this:

Start-Job -ScriptBlock {Start-Sleep 180}

You can see what this looks like in the next screenshot.

PowerShell jobs
I will talk about the command’s output in a moment. Before I do though, I want to show you how to execute a PowerShell script as a job. The method that I usually use is to call the script by using the Start-Job cmdlet, followed by the FilePath parameter, and then the script’s path and filename. Here is what such a command might look like:

Start-Job -FilePath C:\Scripts\Delay.ps1

Checking a job’s status

Now that I have shown you how to launch a script as a job, let’s go back and look at the output in the previous screenshot. As you can see in the screenshot, PowerShell clearly indicates that the command is running as a background job. It also shows you the command that is being run, and the location where the command is running (which is handy if you are running jobs on a remote system). The main thing that I wanted to show you though is the job’s name and ID. You can use these attributes to identify the job.

The reason why these attributes are so important is that in many cases it is necessary to go back and check a job’s status. Otherwise, it may be difficult to determine whether or not a job has completed.

The cmdlet used for checking a job’s status is Get-Job. As you can see in the next screenshot, PowerShell lists the jobs that I previously ran within the current session, as well as the status of each job.

Depending on what you are doing, it is conceivable that you could end up running lots of different jobs within a session. While you could use the technique that I just showed you to check the status of your jobs, you can also use PowerShell’s filtering capabilities to show you which jobs are still running. The command used for doing so is:

Get-Job | Where-Object -Property State -eq “Running”

If you look at the next screenshot, you can see that I launched a new job and then entered this command, which displayed the running job. I then repeated the command, but this time I changed the word Running to Completed. This caused PowerShell to show me the jobs that have completed. This screen capture also demonstrates that because I launched this particular task as a job, the console allows me to continue working rather than having to wait for the command to complete.

PowerShell jobs

This brings up an interesting point. The main benefit of running PowerShell code as a job is that you can continue working without having to wait for it to complete. As strange as it sounds though, Microsoft has created a cmdlet called Wait-Job that actually causes PowerShell to stop and wait for a job to complete. The only time I have ever seen Wait-Job used in the real world was when someone launched several jobs and then wanted to launch yet another job once the running jobs had completed. You can actually use the cmdlet’s ID parameter to specify one or more job ID numbers. Wait-Job will wait for all of the specified jobs to complete before continuing.

PowerShell jobs: Many use cases

PowerShell jobs have a number of different use cases, and I have really only begun to scratch the surface of what you can do with jobs. It is worth noting though, that a poorly constructed job can get stuck. In these situations, you can terminate a stuck job by using the Stop-Job cmdlet.

Featured image: Shutterstock

About The Author

1 thought on “PowerShell jobs — because you have better things to do than wait”

Leave a Comment

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

This site is protected by reCAPTCHA and the Google Privacy Policy and Terms of Service apply.

Scroll to Top