PowerShell How-To

How To Create Progress Bars in PowerShell

When automating a ton of tasks, creating a visual cue on the activate is helpful in knowing that things are running smoothly.

No one likes to wait. We all want stuff done now but, unfortunately, that's not always possible. Things take time, and we're forced to put up with waiting an indefinite amount of time for task X to complete. Writing PowerShell code and waiting for execution is no different. We sometimes expect automation to be instantaneous when, in reality, PowerShell must interact with various other systems that have their own schedules. When the script will take awhile, and the script author is aware of this ahead of time, skilled script writers will add important indicators in the script to keep the user aware that something is happening instead of staring at a blinking cursor for minutes at a time.

Script writers have a couple of options to build visual cues to the user as to what's going on in the background. They may choose to use various Write-Verbose or Write-Information references indicating the status. Or they can use PowerShell's built-in progress bar support to not only display messages but also to show a graphical representation of the percentage of work that's been done.

Let's say you've got a task in a script that may take a couple of minutes. Rather than forcing the user at staring at a blinking cursor always questioning him/herself if it's doing anything or not, we'll build a progress bar to clue them in. First, let's verify that when we do create this progress bar that it will show up. To control progress bar visibility, PowerShell has an automatic variable called $ProgressPreference. By default, it's set to Continue but, if for some reason, it's set to SilentlyContinue, the progress bar will not be visible.

Once we've confirmed we can see the progress bar; we can now get down to it. A progress bar consists of three areas represented by parameters to the Write-Progress cmdlet; the title of the task (Activity), subtasks (Status) and the percent complete for the task (PercentComplete). To bring up the progress bar and to update it as it's running, we use the Write-Progress cmdlet. If Write-Progress is just invoked on its own, you won't notice much because it's meant to display long-running processes. To test it out though, let's create an infinite loop to run continually.

while ($true) { write-progress  -Activity 'Doing thing'; sleep 1 }
Figure 1.

In the image above, we just see a single activity. Let's add some subtasks in there.

$i = 0
while ($true) {
Write-Progress -Activity 'Doing thing' -Status "Did thing $i times"
sleep 1
$i++
}

When the above code is run, you'll see that you now have a "subactivity" underneath indicating what's going on. Up to this point, we've just created a fancy messaging box. To take this one step further, let's now actually make this progress bar by adding a percent complete indicator.

$totalTimes = 10
$i = 0
for ($i=0;$i -lt $totalTimes; $i++) {
$percentComplete = ($i / $totalTimes) * 100
Write-Progress -Activity 'Doing thing' -Status "Did thing $i times" -PercentComplete $percentComplete
sleep 1
}
Figure 2.

Now we can see the actual progress bar! Using these three parameters with Write-Progress will be all you need to get started building an intuitive progress bar!

About the Author

Adam Bertram is an independent consultant, technical writer, trainer and presenter. Adam specializes in consulting and evangelizing all things IT automation mainly focused around Windows PowerShell. Adam is a Microsoft Windows PowerShell MVP, 2015 powershell.org PowerShell hero and has numerous Microsoft IT pro certifications. He is a writer, trainer and presenter and authors IT pro course content for Pluralsight. He is also a regular contributor to numerous print and online publications and presents at various user groups and conferences. You can find Adam at adamtheautomator.com or on Twitter at @adbertram.

comments powered by Disqus

SharePoint Watch

Sign up for our newsletter.

I agree to this site's Privacy Policy.