Masked Input

by Jul 27, 2023

To safely enter input, scripts need to display a masked input. The easiest way to do this is to use Read-Host -AsSecureString:

# Read-Host
$entered = Read-Host -Prompt 'Enter secret info' -AsSecureString

Or, you can use a function with a parameter of type [SecureString], and make this parameter mandatory:

# mandatory parameter
function test([Parameter(Mandatory)][SecureString]$Secret)
{
    "You entered secret: $Secret"
    return $Secret
}

# run function with mandatory parameter
$entered = test

This way, you get a masked input for free (displays as “stars” in a console window, and as a separate input box in ISE), however, you end up with a secure string, not plaintext. Here’s a simple function that you can use to convert the secure string back to plain text:

filter Convert-SecureStringToString
{
   param([Parameter(Mandatory,ValueFromPipeline)][SecureString]$SecureString
   [Runtime.InteropServices.Marshal]::
    PtrToStringAuto(
     [Runtime.InteropServices.Marshal]::
     SecureStringToBSTR($SecureString)
    )
} 

Now you can use masked inputs to ask for sensitive user information, and internally use it as plain text:

# Read-Host
$entered = Read-Host -Prompt 'Enter secret info' -AsSecureString | 
             Convert-SecureStringToString