Reporting Progress with Powershell

Often in the life of an IT engineer or administrator, the command shell is a means of performing an operation on multiple items that would otherwise take a significant amount of time if performed via GUI tools. 
When planning for such operations, reporting on progress is a nice thing to have, since it may take a while for the entire operation to complete and we need to know if things are working out as expected.

In the majority of the cases, we know the actions that need to be taken in advance and thus the easiest way to go through them is to use a For loop.
With For we start processing the items in an array or list either from its start or end and work our way to the last item by incrementing, usually by one.

The Powershell code below will get the items in the current directory and sequentially process them, reporting the status of the operation after each item:

# Get the list of items to process
$items = @(Get-ChildItem)

# Loop through the array
for($i = 0; $i -lt $items.count; $i++)
    # Report the current progress
    Write-Progress -Activity "Processing items." `
                   -Status "Working on $($items[$i].Name)." `
                   -PercentComplete ((100 * $i)/$items.count)

    # Create a long running operation
    Start-Sleep -Seconds 1

The loop in line 5 will have as many iterations as the number of elements in the array and in each iteration we're processing a different item of the array.

Each iteration also contains a Write-Progress command that shows/updates the respective progress bar. The most important parameters are:

  • Activity: The name of the batch operation.
  • Status: Information about the current iteration. Usually contains information to reference the item being processed.
  • PercentComplete: An integer indicating the completion percentage of the operation. This is calculated using the number of the current iteration and the total number of items to process. 
For the purpose of this demo, I'm not performing any operation on the items, instead I've added a command to delay the execution for one second at a time. This is where you'll place your code in similar tasks.

Running the above scriptblock in my home directory results in the below (hover over the image to animate):

The value of the the Activity parameter will be displayed on the top of the progress bar and below it will be the respective value of the Status parameter that changes with each iteration. 

This approach is great for reporting the progress of an operation which will take a while, however depending on the nature of the operation you may have to consider parallel execution in order to speed things up. For that reason, I've developed the Foreach-Object-Parallel cmdlet that aims to make the process of running parallel task easier.

More information on For is available here and on Write-Progress here.

Popular posts from this blog

Domain Controller Machine Password Reset

Configuring a Certificate on Exchange Receive Connector

Running Multiple NGINX Ingress Controllers in AKS