Read individual keystrokes in PowerShell

Using PowerShell, I would like to read the value of keystrokes as they arise, without having to press the enter button. For example, if the user presses "1", I would like the PowerShell script to immediately respond to the selection without 'enter'.

ReadKey appeared in my research,

$ input = $ Host.UI.RawUI.ReadKey ('IncludeKeyDown');

But ReadKey returns much more information in the string than I need:

72, h, 0, True

While I can parse a keystroke from this line, I would prefer a more direct option. Does it exist?

+8
source share
3 answers

, , ReadKey KeyInfo, . KeyInfo VirtualKeyCode, Character, ControlKeyState KeyDown - . , , PowerShell .ToString() . , Character, . , 1:

$key = $Host.UI.RawUI.ReadKey()
if ($key.Character -eq '1') {
  "Pressed 1"
}
+10

$Host.UI.RawUI.ReadKey('IncludeKeyDown'); Goyuix .

$Host.UI.RawUI.ReadKey $Host.UI.RawUI.ReadKey [console].

. . , .

  • 1 = D1
  • 1 NumPad = NumPad1
  • a = A ( )
  • - = OemMinus ()

, [console]::ReadKey Key.

$key = [console]::ReadKey()
if ($key.Key -eq 'D1') {
  "Pressed 1"
}
+1

, .

.

  • PowerShell.
  • , , enter

.

:

1: Read-Host, Enter, ISE. /

2: ReadKey, , ISE... PowerShell. 2.

/ ,

##Formatting Variables
$fgc1 = 'cyan'
$fgc2 = 'white'
$indent = '  '

Function MainMenu {
    CLS
    Write-Host "###############"
    Write-Host "## Main Menu ##"
    Write-Host "###############"
    Write-Host -NoNewLine "$indent" "A " -ForegroundColor 'red'; Write-Host "== Options A" -ForegroundColor $fgc2
    Write-Host -NoNewLine "$indent" "B " -ForegroundColor 'red'; Write-Host "== Options B" -ForegroundColor $fgc2
    Write-Host -NoNewLine "$indent" "C " -ForegroundColor 'red'; Write-Host "== Options C" -ForegroundColor $fgc2
    Write-Host -NoNewLine "$indent" "D " -ForegroundColor 'red'; Write-Host "== Options D" -ForegroundColor $fgc2
    Write-Host -NoNewLine "$indent" "E " -ForegroundColor 'red'; Write-Host "== Options E" -ForegroundColor $fgc2
    Write-Host -NoNewLine "$indent" "F " -ForegroundColor 'red'; Write-Host "== Options F" -ForegroundColor $fgc2
    Write-Host -NoNewLine "$indent" "G " -ForegroundColor 'red'; Write-Host "== Options G" -ForegroundColor $fgc2
    Write-Host ""

    #This gives you a way to set the current function as a variable.  The Script: is there because the variable has to
    #be available OUTSIDE the function.  This way you can make it back to the menu that you came from as long as all 
    #of your menus are in functions!
    $Script:SourceMenu = $MyInvocation.MyCommand.Name

    # Mode 1#
    #Use this for troubleshooting so that you can stay in ISE
    # Uncomment the 2 lines below to use Read-Host.  This will necessitate an ENTER Key. BUT, it WILL work in ISE
    #$K = Read-Host - "Which option?"
    #MenuActions

    # Mode 2#
    #Uncomment the line below to use ReadKey.  This will NOT necessitate an ENTER Key. BUT, it ## will NOT work ## in ISE
    ReadKey
}

Function ReadKey {
    Write-Host "Please make your choice..."
    Write-Host ""
    Write-Host "Press Q to quit"
    $KeyPress = [System.Console]::ReadKey()

    #This gets the keypress to a common variable so that both modes work (Read-Host and KeyPress)
    $K = $KeyPress.Key

    #Jumps you down to the MenuActions function to take the keypress and "Switch" to it
    MenuActions
}

Function MenuActions {
    Switch ($K) {
        A {CLS;Write-Host "You Pressed A";Write-Host "Going to pause now... ";&pause}
        B {CLS;Write-Host "You pressed B";Write-Host "Going to pause now... ";&pause}
        C {CLS;Write-Host "You pressed C";Write-Host "Going to pause now... ";&pause}
        D {CLS;Write-Host "You pressed D";Write-Host "Going to pause now... ";&pause}
        E {CLS;Write-Host "You pressed E";Write-Host "Going to pause now... ";&pause}
        F {CLS;Write-Host "You pressed F";Write-Host "Going to pause now... ";&pause}
        G {CLS;Write-Host "You pressed G";Write-Host "Going to pause now... ";&pause}

        #This is a little strange of a process to exit out, but I like to use an existing mechanism to exit out
        #It sets the $SourceMenu to a process that will exit out.
        #I use this same process to jump to a different menu/sub-menu
        Q {$SourceMenu = "Exit-PSHostProcess";CLS;Write-Host "Exited Program"}
}
        #This next command will loop back to the menu you came from.  This, in essence, provides a validation that one of the 
        #"Switch ($X.key)" options were pressed.  This is also a good way to always find your way back to 
        #the menu you came from.  See "$Script:SourceMenu = $MyInvocation.MyCommand.Name" above.
        #
        #This is also the way that the Menu Item for Q exits out
    & $SourceMenu
}

# This runs the MainMenu function.  It has to be after all the functions so that they are defined before being called
MainMenu

:

$KeyPress = [System.Console]::ReadKey()

#This gets the keypress to a common variable so that both modes work (Read-Host and KeyPress)
$K = $KeyPress.Key
#
#Then do something with $K

, 2 ?

. ... ? , . ReadKey , :

Write-Host "Press the 2 character option you wish"
#Get KeyPress1 Variable
$KeyPress1 = [System.Console]::ReadKey()

#This gets the keypress to a common variable so that both modes work (Read-Host and KeyPress)
$K1 = $KeyPress1.Key

#Get KeyPress1 Variable
$KeyPress2 = [System.Console]::ReadKey()

#This gets the keypress to a common variable so that both modes work (Read-Host and KeyPress)
$K2 = $KeyPress2.Key

#This is just for troubleshooting to prove it works
CLS
Write-Host "This is the state of the variables right now"
Write-Host "Keypress1 is: $K1" -ForegroundColor Green
Write-Host "Keypress1 is: $K2" -ForegroundColor Green

$KEYS = "$K1"+"$K2"

Write-Host "The combined presses are: $KEYS" -ForegroundColor Red
pause

.

0

All Articles