[CmdletBinding()] param ( [Parameter(Mandatory)] [ScriptBlock]$WhileLogic, [Parameter(Mandatory)] [string]$Activity, [string]$Status, [int]$TotalSeconds, [int]$StepDelaySeconds = 1, [switch]$NoCompleteMessage, [string]$CompleteMessage = "Run time", [System.ConsoleColor]$ForegroundColor = [System.ConsoleColor]::Cyan, [int]$MinSecondsDelayForCompleteMessage = 0 ) $local:progressParams = [ordered]@{ Activity = $Activity } if( $Status ) { $progressParams.Status = $Status } if( $TotalSeconds ) { $progressParams.TotalSeconds = $TotalSeconds} $local:sw = [System.Diagnostics.Stopwatch]::StartNew() while( Invoke-Command -ScriptBlock $WhileLogic -ArgumentList @($sw) ) { $progressParams.Elapsed = $sw.Elapsed Show-Progress @progressParams Start-Sleep -Seconds $StepDelaySeconds } Show-Progress -Activity $Activity -Completed if( -not $NoCompleteMessage -and ($MinSecondsDelayForCompleteMessage * 1000) -le $sw.ElapsedMilliseconds ) { Write-Host -ForegroundColor $ForegroundColor "$CompleteMessage`: $(ConvertFrom-TimeSpan $sw.Elapsed)" }