Master PowerShell Pause: Command Line & Scripting Techniques

Published:30 July 2020 - 6 min. read

Today’s sponsor is n8n, the AI-native workflow automation tool built for ITOps and DevSecOps. With 100+ templates to get you started quickly and a powerful visual editor, you can automate complex workflows without giving up control. Check it out here.

 

 

 

 

 

There are many reasons to pause script execution. Perhaps a script needs to wait for user input, slow down execution speed, or wait for another process to conclude before moving forward. As with most tasks in Powershell, there is more than one way to pause a script. Depending on what you are trying to accomplish, the method of pausing you choose will have its strengths and weaknesses. Adding in another wrinkle to the available options is the new cross-platform ability of PowerShell. Since PowerShell is often used as a way to “glue” different technologies together, just like in Windows, the Linux command-line has its options for pausing execution which can be incorporated into PowerShell as well.

Not a reader? Watch this related video tutorial!
Not seeing the video? Make sure your ad blocker is disabled.

Methods of PowerShell Pause

What are the different ways to pause script execution? In this article, we are going to break down the ability to pause into either native and non-native commands. By native we refer to those commands that are PowerShell or .NET built-in functions or methods. Non-native methods are defined as programs that are specific to Windows and Linux that could be used in conjunction with PowerShell.

Native Methods

  • Start-Sleep
  • [System.Threading.Thread]::Sleep()
  • Read-Host
  • [Console]::ReadKey()
  • $host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown")

Non-Native Methods

Windows

  • pause
  • timeout

Linux

  • sleep
  • read -p

As you can tell, there are a number of different options, each with their benefits and drawbacks. Which one you use will influence how execution is paused and what other effects that pause may include.

Native Methods

To start with, we will begin outlining the native methods as they are most used in scripts.

Start-Sleep

The most commonly used pause command is by far, Start-Sleep. This command takes two simple inputs, which are -Seconds and -Milliseconds. Seconds can be a System.Double number value while milliseconds takes only System.Int32 values. By combining the two, precise control over the length of the pause can be achieved. Start-Sleep has an alias of sleep as well.

Start-Sleep -Seconds 2 -Milliseconds 300

Before PowerShell 6.2.0, you would not be able to write a fractional seconds value like, 2.3 which is the same length of time we are pausing for in the above code. With 6.2.0, fractional values are now supported, so instead of writing out the seconds and milliseconds independently, you can now state: -Seconds 2.3.

It’s important to note that you can break out of a Start-Sleep function by using Ctrl-C. This is not true for all methods!

Thread Sleep

A less commonly used method of pausing execution is the [System.Threading.Thread]::Sleep() .NET method. By passing in a System.Int32 or a TimeSpan value, this allows pausing of the current thread for a set amount of time. For example, to pause by that same amount of time, 2.3 seconds, as in our Start-Sleep example, we can write:

[System.Threading.Thread]::Sleep(2300)

To use a timespan construct with the Thread Sleep method, you can do the following:

[System.Threading.Thread]::Sleep([TimeSpan]::New(0, 0, 0, 2, 300))

To indefinitely pause a thread, you can use the [System.Threading.Timeout]::InfiniteTimeSpan but keep in mind this may lock up your process.

Unlike Start-Sleep, the Thread Sleep method does not allow you to break out of the sleep routine using Ctrl-C. Depending on your application, this may be preferable.

Also important to know about thread sleep is that it is not an exact time guarantee. All thread sleep has a guarantee that it will wait at least that many seconds. Since thread sleep counts coincide with clock ticks, then other programs may interrupt this pause function and force the wait to take longer.

While thread sleep has its uses, it is better to use one of the other built-in methods because of these issues.

Read-Host

The above methods describe ways to pause execution, but only for a set amount of time. The other way to pause execution is by prompting for user input. With this method, a manual action must be taken, but it can be very useful to require a confirmation to continue and potentially include additional input.

Read-Host is one of the most common ways to prompt for user input. By prompting for user input, the resulting entry can be saved for further use in the code, or to pause execution as necessary.

Read-Host -Prompt "Press any key to continue"

Once text has been entered, it’s necessary to press the enter or return key to move execution along. By doing so, and without saving the input to a variable, this will output the same text entered to the console.

Press Enter to Move Execution Along
Press Enter to Move Execution Along

