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.
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:
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.
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.
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 )
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.
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.
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.
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
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.
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.
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
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.
0 Response to "Interactive Powershell Require Pass Phrase Before Continuing"
Post a Comment