powershelltimertriggersreadkey

PowerShell, break out of a timer with custom keypress


My timer below will countdown from $total_time down to 0, displaying a progress bar. This is fine, but how can I exit the loop and continue the script upon a custom keypress, such as 'ESC', or 'Enter', or 'Space', or 'm'?

How would I then have multiple custom exit options, e.g. 'x' would exit the loop and continue the script, 'p' to exit the loop and do some task (i.e. capture the key that was pressed and test on that for additional tasks), or other ways to manipulate during the countdown?

$total_time = 17   # Seconds in total to countdown
$interval = $total_time / 100   # There are always 100 percentage pips
$ms_per_pip = $interval * 1000

For ($i=0; $i -le 100; $i++) {   # Always 100 pips
    Start-Sleep -Milliseconds $ms_per_pip
    $remaining_time = [math]::Round($total_time - ($i * $ms_per_pip / 1000),2)
    Write-Progress -Activity "Sleeping For $total_time Seconds ($i% complete, $remaining_time Seconds left)" -Status "StatusString" -PercentComplete $i -CurrentOperation "CurrentOperationString"
}

Solution

  • You can use Console.KeyAvailable to check whether a key press is available in the input stream and then Console.ReadKey(bool) to get the pressed key, after that it's a simple if condition to check if the pressed key is in one of those characters of interest to signal the break of the loop. After that you can use a switch to act on the pressed key.

    for($i = 0; $i -le 100; $i++) {
        if([Console]::KeyAvailable) {
            $key = [Console]::ReadKey($true).Key
            if($key -in 'X', 'P') {
                break
            }
        }
        
        # rest of code here
    }
    
    switch($key) {
        X {
            'X was pressed'
            # do something with X
        }
        P {
            'P was pressed'
            # do something with P
        }
    }