PoshBytes: Stop Guessing and Start Measuring with Stopwatch
Learn how to time PowerShell code with System.Diagnostics.Stopwatch and read TimeSpan output correctly, including a visible progress pause you can actually watch.
This post is a companion for the video embedded below. Scroll down to see the code from the video.
The Basic Stopwatch
Output elapsed time
$sw = [System.Diagnostics.Stopwatch]::StartNew()
Start-Sleep -Seconds 2
$sw.Stop()
$sw.Elapsed
Stopwatch Methods and What They Actually Do
Restart resets AND starts in one call
$sw = New-Object System.Diagnostics.Stopwatch
$sw.Start()
Start-Sleep -Milliseconds 500
$sw.Stop()
$sw.ElapsedMilliseconds
Start-Sleep -Milliseconds 500
$sw.ElapsedMilliseconds # unchanged
$sw.Start()
$sw.ElapsedMilliseconds
Start-Sleep -Milliseconds 300
$sw.Stop()
$sw.ElapsedMilliseconds
$sw.Reset()
$sw.ElapsedMilliseconds # 0
$sw.Restart()
$sw.ElapsedMilliseconds
Start-Sleep -Milliseconds 200
$sw.Stop()
$sw.ElapsedMilliseconds
A Visible Pause You Can Watch
pause the script for a set number of seconds while showing a progress bar and elapsed time
Function Start-WaitProgress {
param (
[int]$SecondsToWait = 30
)
$id = 2147483600
$sw = [system.diagnostics.stopwatch]::StartNew()
while ($sw.Elapsed.TotalSeconds -lt $SecondsToWait) {
$elapsed = [int]$sw.Elapsed.TotalSeconds
$remaining = $SecondsToWait - $elapsed
$WriteProgressParam = @{
Activity = "Waiting $SecondsToWait seconds"
Status = "Elapsed: $elapsed s Remaining: $remaining s"
PercentComplete = $( ( $elapsed / $SecondsToWait ) * 100 )
id = $id
}
Write-Progress @WriteProgressParam
Start-Sleep -Seconds 1
}
Write-Progress -Activity "Done" -Id $id -Completed
}
Start-WaitProgress 30
Breaking a While Loop Before It Ruins Your Day
Breaking a While Loop
$sw = [System.Diagnostics.Stopwatch]::StartNew()
$myExpectedResults = 2
while ($Results -ne $myExpectedResults -and $sw.Elapsed.TotalSeconds -lt 3) {
$Results = Invoke-ExternalCallThatSometimesWorksRight
Write-Host "Got result: $Results after $($sw.ElapsedMilliseconds) ms"
Start-Sleep -Milliseconds 200
}
$sw.Stop()
$sw.Elapsed
Wrap Up
• Stopwatch gives you accurate timing without guessing
• TimeSpan Total* properties are full duration values, non total properties are just the component parts
• Use Restart() to time multiple sections cleanly
• Use elapsed time to build safe loop timeouts and visible waiting progress