Quick Tip To Find Out What Your Background Jobs Are Doing

One of the great things about PowerShell is the use of background jobs to run long operations while still having access to your console, or running multiple jobs to gather your data that much quicker than doing a sequential approach. Rather than go into how cool this is and what not, I am going into a trick that I use to track the status of a running job.  For long running jobs, you might not have a good idea where the job is at in its progress. 

The trick to this is looking not at the job you usually see when you create your background job, as in this image:

image

This was just a simple line of code I used to keep the job running a little while.

Start-Job -ScriptBlock {start-sleep -seconds 10}

This is actually the parent job of a child job which is actually running the operation that you define either in a scriptblock or file.

To quote the msdn page:

The job does not perform any of the work. Each job has at least one child job because the child job performs the actual work. When you run a cmdlet so that the work is performed as a job, the cmdlet must add the job and the child jobs to a common repository, referred to as the job repository.

image

As you can see, there is the child job that is doing all of the work while the parent job patiently waits for it to complete. Now we might be so patient with our jobs, especially when we are trying to gauge when the job will finish. So how do we make this happen you ask? Simple, we use a technique that we already use (well, some of use at least): Write-Verbose logging in our code that will run in the background job. Looking deeper into the child job shows some interesting properties:

(Get-Job).childjobs | Select *

image

The properties I am talking about are Output,Error,Progress,Verbose,Debug and Warning.

Each one of these will display the appropriate data based on what you are using in your background job.  Lets dig deeper and actually see this in action by kicking off a longer job that provides some sort of output:

Start-Job -ScriptBlock {
    for ($i=0;$i -lt 100;$i++) {
        $VerbosePreference = 'continue'
        Write-Verbose ("[$(Get-Date)] - Iteration: {0}" -f $i)
        Start-Sleep -Seconds 5
    }
}

Wait a few seconds…

(Get-Job -Id 5).ChildJobs[0].Verbose

image

As you see, everything that you used for Write-Verbose is now displayed for you to track. You can actually take it a little bit further to only display the verbose output from the job:

(Get-Job -Id 5).ChildJobs[0].Verbose | Select -Expand Message

image

Just by adding a little bit of logging into your background job, you can track the status of it at any given moment when you think it might be hung up on something.  Given, my example was pretty simple, but you still get the idea of what you can do with this trick.

Lets look at the progress property and how we can use Write-Progress in a background job to track it as well. As you know, Write-Progress is a nice tool to use to track a running operation, but it also has great use in a background job as well.

Start-Job -ScriptBlock {
    for ($i=0;$i -lt 100;$i++) {
        $VerbosePreference = 'continue'
        Write-Progress -Activity "Progress" -Status ("Iteration: {0}" -f $i) -PercentComplete ($i)
        Start-Sleep -Seconds 5
    }
}

Wait a few seconds again…

(Get-Job -Id 7).ChildJobs[0].Progress

image

The objects that get returned when checking the progress property of the job is System.Management.Automation.ProgressRecord.  And if you just want the numbers of where it is at:

(Get-Job -Id 7).ChildJobs[0].Progress | Select -expand PercentComplete

image

 

Get-JobMessage Function

I wrote a simple function that can help to parse the jobs and provide you the specific type of data that you want to see, whether it is verbose, progress or errors. I could have probably done more with this, but decided to keep it as simple as possible due to time constraints. But if someone else wants to pick up on this and expand on it, then by all means go for it!

A couple screenshots of it in action.

Get-Job -id 5 | Get-JobMessage -ShowOutPut

image

Get-Job -id 7 | Get-JobMessage -ShowVerbose

image

Like I said, pretty simple but it gets the job done.

You can download the function below:

(Remove .Doc before using)

About Boe Prox

Microsoft Cloud and Datacenter MVP working as a SQL DBA.
This entry was posted in powershell and tagged , , . Bookmark the permalink.

4 Responses to Quick Tip To Find Out What Your Background Jobs Are Doing

  1. Ali says:

    This HUGELY helped me out to get into debugging my threads! Thank you a lot for this post!

  2. Pingback: Monitoring the Progress of a PowerShell Job « The Surly Admin

  3. Pingback: Reshared post from | The Lonely Administrator

  4. Rynant says:

    Very cool. I’ve been using [Diagnostics.Debug]::WriteLine() from within jobs to check progress, but that only helps if I have DebugView running. I’ll have to try this out.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s