<img height="1" width="1" style="display:none" src="https://www.facebook.com/tr?id=1678611822423757&amp;ev=PageView&amp;noscript=1">
Defrag This

| Read. Reflect. Reboot.

Creating A Timeout Feature In Your PowerShell Scripts

Adam Bertram| March 05 2018

| IT insights



Don't let your entire workflow be hung up because one of the scripts is stuck on some task. There's a way around that!

Have you ever written an excellent PowerShell script only to find that it just hangs on some task without any indication why? It's especially frustrating if the script is being kicked off by an unattended process. The entire workflow may be hung up just because one of the scripts is hung on some task. Fortunately, there's a way around this. To prevent a script from hanging indefinitely, we can add a timeout feature to it. Adding a timeout feature to a script forces the script to either exit or continue if a certain task is taking too long.

To add a timeout feature to a PowerShell script requires a few different tasks:

  • Start a timer
  • Invoke some piece of code
  • Check the code's status every so often
  • If timeout is exceeded, do something
  • If timeout is not exceeded, continue with the script
  • Stop the timer

Let's see an example of how this whole process will work.

Read: Advanced PowerShell Functions: Upping Your Game

The first thing we need to do is define a timeout. Most often, a timeout in seconds will work. I want to ensure my code doesn't last for more than 10 seconds, so I'll set a variable for that.

$Timeout = 10 ## seconds

Next, I'll need to take whatever code I want to wait on and add it to a scriptblock. For this example, imagine I've created a few background jobs further up the script. I'd like to wait until all of these jobs are completed before continuing.

$jobs = Get-Job
$Condition = {param($jobs) 'Running' -not in $jobs.State }
$ConditionArgs = $jobs

Next, I need to define how long in between checks my script should perform the task.

$RetryInterval = 5 ## seconds

Now I'll start the timer.

## Start the timer
$timer = [Diagnostics.Stopwatch]::StartNew()

Now that the timer is started, I can now invoke that piece of code I need to be done.

## Start checking the condition scriptblock. Do this as long as the action hasn't exceeded
## the timeout or the condition scriptblock returns something other than $false or $null.
while (($timer.Elapsed.TotalSeconds -lt $Timeout) -and (& $Condition $ConditionArgs)) {

    ## Wait a specific interval
    Start-Sleep -Seconds $RetryInterval

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

Once the timeout has been exceeded, or the task has completed, I'll then need to stop the timer.

## The action either completed or timed out. Stop the timer.

Now I can check to see if the timeout was exceeded or if the task completed on its own. Here, I'm throwing in an exception indicating that the action did not complete if the timeout stopped it. Otherwise, I'm just writing out a verbose statement that any code can follow after that.

## Return status of what happened
if ($timer.Elapsed.TotalSeconds -gt $Timeout) {
    throw 'Action did not complete before timeout period.'
} else {
    Write-Verbose -Message 'Action completed before the timeout period.'

For a function called Wait-Action that incorporates all of this functionality into a PowerShell function, download it from the PowerShell Gallery:

Install-Script -Name Wait-Action

Topics: IT insights

Leave a Reply

Your email address will not be published. Required fields are marked *


Adam Bertram is a 20-year veteran of IT. He’s currently an automation engineer, blogger, independent consultant, freelance writer, author, and trainer. Adam focuses on DevOps, system management, and automation technologies as well as various cloud platforms. He is a Microsoft Cloud and Datacenter Management MVP and efficiency nerd that enjoys teaching others a better way to leverage automation.

Free Trials

Getting started has never been easier. Download a trial today.

Download Free Trials

Contact Us

Let us know how we can help you. Focus on what matters. 

Send us a note

Subscribe to our Blog

Let’s stay in touch! Register to receive our blog updates.