135

OK, I'm losing it. PowerShell is annoying me. I'd like a pause dialog to appear, and it won't.

PS W:\>>> $host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown")
Exception calling "ReadKey" with "1" argument(s): "The method or operation is not implemented."
At line:1 char:23
+ $host.UI.RawUI.ReadKey <<<< ("NoEcho")
    + CategoryInfo          : NotSpecified: (:) [], MethodInvocationException
    + FullyQualifiedErrorId : DotNetMethodException
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Derrick Bell
  • 2,615
  • 3
  • 26
  • 30
  • 1
    I had the same problem in PowerShell ISE. Works fine in the standard PowerShell console though. – Charles Anderson Nov 30 '11 at 09:55
  • 3
    I'm just messing with powershell and it's still annoying as hell, even 2 1/2 years later! – Bill K Apr 12 '13 at 15:44
  • If you read the [Adam's Tech link](http://adamstech.wordpress.com/2011/05/12/how-to-properly-pause-a-powershell-script/) or the code in [@Michael Sorens answer](https://stackoverflow.com/a/22362868/4582204) (about halfway down the page as I write this in 2020) you may discover a technique of wrapping your pause in `if (!$psise) { <# pause #> }`. If you're like me and 99% of the reason you want a pause is so that you can read the screen before it blinks away, then this will help, because if you're in the ISE it does not blink away and you don't need the pause – john v kumpf May 01 '20 at 19:45

9 Answers9

275

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!
Michael Sorens
  • 35,361
  • 26
  • 116
  • 172
  • 9
    Best answer, especially because it provides solution that works everywhere – Petr Mar 14 '14 at 14:35
  • Great answer! I'd like to note that adding the `AllowCtrlC` parameter to choice 2 allows the user to click Ctrl + C without terminating the script. Nevertheless, this choice still doesn't properly excludes the Ctrl modifier key. (it acts just as if the user clicks only on the Ctrl key) Reference: [Microsoft TechNet - Windows PowerShell Tip: Press Any Key to Continue](https://technet.microsoft.com/en-us/library/ff730938.aspx) – Oz Edri Dec 13 '15 at 12:49
  • 2
    Option 3 and 5 have another disadvantage: doesn't work on linux – bitbonk Nov 04 '16 at 09:32
  • @bitbonk If you're working in Linux.... why PowerShell? Just why? Use Bash. – Chris Collett Jan 20 '21 at 16:54
  • Because I don’t want to maintain multiple scripts, one for each OS. One script for Mac, Linux and Windows should suffice, which is powershell in my case. – bitbonk Jan 20 '21 at 16:58
  • One-liner for <5> option could be: `(New-Object -ComObject "WScript.Shell").Popup("Click OK to continue.", 0, "Script Paused", 0)`, but it looks somewhat ugly... – realsonic May 13 '21 at 12:12
97
cmd /c pause | out-null

(It is not the PowerShell way, but it's so much more elegant.)

Save trees. Use one-liners.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Carlos Nunez
  • 2,047
  • 1
  • 18
  • 20
  • 7
    /c Carries out the command specified by string and then terminates | out-null pipes the output to out-null, where you'll never see it If you want to see the "Press any key to continue..." message, remove the pipe. Also, this doesn't seem to work in PowerShell ISE. The process simply gets stuck, and you can't press any key. Any way around that? – Wouter Oct 19 '12 at 09:41
  • 1
    @Wouter See this blog post: [How to Properly Pause a PowerShell Script](http://adamstech.wordpress.com/2011/05/12/how-to-properly-pause-a-powershell-script/) – Nick Dec 14 '12 at 03:52
  • 9
    @Nick yes, 47 lines of code to replace "cmd /c pause | out-null", that sound like the PowerShell way. – Bill K Apr 12 '13 at 15:46
  • @BillK The post I linked to answers Wouter's question. Do you disagree? – Nick Apr 12 '13 at 15:56
  • 7
    It wasn't a commentary on your answer, I think you are totally right. It's a commentary on PowerShell. I'm moderately disgusted--I haven't seen this much pointless obscuring verbosity since I programmed in Cobol. – Bill K Apr 12 '13 at 16:18
46

I assume that you want to read input from the console. If so, use Read-Host -Prompt "Press Enter to continue".

Akira Yamamoto
  • 4,685
  • 4
  • 42
  • 43
rerun
  • 25,014
  • 6
  • 48
  • 78
  • 5
    Ditto - Maybe add the prompt text pilfered from below.. Read-Host -Prompt "Press Enter to continue" – Jon H Dec 08 '15 at 10:37
  • doesn't pause for me for some reason. I'm calling powershell inside a `.bat` script. – xjcl Mar 09 '21 at 18:28
22

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)
Ro Yo Mi
  • 14,790
  • 5
  • 35
  • 43
  • Technically ISE is out of scope because the original question only asked about Powershell 2.0 and excluded ISE. If you're using ISE, then just use a breakpoint. – Ro Yo Mi Aug 08 '17 at 13:19
  • 4
    1. I don't agree ISE was out of scope, but that's irrelevant now. 2. I was noting it doesn't work in the ISE to assist passers-by on this question. – Bill_Stewart Aug 11 '17 at 09:10
5

In addition to Michael Sorens' answer:

<6> ReadKey in a new process

Start-Process PowerShell {[void][System.Console]::ReadKey($true)} -Wait -NoNewWindow
  • Advantage: Accepts any key but properly excludes Shift, Alt, Ctrl modifier keys.
  • Advantage: Works in PS-ISE.
iRon
  • 20,463
  • 10
  • 53
  • 79
3

10 years later i came here.... Don't know since when, but "pause" works in PowerShell like it did in DOS-commandline.

UdeF
  • 255
  • 3
  • 14
  • Thank you for the update! It answers more than one question I was having, strangely enough. – phrebh May 31 '22 at 17:54
1

You may want to use FlushInputBuffer to discard any characters mistakenly typed into the console, especially for long running operations, before using ReadKey:

Write-Host -NoNewLine 'Press any key to continue...'
$Host.UI.RawUI.FlushInputBuffer()
$Host.UI.RawUI.ReadKey('NoEcho,IncludeKeyDown') | Out-Null
Teraokay
  • 120
  • 6
1

If you want to add a timer to the press any key, this works in PS 5.1:

 $i=1
 while (
                 !([Console]::KeyAvailable) -and 
                 ($i -le 10)
            ) {
           sleep 1
           Write-Host “$i..” -NoNewLine
           $i++
 }

Note that the KeyAvailable method for the c# $Host.UI.RawUI is currently bugged in a number of PS versions after PS 2 or 3.

Blaisem
  • 557
  • 8
  • 17
0

One-liner for PS-ISE in option <5> in Michael Sorens' answer:

[Void][Windows.Forms.MessageBox]::Show("Click OK to continue.", "Script Paused")
loxia_01
  • 13
  • 3