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!
This method should never be used for sensitive data.
The Superior Method (Recommended): Using PowerShell
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.
$p = Read-Host -AsSecureString: This is the core of the prompt.Read-Hostcaptures user input. The-AsSecureStringswitch is what stops the input from being echoed to the screen and stores it in a special, encryptedSecureStringobject in memory.$b = [System.Runtime.InteropServices.Marshal]::SecureStringToBSTR($p): ASecureStringcannot be used directly. This step uses the .NETMarshalclass to convert the secure string into a temporary, unencrypted format (a BSTR) in memory.[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 inSETLOCALandENDLOCAL. 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: NeverECHOthe 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 /Pcommand 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 -AsSecureStringmethod 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.