Wait for input, then timeout to default

This topic contains 2 replies, has 3 voices, and was last updated by Profile photo of Matt Bloomfield Matt Bloomfield 10 months, 3 weeks ago.

  • Author
  • #32673
    Profile photo of John Muirhead
    John Muirhead


    Am a veritable PowerShell noob, so please bear with me if this question it foolish and/or obvious. Ok, disclaimer taken care of. Here goes:

    Designing a script that waits for user input selections. Something to the effect of this below:

    Do {
    Write-Host "Selection (A-C)?: " -NoNewLine

    $Answer = Read-Host
    Until("A","B","C" -ccontains $Answer.ToUpper())

    Works great. However, what I'd really like to do is enforce a default (say force option "A") and exit the loop if 90 seconds (for example) have passed without input.

    Possible? Again, relatively new to PS, so it's not obvious to me.


  • #32681
    Profile photo of Don Jones
    Don Jones

    PowerShell's Read-Host can't do what you'e asking, no. Broadly speaking, this isn't what PowerShell's main use case is. It isn't strictly intended to be an event-based user interface responder, and its ability to present user interface – without getting into WinForms or something complex – is fairly primitive. It's mean to be run as directives, meaning you tell it what to do by running commands, not by displaying menus. I'm not saying you absolutely cannot do what you're asking – just that it's going to be a lot more complex than you may realize, so you need to decide if it's worth a lot of extra coding, much of which will essentially be .NET coding.

  • #32685
    Profile photo of Matt Bloomfield
    Matt Bloomfield

    This was much harder to do than I expected. I read several examples online where people have tried to achieve similar results. Using some of them as inspiration, I have come up with the following which pretty much achieves the objective.

    The loop runs until a key is pressed or until the timeout period is reached. If a key is pressed, the key is read and assigned to $response. If no key has been pressed, then $response is assigned a default value. I have just written out $response but it could be passed to a Switch construct to implement menu functionality.

    Note: this won't work in the ISE, only in the PowerShell console.

    function Read-KeyOrTimeout {
               [int]$seconds = 5,
            [string]$prompt = 'Hit a key',
            [string]$default = 'A'
        $startTime = Get-Date
        $timeOut = New-TimeSpan -Seconds $seconds
        Write-Host $prompt
        while (-not $host.ui.RawUI.KeyAvailable) {
            $currentTime = Get-Date
            if ($currentTime -gt $startTime + $timeOut) {
        if ($host.ui.RawUI.KeyAvailable) {
            [string]$response = ($host.ui.RawUI.ReadKey("IncludeKeyDown,NoEcho")).character
        else {
            $response = $default
        Write-Output "You typed $($response.toUpper())"

You must be logged in to reply to this topic.