Pffffieeuw… This was quite the puzzle! Finally got an easy progress bar when I need to execute those long-running batch commands.

Just use this function in your pipeline. It works the same as a Foreach-Object loop. Only it displays a progress bar 🙂

Example:

1..200 | Show-Progress { $_ }

Executing your command

How does it work?

Show-Progress is just a fancy way of using Write-Progress. It accepts 2 parameters: $Input and $ScriptBlock.

$Input

This parameter accepts your current object in the pipeline. It then adds a new property ItemNumber. $ItemNumber is used to calculate how much items are piped through. $PipelineBuffer then stores the entire object so that we can use this “new” object in our next pipe.

$ScriptBlock

Next, the scriptblock takes over. The $ScriptBlock parameter tries to be what it says it would be. That is, a scriptblock.

Since we essentially copied over the piped object to our $PipelineBuffer, we can easily use this object as if it were the original. Only addition is the $Itemnumber. So, we simply use this object to perform our scriptblock on.

Write-Progress

Now, we can calculate our $PercentageComplete. Since we used $a as a temporary counter and since we didn’t update it since our last object, this reflects the total amount of items in our original object.

$a = Total amount of items in original object

$ItemNumber = Number of the current item in the pipeline

$PercentageComplete = 100 / $a * ( $_ .ItemNumber + 1)

And here is the code: