1

Powershell command used in BAT file is eliminating the escape character available in the password specified by user in the console and saving it in a file.

I have a BAT script which prompt the user to specify the password in console. Password should be masked as ***** while user typing it in console. Password will be something like wel!123. This password is saved into variable and finally getting copied to a text file. I got few suggestion use the below code in my BAT file, but the escape character in the actual password( Wel!123) is getting eliminated and saving the password as Wel123 into login.txt file.

SetLocal
set "psCmd=powershell -Command "$pwd = read-host 'Enter Your Password' - 
AsSecureString; $BSTR= 
[System.Runtime.InteropServices.Marshal]::SecureStringToBSTR($pwd); 
[System.Runtime.InteropServices.Marshal]::PtrToStringAuto($BSTR)""
for /F "usebackq delims=" %%# in (`%psCmd%`) do set "pwd=%%#"

@echo %pwd%>>login.txt
user78873
  • 97
  • 7
  • 2
    I recommend doing this entirely in Powershell. – UnhandledExcepSean Mar 26 '19 at 19:51
  • Can you tell me how to do it – user78873 Mar 26 '19 at 19:57
  • Possible duplicate of [Batch File Command Hide Password](https://stackoverflow.com/questions/36291324/batch-file-command-hide-password) – Squashman Mar 26 '19 at 20:11
  • You are missing some stuff in your code. The reason the `^` does not get written to `login.txt` is because the variable is expanded before execution and assumes you want to use the `^` as an escape character. You either need to escape the escape with string substitution or output the variable with delayed expansion. – Squashman Mar 26 '19 at 20:15
  • @Squashman: Good point re `^`, but note that the OP's problem is about `!`, so I suspect it is delayed expansion already being in effect that is actually the problem. – mklement0 Mar 26 '19 at 20:31
  • 1
    @mklement0, you are probably correct. I kept focusing on what the user was writing because they kept saying **ESCAPE**. The exclamation is not an escape. – Squashman Mar 26 '19 at 20:37

2 Answers2

1

To convert this to PowerShell, you have most of the code already written:

$pwd = Read-Host 'Enter Your Password' -AsSecureString
$BSTR = [System.Runtime.InteropServices.Marshal]::SecureStringToBSTR($pwd)
[System.Runtime.InteropServices.Marshal]::PtrToStringAuto($BSTR) | Add-Content -Path login.txt
AdminOfThings
  • 23,946
  • 4
  • 17
  • 27
1

! characters disappearing is unrelated to PowerShell - it suggests that cmd.exe's enabledelayedexpansion option is in effect, in which case ! serves as a variable-name delimiter - and in which case isolated ! chars. are simply discarded.

As an aside: ! is therefore not an escape character.

You therefore need to:

  • Disable delayed variable expansion with setLocal disabledelayedexpansion:

    • Note that delayed expansion is off by default, so something in your environment must have turned it on.
  • Additionally, as Squashman points out, ^ characters - cmd.exe's escape char. in unquoted strings - would be "eaten", so you must escape all ^ chars. as ^^, which can you do with %pwd:^=^^%.

To put it all together:

@echo off
setLocal disabledelayedexpansion

set "psCmd=powershell -Command "$pwd = read-host 'Enter Your Password' -AsSecureString; $BSTR=[System.Runtime.InteropServices.Marshal]::SecureStringToBSTR($pwd); [System.Runtime.InteropServices.Marshal]::PtrToStringAuto($BSTR)""

for /F "usebackq delims=" %%# in (`%psCmd%`) do set "pwd=%%#"

echo %pwd:^=^^%>>login.txt
mklement0
  • 382,024
  • 64
  • 607
  • 775