Skip to main content

How to Read a Password Securely (without echo) in Batch Script

When writing interactive scripts that require sensitive information like a password, API key, or personal data, it is a critical security flaw to have the user's input displayed on the screen as they type. The standard SET /P command echoes every character to the console, making it unsuitable for secure entry. While Windows Batch has no direct, built-in command to mask password input, this functionality is available by calling a more powerful, modern tool: PowerShell.

This guide will explain why SET /P is insecure, and will teach you the definitive modern method for securely prompting for a password using a PowerShell one-liner. This is the only recommended approach, as there is no reliable "pure-batch" equivalent.

The Core Problem: SET /P Echoes Everything

The standard command for getting user input is SET /P. While it's great for normal input, it has no option to hide the user's typing.

The Insecure SET /P Method

@ECHO OFF
ECHO --- INSECURE PASSWORD PROMPT ---
SET /P "UserPassword=Enter your password: "
ECHO You entered: %UserPassword%

As the user types, their password is fully visible on the screen, which is a major security risk, especially in an office environment or if the session is being recorded.

--- INSECURE PASSWORD PROMPT ---
Enter your password: MySecretPassword!
You entered: MySecretPassword!
note

This method should never be used for sensitive data.

The correct and professional way to handle this is to call PowerShell from your batch script. PowerShell has built-in capabilities to read from the console in a secure manner. It can read the input without displaying it at all.

Syntax: This one-liner, executed from a FOR /F loop, is the key.

powershell -Command "$p = Read-Host -AsSecureString; $b = [System.Runtime.InteropServices.Marshal]::SecureStringToBSTR($p); [System.Runtime.InteropServices.Marshal]::PtrToStringAuto($b)"

This command is complex, but it is a robust, single-line solution to the problem.

Let's see an example of a Secure Password Prompt: this script uses the PowerShell one-liner to prompt the user for a password. The user's typing will be completely invisible.

@ECHO OFF
ECHO --- SECURE PASSWORD PROMPT ---
ECHO Your typing will not be visible. Press Enter when done.
ECHO.
SET /P "Username=Enter your username: "
ECHO Enter your password:
SET "UserPassword="

FOR /F "delims=" %%P IN (
'powershell -Command "$p = Read-Host -AsSecureString; $b = [System.Runtime.InteropServices.Marshal]::SecureStringToBSTR($p); [System.Runtime.InteropServices.Marshal]::PtrToStringAuto($b)"'
) DO (
SET "UserPassword=%%P"
)

ECHO.
ECHO --- For demonstration only ---
ECHO Username entered: %Username%
ECHO Password captured: %UserPassword%

Example of user usage and interaction: the cursor will blink, but nothing will appear on the screen as the user types their password.

--- SECURE PASSWORD PROMPT ---
Your typing will not be visible. Press Enter when done.

Enter your username: Admin
Enter your password:

Let's see how the PowerShell method works: the PowerShell command is a three-step pipeline designed to handle a SecureString object correctly.

  1. $p = Read-Host -AsSecureString: This is the core of the prompt. Read-Host captures user input. The -AsSecureString switch is what stops the input from being echoed to the screen and stores it in a special, encrypted SecureString object in memory.
  2. $b = [System.Runtime.InteropServices.Marshal]::SecureStringToBSTR($p): A SecureString cannot be used directly. This step uses the .NET Marshal class to convert the secure string into a temporary, unencrypted format (a BSTR) in memory.
  3. [System.Runtime.InteropServices.Marshal]::PtrToStringAuto($b): This final step converts the temporary, unencrypted BSTR into a regular, plain-text string that PowerShell can write to its output.

The FOR /F loop in the batch script then captures this plain-text output and stores it in the UserPassword variable.

Common Pitfalls and How to Solve Them

Problem: The User Needs to See Asterisks (*)

The Read-Host -AsSecureString command provides no visual feedback, which can be confusing for some users. Unfortunately, there is no simple way to make it display asterisks (****) from a one-liner. This behavior requires a more complex, multi-line PowerShell script. For the vast majority of batch script use cases, the invisible input is a standard and acceptable security practice.

Problem: Storing the Password in a Variable

Once the password has been captured into a batch variable (e.g., %UserPassword%), it is now stored in plain text in the cmd.exe process's memory. This is an unavoidable consequence of needing to use the password in a batch context.

Solution (Mitigation):

  • Use SETLOCAL: Always wrap your password-handling scripts in SETLOCAL and ENDLOCAL. This ensures that as soon as the script or subroutine finishes, the variable is completely destroyed and does not remain in the command session's memory.
  • Avoid ECHO: Never ECHO the password variable to the screen or to a log file, as that defeats the entire purpose of the secure entry.

Practical Example: A Secure Script Launcher

This script securely prompts for a username and password and then uses them as command-line arguments to launch another program (e.g., a database tool or a deployment utility).

@ECHO OFF
SETLOCAL
ECHO --- Secure Application Launcher ---
ECHO You will be prompted for your credentials.
ECHO.

SET /P "Username=Enter Username: "
ECHO Enter Password (input will be hidden):
SET "Password="

FOR /F "delims=" %%P IN (
'powershell -NoProfile -Command "$p=Read-Host -AsSecureString; $b=[System.Runtime.InteropServices.Marshal]::SecureStringToBSTR($p); [System.Runtime.InteropServices.Marshal]::PtrToStringAuto($b)"'
) DO (
SET "Password=%%P"
)

ECHO.
ECHO Credentials captured. Launching the application...
"C:\Program Files\MyTool\tool.exe" --user "%Username%" --password "%Password%"

ECHO.
ECHO --- Script Finished ---
ENDLOCAL

Conclusion

Securely prompting for a password is a task where the native capabilities of batch scripting are insufficient.

  • The standard SET /P command is insecure and must never be used for sensitive data.
  • There is no reliable "pure-batch" method to hide user input.
  • The PowerShell Read-Host -AsSecureString method is the only correct and recommended solution. It is a modern, secure, and robust command that is easily integrated into any batch script.

For any script that requires the user to enter a password or other secret information, the PowerShell one-liner is the professional and secure choice.