How do you do a ‘Pause’ with PowerShell 2.0?
I assume that you want to read input from the console. If so, use Read-Host
.
cmd /c pause | out-null
(It is not the PowerShell way, but it's so much more elegant.)
Save trees. Use one-liners.
I think it is worthwhile to recap/summarize the choices here for clarity... then offer a new variation that I believe provides the best utility.
<1> ReadKey (System.Console)
write-host "Press any key to continue..."
[void][System.Console]::ReadKey($true)
- Advantage: Accepts any key but properly excludes Shift, Alt, Ctrl modifier keys.
- Disadvantage: Does not work in PS-ISE.
<2> ReadKey (RawUI)
Write-Host "Press any key to continue ..."
$x = $host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown")
- Disadvantage: Does not work in PS-ISE.
- Disadvantage: Does not exclude modifier keys.
<3> cmd
cmd /c Pause | Out-Null
- Disadvantage: Does not work in PS-ISE.
- Disadvantage: Visibly launches new shell/window on first use; not noticeable on subsequent use but still has the overhead
<4> Read-Host
Read-Host -Prompt "Press Enter to continue"
- Advantage: Works in PS-ISE.
- Disadvantage: Accepts only Enter key.
<5> ReadKey composite
This is a composite of <1> above with the ISE workaround/kludge extracted from the proposal on Adam's Tech Blog (courtesy of Nick from earlier comments on this page). I made two slight improvements to the latter: added Test-Path to avoid an error if you use Set-StrictMode (you do, don't you?!) and the final Write-Host to add a newline after your keystroke to put the prompt in the right place.
Function Pause ($Message = "Press any key to continue . . . ") {
if ((Test-Path variable:psISE) -and $psISE) {
$Shell = New-Object -ComObject "WScript.Shell"
$Button = $Shell.Popup("Click OK to continue.", 0, "Script Paused", 0)
}
else {
Write-Host -NoNewline $Message
[void][System.Console]::ReadKey($true)
Write-Host
}
}
- Advantage: Accepts any key but properly excludes Shift, Alt, Ctrl modifier keys.
- Advantage: Works in PS-ISE (though only with Enter or mouse click)
- Disadvantage: Not a one-liner!
The solutions like cmd /c pause
cause a new command interpreter to start and run in the background. Although acceptable in some cases, this isn't really ideal.
The solutions using Read-Host
force the user to press Enter and are not really "any key".
This solution will give you a true "press any key to continue" interface and will not start a new interpreter, which will essentially mimic the original pause
command.
Write-Host "Press any key to continue..."
[void][System.Console]::ReadKey($true)