PowerShell: Implementing a Progress Bar with Write-Progress

Have you always wanted to make your script more professional? A progress bar adds professionalism to your work. And it gives the user information how long your script will run and what the script is actually doing. In this blog post I will deal with Write-Progress. I will begin right from the scratch and then explain how to implement a progress bar in a script. Let’s jump in.

The Basics

I really like it to explain the basics with an example the reader can build on. Please keep in mind that the example is only for testing und learning purposes. Here it is.

Here is the code.

$services = Get-Service


For($i = 1; $i -le $count; $i++)

Write-Progress -Activity "Services" `
-PercentComplete (($i*100)/$count) `
-Status "$(([math]::Round((($i)/$count * 100),0))) %"

Start-Sleep -Milliseconds 100

This leads to the following progress bar:


Let me explain what will happen when the script runs.

Line 1

$services = Get-Service

That’s easy. Line 1 retrieves all Windows services and stores them into a varialbe $services.

Line 3


In line 3 the number of Windows services are counted. This value will be processed later on.

Line 5

For($i = 1; $i -le $count; $i++)

What does line 5 actually do? It’s  the condition for a for loop that sets $i to 1 followed by a condition that $i must be less or equal then the number of services. We get the number of services from the $servcies variable. Finally, $i counts up to the maximum number defined by the condition.

We absolutely need this for loop for our progress bar. Without this counter the progress bar cannot show you the current operation state.

Line 6

Line 6 starts the for loop. The code is placed in braces. The loop code ends in line 10.

Line 8 to 10

Write-Progress -Activity "Services" `
-PercentComplete (($i*100)/$count) `
-Status "$(([math]::Round((($i)/$count * 100),0))) %"

Line 8 is the most interesting part of the code and that line of code is what this blog post is about. Write-Progress comes into play.

Line 8 starts Write-Progress with an Activity name “Services”.

Then the progress bar must determine the percentage of the status while the loop is running. In order to do that, Write-Progress uses the PercentComplete parameter. To calculate the progress of the bar $i is multiplied by 100 and then divided by the number of services.

The Status parameter can show anything you like. For example it could show the name of the current processed service or it could show the percentage of the progress.

I like it when it shows how many percent have already been processed, so I decided to show the status in percent with the math method. Slow down. Let’s break into the details.

($i*100)/$count is my percentage calculator. Let’s say we have 30 services. When the loop meets the fifth service, the calculation is 5*100/30 = 16.66 %, that means 16.66 % of the entire process has already been processed. Now the math method comes into play. I put the entire code in parentheses to remove the comma digits (0). $(([math]::Round((($i)/$count * 100),0))) %.

Line 12

Start-Sleep -Milliseconds 100

Line 12 is only for testing purposes. It slows down the progress bar so that we can comfortably watch the progress running up.

Implementing a Progress Bar in Scripts

Now we have seen how Write-Progress can make our work look more professional. What about scripts? How to implement a progress bar in scripts? Well, it’s almost the same procedure. I will give you an example.

Consider the following script which will retrieve IP configuration from all domain joined Windows server operating sytstems. Notice the red markings, that’s where it happens.


In lines 3 to 10 the parameters Activity, CurrentOperation and PercentComplete are created. The information is saved in a hashtable @(). Hashtables can store keys and values. The keys are already defined, the values will come later from the loop started in line 18.

In line 22 to 27 $u is set to 0, it’s equal to $i from the last example. Then in line 22 the loop starts counting up $u and calculating the count (computer accounts) and the percentage. Write-Progress completes the progress bar setup.

Here is the script in action.


The Write-Progress code of this script example is built on this excellent guide “How to add progress bar in your PowerShell scripts?” that can be found here: https://www.powershellbros.com/how-to-add-progress-bar-in-your-powershell-scripts/

You can download my Get-NetIPServerInfo script here (without a progress bar): Retrieve the IP configuration of all Windows Servers with Get-NetIPServerInfo

I hope this blog post was helpful. See you next time with PowerShell again!

Categories: PowerShell

Tagged as: ,

9 replies »

  1. Hi Patrick. Thank you for taking the time to provide an excellent example (and by keeping it simple for us newbies). I see that it has been nearly a year and a half since this has been posted, but in the off chance that you are still responding, here, I wanted to ask you this question:

    In your article – under “The Basics” section, you show sample output. It shows:

    And then it shows a graphical (GUI) progress bar (with the blue fill in). How did you get it to do it graphically? I have it working without this, but would really like to have the nice professional GUI progress bar like you show.

    Any insight on that would be appreciated.



  2. Thanks, Patrick very good line details, keep it up

    Note, Need to remove closing curly bracket inline 15 it gives an error for the first code snippet (Here the code section)

    At line:15 char:1
    + }
    + ~
    Unexpected token ‘}’ in expression or statement.
    + CategoryInfo : ParserError: (:) [], ParentContainsErrorRecordException
    + FullyQualifiedErrorId : UnexpectedToken

    Liked by 1 person

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 )

Facebook photo

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

Connecting to %s

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