If you wanted to save the resulting text entered into a variable for later use, simply assign the Read-Host input to a variable.

$Input = Read-Host -Prompt "Press any key to continue"

Sometimes you may want to read in the input as a secure string. Thankfully, Read-Host makes that trivially easy.

$SecureInput = Read-Host -Prompt "Enter your password" -AsSecureString

Ctrl-C will allow you to break out of the Read-Host prompt.

Console ReadKey Method

Using the [Console]::ReadKey() method, you can easily read in key commands, along with modifiers, while pausing the program execution. By default, the key commands sent are echoed back to the screen as a System.ConsoleKeyInfo object. This includes the Key, KeyChar, and the Modifiers values, which can be very useful when checking for certain key combinations.

[Console]::ReadKey()
Console ReadKey Command
Console ReadKey Command

Often you may want to check for a certain key input before moving on continually. This can easily be done using a Do-While loop like below.

Do {
	$Key = [Console]::ReadKey($True)
	Write-Host $Key.Key
} While ( $Key.Key -NE [ConsoleKey]::Escape )
Do-While Loop Key
Do-While Loop Key

Please note that since we are looking for a specific key combination, Ctrl-C will not break out of the input here.

Host RawUI ReadKey Method

Finally, we have the $host.UI.RawUI.ReadKey() method. This is similar to the Console ReadKey method, but this method allows for passing in additional options into the ReadKey method to control behavior and output further.

$host.UI.RawUI.ReadKey()
RawUI.ReadKey
RawUI.ReadKey

There are a number of ReadKeyOptions that can be passed in which may make the RawUI ReadKey method more useful.

  • AllowCtrlC
  • IncludeKeyDown
  • IncludeKeyUp
  • NoEcho

This can be used in the following way which way include key down events and not echo the text out.

$host.UI.RawUI.ReadKey('NoEcho,IncludeKeyDown')

This method will allow the use of Ctrl-C to break out of the command, except if the AllowCtrlC option is used.

Non-Native Methods

In this section, we explore a few non-native methods of pausing script execution. These methods are intended for utilizing non-PowerShell console-specific utilities that can be integrated into PowerShell scripts depending on your needs.

Windows

Pause

The pause command is very simple, and will display Press any key to continue . . . and remain that way until a key is pressed to resume execution.

cmd /c 'pause'
Pause Command
Pause Command

You may ask how to use this in a script, but just like you would any other command, insert the cmd /c 'pause' command within your script to utilize the native functionality.

Cmd/C Pause Command
Cmd/C Pause Command

Timeout

Typically used in Windows batch files, the timeout command allows for pausing a specified number of seconds and optionally ignore any key commands. A user keystroke will typically resume execution even if the timeout period hasn’t elapsed. It is very simply used by passing in the number of seconds.

# Pause for 2 seconds
timeout /t 2

# Pause for 5 seconds but disallow keystroke breaks
timeout /t 5 /nobreak

# Pause indefinitely until a key is pressed
timeout /t -1
Timeout Command
Timeout Command

Just as with the pause command, insert the timeout command within the script and in the example below, we hit the enter key to continue.

Timeout Command Execution
Timeout Command Execution

Linux

Sleep

Like the pause command in Windows, the sleep command in Linux allows for setting an arbitrary value for sleep. Unlike the pause command, the sleep command has a few more options that allow for flexibility in sleep time.

sleep 2.3s
Sleep Command
Sleep Command

The sleep command also optionally has suffixes that can allow for longer periods of time to be defined. Examples:

  • sleep 1m – Sleep for one minute
  • sleep 2h – Sleep for two hours
  • sleep 1d – Sleep for one day

Read -P

Finally, the other way that Linux can pause is by using the read application to pause for the enter key to be hit to continue execution. There is an optional timeout parameter that will continue execution if the enter key is not hit by the specified time.

read -p 'Press enter to continue' -t 5
Read Application to Pause
Read Application to Pause

Conclusion

As you can see, there are many ways to pause execution within a script or on the command line. Depending on your needs, it could be as simple as a Start-Sleep command or a more complex input-driven process. Combined with native commands, PowerShell pause allows for flexibility in nearly any environment and maximum script utility.

Hate ads? Want to support the writer? Get many of our tutorials packaged as an ATA Guidebook.

Explore ATA Guidebooks

Looks like you're offline!