PowerShell How-To

Using a Stopwatch In PowerShell

Monitoring the speed at which code is executed will give a window into avenues to improve it for efficiency.

Ever wonder how long a piece of PowerShell code takes to execute? Maybe you've got a script that occasionally gets hung up on some process, and you'd like a way to terminate the script if it takes too long. If so, you're going to love the System.Diagnostics.Stopwatch .NET class available in PowerShell. Using a Stopwatch object allows you to precisely measure a start and stop time which opens up all kinds of opportunities in a PowerShell script.

To use the Stopwatch object, let's first create an object using a static method called StartNew().

 

$stopwatch =  [system.diagnostics.stopwatch]::StartNew()

Once the object has been created, it is continually running in the background. Every time the value of $stopwatch is checked, you'll see a different time down to the microsecond level.

 

PS C:\> $stopwatch =  [system.diagnostics.stopwatch]::StartNew()
PS C:\> $stopwatch

IsRunning Elapsed          ElapsedMilliseconds ElapsedTicks
--------- -------          ------------------- ------------
True 00:00:02.2956772                2299     22990551


PS C:\> $stopwatch

IsRunning Elapsed          ElapsedMilliseconds ElapsedTicks
--------- -------          ------------------- ------------
True 00:00:04.0694321                4069     40694669


PS C:\> $stopwatch

IsRunning Elapsed          ElapsedMilliseconds ElapsedTicks
--------- -------          ------------------- ------------
True 00:00:05.1999316                5199     51999528
We can also use the Elapsed property to see all of the time metrics easier.
PS C:\> $stopwatch.Elapsed


Days              : 0
Hours             : 0
Minutes           : 1
Seconds           : 23
Milliseconds      : 795
Ticks             : 837958187
TotalDays         : 0.000969859012731481
TotalHours        : 0.0232766163055556
TotalMinutes      : 1.39659697833333
TotalSeconds      : 83.7958187
TotalMilliseconds : 83795.8187

We can check to see if the stopwatch is running or not by using the IsRunning property and finally stop the stopwatch by using the Stop() method.

PS C:\> $stopwatch.IsRunning
True
PS C:\> $stopwatch.Stop()
PS C:\> $stopwatch.IsRunning
False

How the this method be used in a real-world situation? One great use of using the stopwatch is by creating a timeout. Let's say you've got a task that sometimes gets hung up and you want to ensure the entire script doesn't stop if this happens. We can use the stopwatch by including it in a while loop. Below is an example of checking the total seconds the stopwatch has been running and then executing some code. To prevent from attempting to execute the code every microsecond or less I've added a sleep cmdlet in there so that it will only check every second.

while ($timer.Elapsed.TotalSeconds -lt 10) {
## Do some stuff here

## Wait a specific interval
Start-Sleep -Seconds 1

## Check the time
$totalSecs = [math]::Round($timer.Elapsed.TotalSeconds,0)
Write-Verbose -Message "Still waiting for action to complete after [$totalSecs] seconds..."
}

This example ensures that the code inside of the while loop does not execute for longer than ten seconds. Using a timeout is a great way to use this useful .NET object. What other applications do you see that would come in handy by using the stopwatch?

About the Author

Adam Bertram is an independent consultant, technical writer, trainer and presenter. Adam specializes in consulting and evangelizing all things IT automation mainly focused around Windows PowerShell. Adam is a Microsoft Windows PowerShell MVP, 2015 powershell.org PowerShell hero and has numerous Microsoft IT pro certifications. He is a writer, trainer and presenter and authors IT pro course content for Pluralsight. He is also a regular contributor to numerous print and online publications and presents at various user groups and conferences. You can find Adam at adamtheautomator.com or on Twitter at @adbertram.

comments powered by Disqus

SharePoint Watch

Sign up for our newsletter.

I agree to this site's Privacy Policy.