PowerShell comes with support for progress bars. Here is a very simple example:
1..100 | ForEach-Object { Write-Progress -Activity 'Counting' -Status "Processing $_" -PercentComplete $_ Start-Sleep -Milliseconds 100 }
Using a progress bar can be valuable as long as you don’t call Write-Progress excessively. Especially with long-running loops, it makes no sense to call Write-Progress for each loop iteration. If you do, your scripts become very slow.
Let’s assume for example you have a loop that runs 10000 times. Displaying a progress bar will slow down the script considerably:
$min = 1 $max = 10000 $start = Get-Date $min..$max | ForEach-Object { $percent = $_ * 100 / $max Write-Progress -Activity 'Counting' -Status "Processing $_" -PercentComplete $percent } $end = Get-Date ($end-$start).TotalMilliseconds
This delay is directly related to the number of calls to Write-Progress, so if you change the value for $max to 100000, the script takes 10 times the time, just because Write-Progress is called 10 times more often.
That’s why you should add an intelligent mechanism to limit the number of calls to Write-Progress. The following example updates the progress bar in 0.1% increments:
$min = 1 $max = 10000 $start = Get-Date # update progress bar every 0.1 % $interval = $max / 1000 $min..$max | ForEach-Object { $percent = $_ * 100 / $max if ($_ % $interval -eq 0) { Write-Progress -Activity 'Counting' -Status "Processing $_" -PercentComplete $percent } } $end = Get-Date ($end-$start).TotalMilliseconds
When you increase the number for $max, you will now notice that the script won’t take much longer because the number of calls to Write-Progress stays the same.