windowspowershellwinapi

Is there way to turn off `ECHO` user input in `powershell`


Linux has have stty -echo which make off typing so it is not echoed back to user.

So basically what you're typing is not seen on the shell.

Is there way to do the same in powershell?


Solution

  • As it turns out, your intent was to suppress echoing of commands provided via stdin to the PowerShell CLI (powershell.exe for Windows PowerShell, pwsh for PowerShell (Core) 7):

    To do so, use -Command - (-c -), which - like -File - (-f -, the default behavior) - accepts (independent) commands one by one via stdin, but - unlike -File - - neither prints a prompt string nor echoes the command provided:

    # OK: Just the piped command's *output* prints.
    PS> 'Get-Date' | powershell.exe -Command -
    
    Friday, September 3, 2021 10:08:07 AM
    
    
    # Pseudo-interactive behavior:
    # The piped command's output is: 
    #  * *preceded by* the prompt string as well as the input command.
    #  * *followed by* another rendering of the prompt string.
    PS> 'Get-Date' | powershell.exe -File -
    
    PS C:\Users\jdoe> Get-Date
    
    Friday, September 3, 2021 10:09:44 AM
    
    PS C:\Users\jdoe>
    

    Note: In the examples above, a single command is provided via stdin (via the pipeline), and since no more stdin input is provided, the PowerShell process exits. However, in scenarios where you keep stdin open, you'll be able to feed commands - one by one - to the PowerShell process indefinitely.

    Caveat: Both -File - and -Command - exhibit problematic, pseudo-interactive behavior; notably, a command spanning multiple lines must be terminated with two newlines; see GitHub issue #3223 for details.

    Note:


    On a loosely related note (prompted by a misreading of the question's intent), the following discusses:

    How to hide or mask interactive user input solicited via the Read-Host cmdlet:

    There is no built-in PowerShell feature that hides what the user types, but if the intent is simply to mask user input, so as to hide sensitive information being typed, such as a password, you have two options - both of which mask each character typed printing * instead:

    Use Read-Host -AsSecureString:

    $valueEnteredSecure = Read-Host -AsSecureString -Prompt 'Enter your password'
    

    Note that this outputs a System.Security.SecureString instance (which provides limited security on Windows, and virtually none on Unix-like platforms),[1] which you can convert back to a regular string as follows:

    $valueEntered = [System.Net.NetworkCredential]::new('', $valueEnteredSecure).Password
    

    In PowerShell (Core) 7, you can alternatively use (though note the simpler overall solution further below):

    $valueEntered = ConvertFrom-SecureString $valueEnteredSecure -AsPlainText
    

    PowerShell (Core) 7 now supports a -MaskInput switch that exhibits the same UI behavior, but directly returns a regular, plain-text string:

    # PowerShell 7 only (since v7.1)
    $valueEntered = Read-Host -MaskInput -Prompt 'Enter your password'
    

    If truly suppressing the display of all characters typed by the user is a must, you'll have to create a custom solution that uses $host.ui.RawUI.ReadKey('NoEcho') in a loop:

    Here's a simple implementation, which you can call as
    $valueEntered = Read-HostSilent -Prompt 'Enter your password', for instance:

    function Read-HostSilent {
      param([string] $Prompt)
      if ($Prompt) { Write-Host -NoNewline "${Prompt}: " }
      $entered = $null; $done = $false
      do {
        $key = $host.ui.RawUI.ReadKey('NoEcho')
        switch ($key.VirtualKeyCode) {
          # Backspace
          8 { if ($entered.Length -gt 1) { $entered = $entered.Substring(0, $entered.Length-1) } }
          # Enter
          13 { $done = $true; break }
          default {
            if ($key.Character) { # printable?
              $entered += $key.Character
            }
          }
        }
      } while (-not $done)
      $entered # output
    }
    

    [1] See this answer for more information.