Categories Tutorials

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.

Treating 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.

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.

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

Brien Posey

Brien Posey is a freelance technology author and speaker with over two decades of IT experience. Prior to going freelance, Brien was a CIO for a national chain of hospitals and healthcare facilities. He has also served as a network engineer for the United States Department of Defense at Fort Knox. In addition, Brien has worked as a network administrator for some of the largest insurance companies in America. To date, Brien has received Microsoft’s MVP award numerous times in categories including Windows Server, IIS, Exchange Server, and File Systems / Storage. You can visit Brien’s Website at:

Published by
Brien Posey

Recent Posts

Azure DevOps Wiki: Manage your project documentation and collaboration

Not being able to find project documentation is way too common. Use Azure DevOps’ built-in…

2 days ago

Samsung Unpacked 2020: Galaxy S20, Galaxy Z Flip, and more

Samsung is again the first major company to roll out new smartphones in the new…

2 days ago

PhotoSquared data leak exposes users’ photos, information

PhotoSquared has experienced a data leak, mainly because the popular U.S.-based photo app failed to…

2 days ago

Moving data from an Azure VM to Storage Account with AzCopy

Here’s an elegant and modern way to move data from your Azure virtual machine to…

3 days ago

A lot not to like: Analysis of recent Facebook data breach

The effects of the recent Facebook data breach are still being felt. In this new…

3 days ago

Exchange 2019: Building an environment from scratch

Are you finally ready to take the plunge into Exchange 2019? If you are building…

3 days ago