Pause

Pause

Rate This
  • Comments 14

In the Newsgroup Microsoft.Public.Windows.PowerShell, BJ Stigall asked what the equivalent of the batch file PAUSE function was in PowerShell.

There were lots of good answers that came close but I think the one below comes the closest (and a little bit better).

function Pause ($Message="Press any key to continue...")
{
Write-Host -NoNewLine $Message
$null = $Host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown")
Write-Host ""
}

Here is an example of it in use:

PS> pause
Press any key to continue...
PS> pause "Press any key to win a million dollars..."
Press any key to win a million dollars...
PS>

Of course you can see me pressing a key but go ahead and use this function and see for yourself. The key was to realize that the ReadKey() function takes Options. How do you do that? Let me show you a trick:

PS> $host.UI.RawUI.ReadKey


MemberType : Method
OverloadDefinitions : {System.Management.Automation.Host.KeyInfo ReadKey(Re
adKeyOptions options),
System.Management.Automation.H
ost.KeyInfo ReadKey()}
TypeNameOfValue : System.Management.Automation.PSMethod
Value : System.Management.Automation.Host.KeyInfo ReadKey(Rea
dKeyOptions options), System.Management.Automation.Ho
st.KeyInfo ReadKey()
Name : ReadKey
IsInstance : True

What this is showing you is that in PowerShell, if you just provide the name of a method but don't call it by adding the (), we return the information about the method. This shows you that there is an overload that takes a parameter Options. From there I guessed that it would be in the same namespace as the method:

PS> [System.Management.Automation.Host.ReadKeyOptions]

IsPublic IsSerial Name BaseType
-------- -------- ---- --------
True True ReadKeyOptions System.Enum
PS>

This showed that it was an enum so the question then is – what are the values of the ENUM? I always just give a bad value and let PowerShell's error message tell me what the acceptable values are:

PS> [System.Management.Automation.Host.ReadKeyOptions]""
Cannot convert value "" to type "System.Management.Automation.Host.ReadKeyO
ptions" due to invalid enumeration values. Specify one of the following enu
meration values and try again. The possible enumeration values are "AllowCt
rlC, NoEcho, IncludeKeyDown, IncludeKeyUp"
.
At line:1 char:51
+ [System.Management.Automation.Host.ReadKeyOptions] <<<<
""
PS>

I realized that I wanted NOECHO (this was a the behavior in CMD.EXE's PAUSE that the other answers didn't replicate). I tried that and got a error (Notice that I just provide a STRING "NoEcho" and PowerShell does the rest for me:

PS> $host.UI.RawUI.ReadKey("NoEcho")
Exception calling "ReadKey" with "1" argument(s): "Cannot read key options.
To read options either IncludeKeyDown,IncludeKeyUp or both must be set."
At line:1 char:23
+ $host.UI.RawUI.ReadKey <<<< ("NoEcho")
PS>

The error message is telling me that I must also do a bit OR with IncludeKeyDown or IncludeKeyUp so that only other trick was to realize that you could use a "," in the string and PowerShell does that for you.

PS> $host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown")

VirtualKeyCode Character ControlKeyState KeyDown
-------------- --------- --------------- -------
65 a 0 True


PS>

Of course this then tells you what the user typed which we don't want so we just assign this to $NULL and Bobs' your uncle!

PS> $null = $host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown")
PS>

Cheers!

BTW – if you are reading the blog after the weekend, please don't miss this entry Supporting –Whatif, -Confirm, -Verbose in Scripts – it is super important.

Jeffrey Snover [MSFT]
Windows PowerShell/MMC Architect
Visit the Windows PowerShell Team blog at: http://blogs.msdn.com/PowerShell
Visit the Windows PowerShell ScriptCenter at: http://www.microsoft.com/technet/scriptcenter/hubs/msh.mspx

Leave a Comment
  • Please add 2 and 3 and type the answer here:
  • Post
  • In the Hey Scripting Guy article : How Can I Monitor Event Log Messages for Specific Words? , a WMI eventwatcher

  • Can PAUSE be used to pause a running application if not how can I pause a running application using powershell.

    Thanks in advance.

  • Isn't it more elegantly to get the valid values for an enum using the following code?

    [System.Enum]::GetNames(<type>)

    In this case:

    [System.Enum]::GetNames([System.Management.Automation.Host.ReadKeyOptions])

  • Great article!

    In PowerShell 2 CTP3 I get:

    Press any key to continue...Exception calling "ReadKey" with "1" argument(s): "The method or operation is not implemented."

    So, I solved the problem by just calling .ReadKey with no arguments instead.

  • I'm getting a similar error, but only when I run my script within Powershell ISE (Win 7 Pro).

    Press any key to exit

    Exception calling "ReadKey" with "1" argument(s): "The method or operation is not implemented."

    At C:\Users\jma6a\Scripts\HAMemCheck.ps1:31 char:32

    +     $null = $host.UI.RawUI.ReadKey <<<< ("NoEcho,IncludeKeyDown")

       + CategoryInfo          : NotSpecified: (:) [], MethodInvocationException

       + FullyQualifiedErrorId : DotNetMethodException

    Otherwise, it runs fine in a Powershell console.  

    If I remove the arguments as Chris Patti suggested, I don't receive the error but it does not pause.

    Any ideas?

  • RE: the ReadKey exceptions

    I found that this exception only occurs when called from the ISE.  It works fine at the console (which is where I want to use it).  Use the snippet below to account for that:

    function Pause ($Message="Press any key to continue...")

    {

       # The ReadKey functionality is only supported at the console (not is the ISE)

       if (!$psISE)

       {

           Write-Host -NoNewLine $Message

           $null = $Host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown")

           Write-Host ""

       }

    }

  • I may have omitted a '!' from my last comment.  Please go ahead and edit that post if you could.

  • See Using the Start-Sleep Cmdlet

    http://technet.microsoft.com/en-us/library/ee177002.aspx

  • I'm not using the ISE, but PowerGui Script Editor instead.. so modded the above script so that it ONLY waits for keystroke if running in the console, otherwise sleeps for 3 sec.

    # Function that pauses until user presses a key if in the powershell console or sleep for 3 secs

    function Pause (

    [string] $Message="Press any key to continue..."

    )

    {

      # The ReadKey functionality is only supported at the console (not is the ISE)

      if (((Get-Host).Name) -eq 'ConsoleHost')

      {

          Write-Host -NoNewLine $Message

          $null = $Host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown")

          Write-Host ""

      } else {

          Write-Host "$Message`n  Not running in console, so sleep for 5 seconds"

      Start-Sleep -Seconds 3

      }

    }

  • Is there a way to associate a particular Keyboard key to a Cmdlet in Powershell???

  • I appreciate this blog post! Unfortunately, the script has two things wrong with it. The first thing has already been pointed out by others, and that is that it doesn't work from within Windows PowerShell ISE. The second thing, though, is that, unlike cmd.exe's "Pause" command, pressing keys like Ctrl and Alt causes the script to continue. I came up with a function that resolves both of these things:

    adamstech.wordpress.com/.../how-to-properly-pause-a-powershell-script

    For the record, I'm not trying to spam; I'm trying to be of help to others.

  • Your example is broken, I didn't get a million dollars. :O

  • Wouldn't it be better to pipe it to Out-Null instead?

    $host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown") | Out-Null

  • I using a New-PSDrive cmdlet and it appears that it is taking too long to map the drive.

    Is there a way to have a timed pause?  Pause for 30 seconds and then continue.

Page 1 of 1 (14 items)