我可以屏蔽 bat 文件中的输入文本吗?

发布于 2024-07-15 12:52:22 字数 247 浏览 11 评论 0 原文

我正在编写一个批处理文件来执行其他一些程序。 在这种情况下,我需要提示输入密码。 我有什么方法可以屏蔽输入文本吗? 我不需要打印********字符而不是输入字符。 Linux 的密码提示行为(键入时不打印任何内容)就足够了。

@echo off
SET /P variable=Password : 
echo %variable%
Pause

这将读取输入,但我无法使用这种方法屏蔽文本。

I am writing a batch file to execute some other programs. In this case I need to prompt for a password. Do I have any way to mask the input text? I don't need to print ******* characters instead of input characters. Linux's Password prompt behavior (Print nothing while typing) is enough.

@echo off
SET /P variable=Password : 
echo %variable%
Pause

This will read the input but I can't mask the text using this approach.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(19

○愚か者の日 2024-07-22 12:52:23

是的——我迟到了四年。

但我找到了一种方法可以在一行中完成此操作,而无需创建外部脚本; 通过从批处理文件调用 powershell 命令。

感谢 TessellationHeckler - 无需输出到文本文件(我在变量中设置了 powershell 命令,因为它在 for 循环内的一长行中非常混乱)。

@echo off
set "psCommand=powershell -Command "$pword = read-host 'Enter Password' -AsSecureString ; ^
    $BSTR=[System.Runtime.InteropServices.Marshal]::SecureStringToBSTR($pword); ^
        [System.Runtime.InteropServices.Marshal]::PtrToStringAuto($BSTR)""
for /f "usebackq delims=" %%p in (`%psCommand%`) do set password=%%p
echo %password%

最初我将其编写为输出到文本文件,然后从该文本文件中读取。 但上面的方法比较好。 在一个非常长、几乎难以理解的行中:

@echo off
powershell -Command $pword = read-host "Enter password" -AsSecureString ; $BSTR=[System.Runtime.InteropServices.Marshal]::SecureStringToBSTR($pword) ; [System.Runtime.InteropServices.Marshal]::PtrToStringAuto($BSTR) > .tmp.txt & set /p password=<.tmp.txt & del .tmp.txt
echo %password%

我将把它分解 - 你可以使用脱字符号 ^ 将其分成几行,这要好得多......

@echo off
powershell -Command $pword = read-host "Enter password" -AsSecureString ; ^
    $BSTR=[System.Runtime.InteropServices.Marshal]::SecureStringToBSTR($pword) ; ^
        [System.Runtime.InteropServices.Marshal]::PtrToStringAuto($BSTR) > .tmp.txt 
set /p password=<.tmp.txt & del .tmp.txt
echo %password%

本文 解释 powershell 命令正在做什么; 本质上,它使用 Read-Host -AsSecureString 获取输入 - 以下两行将该安全字符串转换回纯文本,然后使用 > 将输出(纯文本密码)发送到文本文件.tmp.txt。 然后将该文件读入变量并删除。

Yes - I am 4 years late.

But I found a way to do this in one line without having to create an external script; by calling powershell commands from a batch file.

Thanks to TessellatingHeckler - without outputting to a text file (I set the powershell command in a variable, because it's pretty messy in one long line inside a for loop).

@echo off
set "psCommand=powershell -Command "$pword = read-host 'Enter Password' -AsSecureString ; ^
    $BSTR=[System.Runtime.InteropServices.Marshal]::SecureStringToBSTR($pword); ^
        [System.Runtime.InteropServices.Marshal]::PtrToStringAuto($BSTR)""
for /f "usebackq delims=" %%p in (`%psCommand%`) do set password=%%p
echo %password%

Originally I wrote it to output to a text file, then read from that text file. But the above method is better. In one extremely long, near incomprehensible line:

@echo off
powershell -Command $pword = read-host "Enter password" -AsSecureString ; $BSTR=[System.Runtime.InteropServices.Marshal]::SecureStringToBSTR($pword) ; [System.Runtime.InteropServices.Marshal]::PtrToStringAuto($BSTR) > .tmp.txt & set /p password=<.tmp.txt & del .tmp.txt
echo %password%

I'll break this down - you can split it up over a few lines using caret ^, which is much nicer...

@echo off
powershell -Command $pword = read-host "Enter password" -AsSecureString ; ^
    $BSTR=[System.Runtime.InteropServices.Marshal]::SecureStringToBSTR($pword) ; ^
        [System.Runtime.InteropServices.Marshal]::PtrToStringAuto($BSTR) > .tmp.txt 
set /p password=<.tmp.txt & del .tmp.txt
echo %password%

This article explains what the powershell commands are doing; essentially it gets input using Read-Host -AsSecureString - the following two lines convert that secure string back into plain text, the output (plaintext password) is then sent to a text file using >.tmp.txt. That file is then read into a variable and deleted.

何止钟意 2024-07-22 12:52:23

在 XP 和 Server 2003 之前,您可以使用另一个附带的工具 (VBScript) - 以下两个脚本可以完成您想要的工作。

首先,getpwd.cmd

@echo off
<nul: set /p passwd=Password: 
for /f "delims=" %%i in ('cscript /nologo getpwd.vbs') do set passwd=%%i
echo.

然后,getpwd.vbs

Set oScriptPW = CreateObject("ScriptPW.Password")
strPassword = oScriptPW.GetPassword()
Wscript.StdOut.WriteLine strPassword

getpwd.vbs只是使用密码对象来输入用户的密码,然后然后将其打印到标准输出(下一段将解释为什么它没有显示在终端中)。

getpwd.cmd 命令脚本有点棘手,但其基本工作原理如下。

" 命令的作用是输出不带尾随换行符的提示符 - 这是模拟 "echo -n 的一种偷偷摸摸的方式来自 bash shell 的“ 命令。 它将 passwd 设置为空字符串,作为不相关的副作用,并且不等待输入,因为它从 nul: 设备获取输入。

"for /f "delims=" %%i in ('cscript /nologo getpwd.vbs') do set passwd=%%i" 语句是最棘手的部分。 它运行 VBScript 时没有 Microsoft“广告”,因此唯一的行输出是密码(来自 VBscript “Wscript.StdOut.WriteLine strPassword”)。

将分隔符设置为空不需要捕获密码。整个输入行都包含空格,否则您只会得到第一个单词“for ... do set ...”位将 passwd 设置为实际的密码输出。 我们回显一个空行(以终止 "Password: " 行) ,

代码运行后密码将位于 passwd 环境变量中。


然后 如上所述,scriptpw.dll 仅适用于 XP/2003。为了纠正此问题,您只需从 复制 scriptpw.dll 文件即可。将 DLL 复制到 XP/2003 系统的 Windows\System32 文件夹到您自己系统上的 Winnt\System32Windows\System32 文件夹中。您需要通过运行来注册它:

regsvr32 scriptpw.dll

要在 Vista 及更高版本上成功注册 DLL,您将需要管理员权限。 我还没有研究过这样的举动的合法性,所以洞穴讲师。


如果您不太热衷于尝试追踪和注册旧的 DLL 文件(出于方便或法律原因),还有另一种方法。 更高版本的 Windows(没有具有所需 DLL 的版本)应该可以使用 Powershell。

事实上,您确实应该考虑升级脚本以充分使用它,因为它是一种比 cmd.exe 更强大的脚本语言。 但是,如果您希望将大部分代码保留为 cmd.exe 脚本(例如,如果您有很多代码不想转换) ,你可以使用同样的技巧。

首先,修改 cmd 脚本,使其调用 Powershell 而不是 CScript:

@echo off
for /f "delims=" %%i in ('powershell -file getpwd.ps1') do set passwd=%%i

Powershell 脚本同样简单:

$password = Read-Host "Enter password" -AsSecureString
$password = [Runtime.InteropServices.Marshal]::SecureStringToBSTR($password)
$password = [Runtime.InteropServices.Marshal]::PtrToStringAuto($password)
echo $password

尽管需要进行一些编组来获取实际的密码文本。

请记住,要在计算机上运行本地未签名的 Powershell 脚本,您可能需要从(严格的,但非常安全的)默认值修改执行策略,例如:

set-executionpolicy remotesigned

从 Powershell 本身内部。

Up to XP and Server 2003, you can make use of another included tool (VBScript) - the following two scripts do the job you want.

First, getpwd.cmd:

@echo off
<nul: set /p passwd=Password: 
for /f "delims=" %%i in ('cscript /nologo getpwd.vbs') do set passwd=%%i
echo.

Then, getpwd.vbs:

Set oScriptPW = CreateObject("ScriptPW.Password")
strPassword = oScriptPW.GetPassword()
Wscript.StdOut.WriteLine strPassword

The getpwd.vbs simply uses the password object to input the password from the user and then print it to standard output (the next paragraph will explain why that doesn't show up in the terminal).

The getpwd.cmd command script is a bit trickier but it basically works as follows.

The effect of the "<nul: set /p passwd=Password: " command is to output the prompt with no trailing newline character - it's a sneaky way to emulate the "echo -n" command from the bash shell. It sets passwd to an empty string as an irrelevant side effect and doesn't wait for input since it's taking its input from the nul: device.

The "for /f "delims=" %%i in ('cscript /nologo getpwd.vbs') do set passwd=%%i" statement is the trickiest bit. It runs the VBScript with no Microsoft "advertising", so that the only line output is the password (from the VBscript "Wscript.StdOut.WriteLine strPassword".

Setting the delimiters to nothing is required to capture an entire input line with spaces, otherwise you just get the first word. The "for ... do set ..." bit sets passwd to be the actual password output from the VBScript.

Then we echo a blank line (to terminate the "Password: " line) and the password will be in the passwd environment variable after the code has run.


Now, as mentioned, scriptpw.dll is available only up to XP/2003. In order to rectify this, you can simply copy the scriptpw.dll file from the Windows\System32 folder of an XP/2003 system to the Winnt\System32 or Windows\System32 folder on your own system. Once the DLL has been copied, you will need to register it by running:

regsvr32 scriptpw.dll

To successfully register the DLL on Vista and later, you will need administrator privileges. I haven't examined the legality of such a move so cave lector.


If you're not overly keen on trying to track down and register older DLL files (for convenience or legal reasons), there is another way. Later versions of Windows (the ones that don't have the required DLL) should have Powershell available to you.

And, in fact, you really should consider upgrading your scripts to use it fully since it's a much more capable scripting language than cmd.exe. However, if you want to keep the bulk of your code as cmd.exe scripts (such as if you have a lot of code that you don't want to convert), you can use the same trick.

First, modify the cmd script so it calls Powershell rather than CScript:

@echo off
for /f "delims=" %%i in ('powershell -file getpwd.ps1') do set passwd=%%i

The Powershell script is equally simple:

$password = Read-Host "Enter password" -AsSecureString
$password = [Runtime.InteropServices.Marshal]::SecureStringToBSTR($password)
$password = [Runtime.InteropServices.Marshal]::PtrToStringAuto($password)
echo $password

although with some marshalling to get the actual password text.

Remember that, to run local unsigned Powershell scripts on your machine, you may need to modify the execution policy from the (draconian, though very safe) default, with something like:

set-executionpolicy remotesigned

from within Powershell itself.

久隐师 2024-07-22 12:52:23

1.纯批处理解决方案(ab)使用XCOPY命令及其/P /L开关此处(对此进行一些改进在此处找到):

:: Hidden.cmd
::Tom Lavedas, 02/05/2013, 02/20/2013
::Carlos, 02/22/2013
::https://groups.google.com/forum/#!topic/alt.msdos.batch.nt/f7mb_f99lYI


@Echo Off
:HInput
SetLocal EnableExtensions EnableDelayedExpansion
Set "FILE=%Temp%.\T"
Set "FILE=.\T"
Keys List >"%File%"
Set /P "=Hidden text ending with Ctrl-C?: " <Nul
Echo.
Set "HInput="
:HInput_
For /F "tokens=1* delims=?" %%A In (
 '"Xcopy /P /L "%FILE%" "%FILE%" 2>Nul"'
) Do (
  Set "Text=%%B"
  If Defined Text (
    Set "Char=!Text:~1,1!"
    Set "Intro=1"
    For /F delims^=^ eol^= %%Z in ("!Char!") Do Set "Intro=0"
    Rem If press Intro
    If 1 Equ !Intro! Goto :HInput#
    Set "HInput=!HInput!!Char!"
  )
)
Goto :HInput_
:HInput#
Echo(!HInput!
Goto :Eof 

1.2 另一种基于替换命令的方式

@Echo Off
SetLocal EnableExtensions EnableDelayedExpansion

Set /P "=Enter a Password:" < Nul
Call :PasswordInput
Echo(Your input was:!Line!

Goto :Eof

:PasswordInput
::Author: Carlos Montiers Aguilera
::Last updated: 20150401. Created: 20150401.
::Set in variable Line a input password
For /F skip^=1^ delims^=^ eol^= %%# in (
'"Echo(|Replace.exe "%~f0" . /U /W"') Do Set "CR=%%#"
For /F %%# In (
'"Prompt $H &For %%_ In (_) Do Rem"') Do Set "BS=%%#"
Set "Line="
:_PasswordInput_Kbd
Set "CHR=" & For /F skip^=1^ delims^=^ eol^= %%# in (
'Replace.exe "%~f0" . /U /W') Do Set "CHR=%%#"
If !CHR!==!CR! Echo(&Goto :Eof
If !CHR!==!BS! (If Defined Line (Set /P "=!BS! !BS!" <Nul
Set "Line=!Line:~0,-1!"
)
) Else (Set /P "=*" <Nul
If !CHR!==! (Set "Line=!Line!^!"
) Else Set "Line=!Line!!CHR!"
)
Goto :_PasswordInput_Kbd

2.使用HTA弹出窗口的密码提交器
这是一个 hybrit .bat/jscript/mshta 文件,应另存为.bat

<!-- :
:: PasswordSubmitter.bat
@echo off
for /f "tokens=* delims=" %%p in ('mshta.exe "%~f0"') do (
    set "pass=%%p"
)

echo your password is %pass%
exit /b
-->

<html>
<head><title>Password submitter</title></head>
<body>

    <script language='javascript' >
        window.resizeTo(300,150);
        function entperPressed(e){
                if (e.keyCode == 13) {
                    pipePass();
                }
        }
        function pipePass() {
            var pass=document.getElementById('pass').value;
            var fso= new ActiveXObject('Scripting.FileSystemObject').GetStandardStream(1);
            close(fso.Write(pass));

        }
    </script>

    <input type='password' name='pass' size='15' onkeypress="return entperPressed(event)" ></input>
    <hr>
    <button onclick='pipePass()'>Submit</button>

</body>
</html>

3.< a href="http://www.dostips.com/forum/viewtopic.php?f=3&t=5260">自编译的 .net 混合体。再次应另存为.bat . 与其他解决方案它将创建/编译一个将被调用的小 .exe 文件(如果您希望可以删除它)。 还需要安装 .net 框架,但这不是问题:

@if (@X)==(@Y) @end /* JScript comment
@echo off
setlocal enableDelayedExpansion

for /f "tokens=* delims=" %%v in ('dir /b /s /a:-d  /o:-n "%SystemRoot%\Microsoft.NET\Framework\*jsc.exe"') do (
   set "jsc=%%v"
)

if not exist "%~n0.exe" (
    "%jsc%" /nologo /out:"%~n0.exe" "%~dpsfnx0"
)

for /f "tokens=* delims=" %%p in ('"%~n0.exe"') do (
    set "pass=%%p"
)

echo your password is !pass!

endlocal & exit /b %errorlevel%

*/



import System;



var pwd = "";
var key;

Console.Error.Write("Enter password: ");

        do {
           key = Console.ReadKey(true);

           if ( (key.KeyChar.ToString().charCodeAt(0)) >= 20 && (key.KeyChar.ToString().charCodeAt(0) <= 126) ) {
              pwd=pwd+(key.KeyChar.ToString());
              Console.Error.Write("*");
           }

           if ( key.Key == ConsoleKey.Backspace && pwd.Length > 0 ) {
               pwd=pwd.Remove(pwd.Length-1);
               Console.Error.Write("\b \b");
           }


        } while (key.Key != ConsoleKey.Enter);
        Console.Error.WriteLine();
        Console.WriteLine(pwd);

1.Pure batch solution that (ab)uses XCOPY command and its /P /L switches found here (some improvements on this could be found here ):

:: Hidden.cmd
::Tom Lavedas, 02/05/2013, 02/20/2013
::Carlos, 02/22/2013
::https://groups.google.com/forum/#!topic/alt.msdos.batch.nt/f7mb_f99lYI


@Echo Off
:HInput
SetLocal EnableExtensions EnableDelayedExpansion
Set "FILE=%Temp%.\T"
Set "FILE=.\T"
Keys List >"%File%"
Set /P "=Hidden text ending with Ctrl-C?: " <Nul
Echo.
Set "HInput="
:HInput_
For /F "tokens=1* delims=?" %%A In (
 '"Xcopy /P /L "%FILE%" "%FILE%" 2>Nul"'
) Do (
  Set "Text=%%B"
  If Defined Text (
    Set "Char=!Text:~1,1!"
    Set "Intro=1"
    For /F delims^=^ eol^= %%Z in ("!Char!") Do Set "Intro=0"
    Rem If press Intro
    If 1 Equ !Intro! Goto :HInput#
    Set "HInput=!HInput!!Char!"
  )
)
Goto :HInput_
:HInput#
Echo(!HInput!
Goto :Eof 

1.2 Another way based on replace command

@Echo Off
SetLocal EnableExtensions EnableDelayedExpansion

Set /P "=Enter a Password:" < Nul
Call :PasswordInput
Echo(Your input was:!Line!

Goto :Eof

:PasswordInput
::Author: Carlos Montiers Aguilera
::Last updated: 20150401. Created: 20150401.
::Set in variable Line a input password
For /F skip^=1^ delims^=^ eol^= %%# in (
'"Echo(|Replace.exe "%~f0" . /U /W"') Do Set "CR=%%#"
For /F %%# In (
'"Prompt $H &For %%_ In (_) Do Rem"') Do Set "BS=%%#"
Set "Line="
:_PasswordInput_Kbd
Set "CHR=" & For /F skip^=1^ delims^=^ eol^= %%# in (
'Replace.exe "%~f0" . /U /W') Do Set "CHR=%%#"
If !CHR!==!CR! Echo(&Goto :Eof
If !CHR!==!BS! (If Defined Line (Set /P "=!BS! !BS!" <Nul
Set "Line=!Line:~0,-1!"
)
) Else (Set /P "=*" <Nul
If !CHR!==! (Set "Line=!Line!^!"
) Else Set "Line=!Line!!CHR!"
)
Goto :_PasswordInput_Kbd

2.Password submitter that uses a HTA pop-up
. This is a hybrit .bat/jscript/mshta file and should be saved as a .bat:

<!-- :
:: PasswordSubmitter.bat
@echo off
for /f "tokens=* delims=" %%p in ('mshta.exe "%~f0"') do (
    set "pass=%%p"
)

echo your password is %pass%
exit /b
-->

<html>
<head><title>Password submitter</title></head>
<body>

    <script language='javascript' >
        window.resizeTo(300,150);
        function entperPressed(e){
                if (e.keyCode == 13) {
                    pipePass();
                }
        }
        function pipePass() {
            var pass=document.getElementById('pass').value;
            var fso= new ActiveXObject('Scripting.FileSystemObject').GetStandardStream(1);
            close(fso.Write(pass));

        }
    </script>

    <input type='password' name='pass' size='15' onkeypress="return entperPressed(event)" ></input>
    <hr>
    <button onclick='pipePass()'>Submit</button>

</body>
</html>

3.A self-compiled .net hybrid .Again should be saved as .bat .In difference with other solutions it will create/compile a small .exe file that will be called (if you wish you can delete it). Also requires installed .net framework but that's rather not a problem:

@if (@X)==(@Y) @end /* JScript comment
@echo off
setlocal enableDelayedExpansion

for /f "tokens=* delims=" %%v in ('dir /b /s /a:-d  /o:-n "%SystemRoot%\Microsoft.NET\Framework\*jsc.exe"') do (
   set "jsc=%%v"
)

if not exist "%~n0.exe" (
    "%jsc%" /nologo /out:"%~n0.exe" "%~dpsfnx0"
)

for /f "tokens=* delims=" %%p in ('"%~n0.exe"') do (
    set "pass=%%p"
)

echo your password is !pass!

endlocal & exit /b %errorlevel%

*/



import System;



var pwd = "";
var key;

Console.Error.Write("Enter password: ");

        do {
           key = Console.ReadKey(true);

           if ( (key.KeyChar.ToString().charCodeAt(0)) >= 20 && (key.KeyChar.ToString().charCodeAt(0) <= 126) ) {
              pwd=pwd+(key.KeyChar.ToString());
              Console.Error.Write("*");
           }

           if ( key.Key == ConsoleKey.Backspace && pwd.Length > 0 ) {
               pwd=pwd.Remove(pwd.Length-1);
               Console.Error.Write("\b \b");
           }


        } while (key.Key != ConsoleKey.Enter);
        Console.Error.WriteLine();
        Console.WriteLine(pwd);
岁月染过的梦 2024-07-22 12:52:23

我可能会这样做:

..
echo Before you enter your password, make sure no-one is looking!
set /P password=Password:  
cls
echo Thanks, got that.
.. 

所以你会收到提示,然后输入后屏幕会清除。

请注意,如果从命令提示符执行批处理文件,输入的密码将存储在 CMD 历史记录中(感谢 @Mark K Cowan)。

如果这还不够好,我要么切换到 python,要么编写可执行文件而不是脚本。

我知道这些都不是完美的解决方案,但也许其中一个对您来说就足够了:)

I would probably just do:

..
echo Before you enter your password, make sure no-one is looking!
set /P password=Password:  
cls
echo Thanks, got that.
.. 

So you get a prompt, then the screen clears after it's entered.

Note that the entered password will be stored in the CMD history if the batch file is executed from a command prompt (Thanks @Mark K Cowan).

If that wasn't good enough, I would either switch to python, or write an executable instead of a script.

I know none of these are perfect soutions, but maybe one is good enough for you :)

回眸一遍 2024-07-22 12:52:23

您可以使用 ReadFormattedLine 子例程来处理所有类型的格式化输入。 例如,下面的命令读取 8 个字符的密码,在屏幕上显示星号,然后自动继续,无需按 Enter:

call :ReadFormattedLine password="********" /M "Enter password (8 chars): "

该子程序是用纯 Batch 编写的,因此不需要任何额外的程序,并且允许多种格式化输入操作,如只读数字、将字母转换为大写等。您可以从 读取特定格式的行


编辑 2018-08-18输入“不可见”密码的新方法

FINDSTR 命令有一个奇怪的错误,当该命令用于显示彩色字符时会发生 AND此类命令的输出被重定向到 CON 设备。 有关如何使用 FINDSTR 命令以颜色显示文本的详细信息,请参阅 这个主题

当这种形式的FINDSTR命令的输出被重定向到CON时,在文本以所需的颜色输出后会发生一些奇怪的事情:它后面的所有文本都被输出为“不可见”字符,尽管更精确的描述是文本是输出为黑色背景上的黑色文本。 如果使用COLOR命令重置整个屏幕的前景色和背景色,就会出现原来的文本。 但是,当文本“不可见”时,我们可以执行 SET /P 命令,因此输入的所有字符都不会出现在屏幕上。

@echo off
setlocal

set /P "=_" < NUL > "Enter password"
findstr /A:1E /V "^$" "Enter password" NUL > CON
del "Enter password"
set /P "password="
cls
color 07
echo The password read is: "%password%"

You may use ReadFormattedLine subroutine for all kind of formatted input. For example, the command below read a password of 8 characters, display asterisks in the screen, and continue automatically with no need to press Enter:

call :ReadFormattedLine password="********" /M "Enter password (8 chars): "

This subroutine is written in pure Batch so it does not require any additional program, and it allows several formatted input operations, like read just numbers, convert letters to uppercase, etc. You may download ReadFormattedLine subroutine from Read a line with specific format.


EDIT 2018-08-18: New method to enter an "invisible" password

The FINDSTR command have a strange bug that happen when this command is used to show characters in color AND the output of such a command is redirected to CON device. For details on how use FINDSTR command to show text in color, see this topic.

When the output of this form of FINDSTR command is redirected to CON, something strange happens after the text is output in the desired color: all the text after it is output as "invisible" characters, although a more precise description is that the text is output as black text over black background. The original text will appear if you use COLOR command to reset the foreground and background colors of the entire screen. However, when the text is "invisible" we could execute a SET /P command, so all characters entered will not appear on the screen.

@echo off
setlocal

set /P "=_" < NUL > "Enter password"
findstr /A:1E /V "^$" "Enter password" NUL > CON
del "Enter password"
set /P "password="
cls
color 07
echo The password read is: "%password%"
柏林苍穹下 2024-07-22 12:52:23

另一种选择是我的 EditV32 (x86) 或 EditV64 (x64) 命令行工具。 例如:

editv32 -m -p "Password: " PWD

-m 表示“屏蔽输入”,-p 是提示符。 用户的输入存储在 PWD 环境变量中。 您可以在这里获取:

https://westmesatech.com/?page_id=19

another alternative is my EditV32 (x86) or EditV64 (x64) command-line tools. For example:

editv32 -m -p "Password: " PWD

-m means "masked input" and -p is the prompt. The user's input is stored in the PWD environment variable. You can get it here:

https://westmesatech.com/?page_id=19

无风消散 2024-07-22 12:52:23

您可以将前景颜色设置为黑色,如下所示:

:: see https://stackoverflow.com/questions/33293220/what-is-the-fastest-color-function-in-batch
@echo off
for /F %%a in ('echo prompt $E ^| cmd') do set "ESC=%%a"
set color_white=%ESC%[37m
set color_black=%ESC%[30m
echo(
set /p user=Username:
set /p pass=password:%color_black%
echo %color_white%
echo blablablba

享受吧!
C。

You can set the forground color to black such:

:: see https://stackoverflow.com/questions/33293220/what-is-the-fastest-color-function-in-batch
@echo off
for /F %%a in ('echo prompt $E ^| cmd') do set "ESC=%%a"
set color_white=%ESC%[37m
set color_black=%ESC%[30m
echo(
set /p user=Username:
set /p pass=password:%color_black%
echo %color_white%
echo blablablba

Enjoy!!!
C.

温柔戏命师 2024-07-22 12:52:23

如果安装了 Python,则可以使用:

for /f "delims=" %%A in ('python -c "import getpass; print(getpass.getpass('Enter the CVS password: '));"') do @set CVSPASS=%%A
echo PASS: %CVSPASS%

输出:

Enter the CVS password:
PASS: 123

If you have Python installed, you can use:

for /f "delims=" %%A in ('python -c "import getpass; print(getpass.getpass('Enter the CVS password: '));"') do @set CVSPASS=%%A
echo PASS: %CVSPASS%

the output:

Enter the CVS password:
PASS: 123
绾颜 2024-07-22 12:52:23

如果缺少源代码让您烦恼,我还有另一个选择。

@echo off
for /f "delims=" %%p in ('ReadLine -h -p "Enter password: "') do set PWD=%%p
echo You entered: %PWD%

您可以从 https://westmesatech.com/?page_id=49 获取它。 包含源代码。

If the lack of source code bothers you, I have another alternative.

@echo off
for /f "delims=" %%p in ('ReadLine -h -p "Enter password: "') do set PWD=%%p
echo You entered: %PWD%

You can get it from https://westmesatech.com/?page_id=49. Source code is included.

怕倦 2024-07-22 12:52:23

我使用了Blorgbeard的上述解决方案,在我看来这实际上很棒。 然后我按如下方式对其进行了增强:

  1. Google for ansicon
  2. 下载 zip 文件和示例文本文件。
  3. 安装(这意味着将 2 个文件复制到 system32 中)

像这样使用它:

@echo off
ansicon -p
set /p pwd=Password:ESC[0;37;47m
echo ESC[0m

这会将控制台切换为灰色,以便您输入密码,并在完成后切换回来。 ESC 实际上应该是一个不可打印的字符,您可以将其从下载的示例文本文件(在记事本中显示为左箭头)复制到批处理文件中。 您可以使用示例文本文件查找所有颜色组合的代码。

如果您不是计算机的管理员,您可能能够将文件安装在非系统目录中,那么您必须在调用程序并使用转义序列之前将该目录附加到脚本中的 PATH 中。 如果您需要仅包含几个文件的非管理员可分发包,这甚至可能是当前目录。

I used Blorgbeard's above solution which is actually great in my opinion. Then I enhanced it as follows:

  1. Google for ansicon
  2. Download zip file and sample text file.
  3. Install (that means copy 2 files into system32)

Use it like this:

@echo off
ansicon -p
set /p pwd=Password:ESC[0;37;47m
echo ESC[0m

This switches the console to gray on gray for your password entry and switches back when you are done. The ESC should actually be an unprintable character, which you can copy over from the downloaded sample text file (appears like a left-arrow in Notepad) into your batch file. You can use the sample text file to find the codes for all color combinations.

If you are not admin of the machine, you will probably be able to install the files in a non-system directory, then you have to append the directory to the PATH in your script before calling the program and using the escape sequences. This could even be the current directory probably, if you need a non-admin distributable package of just a few files.

梦与时光遇 2024-07-22 12:52:23

创建一个批处理文件来调用不可见字符所需的批处理文件,然后为正在调用的批处理文件创建一个快捷方式。

右键单击

属性

颜色

文本==黑色

背景==黑色

应用确定

希望

从而帮助你!!!!!!!!!

make a batch file that calls the one needed for invisible characters then make a shortcut for the batch file being called.

right click

properties

colors

text==black

background == black

apply

ok

hope thus helps you!!!!!!!!

爱,才寂寞 2024-07-22 12:52:23

更新:
我添加了两种新方法,它们不是利用 cls 来隐藏输入,而是创建一个仅包含一行的新弹出窗口。

缺点是一种方法(方法 2)会在注册表中留下垃圾 - “如果运行时没有正确执行权利”,另一种(方法三)在脚本中附加一些垃圾。 不用说,它可以很容易地写入任何 tmp 文件并删除,我只是试图想出一个替代方案。

限制: 密码只能是字母数字 - 不能有其他字符!

@echo off
if "%1"=="method%choice%" goto :method%choice%
::::::::::::::::::
::Your code here::
::::::::::::::::::
cls
echo :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
echo ::::                   Batch script to prompt for password!                 :::
echo :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
:choice
echo.
echo 1. First method
echo.
echo 2. Second method
echo.
echo 3. Third method
echo.
set/p choice=Choose a method: 
if "%choice%" gtr "3" echo. & echo invalid option & echo. & pause & goto choice

call :vars
    set options= %num%%smAlph%%cpAlph%
    set pwdLen=6

if "%choice%" == "1" (
    set /p=Password: <nul 
    for /l %%i in (1,1,%pwdLen%) do call :password
) else (
    start /wait cmd /c call "%~f0" method%choice%
    )

call :result%choice%


::just to see if it worked!
echo.
echo The Password you entered is: "%pwd%"&pause>nul

::::::::::::::::::
::More code here::
::::::::::::::::::
exit /b





:vars
set num=1234567890
set smAlph=abcdefghijklmnopqrstuvwxyz
set cpAlph=ABCDEFGHIJKLMNOPQRSTUVWXYZ
    set pwd=
goto :EOF


:method2
call :popUp
setx result %pwd% >nul
goto :EOF

:method3
call :popUp
    >> "%~f0" echo.
    >> "%~f0" echo :result%choice%
    >> "%~f0" echo set pwd=%pwd%
goto :EOF

:popUp
title Password
mode con lines=1 cols=30
color 5a
set /p=Password: <nul
for /l %%i in (1,1,%pwdLen%) do call :password
goto :EOF

:password
:: If you don't want case sensative remove "/cs" but remember to remove %cpAlph% from the %options%
choice /c %options% /n /cs >nul
    call SET pwd=%pwd%%%options:~%errorlevel%,1%%
    set /p =*<nul
GOTO :EOF


:result2
for /f "tokens=3" %%a in ('reg query hkcu\environment /v result') do set pwd=%%a
    setx result "" >nul
    reg delete hkcu\environment /v result /f >nul 2>&1
:result1
goto :EOF   
::You can delete from here whenever you want.

更新:
我发现 sachadee 的帖子非常完美 我刚刚添加了我的“弹出”怪癖。

@Echo Off  
  SetLocal EnableDelayedExpansion
  if "%1"==":HInput" goto :HInput
  set r=r%random%
  start /wait cmd /c call "%~f0" :HInput

For /f "tokens=2,13 delims=, " %%a in (
    'tasklist /v /fo csv /fi "imagename eq cmd.exe"
    ^|findstr /v "Windows\\system32\\cmd.exe"
    ^|findstr "set /p=%r%"'
     ) do (
        set pid=%%a
        set Line=%%b
        set Line=!Line:%r%=!
        set Line=!Line:~,-2!
        )       
taskkill /pid %pid:"=%>nul
  goto :HIEnd


  :HInput
  SetLocal DisableDelayedExpansion
  title Password
  mode con lines=2 cols=30

Echo Enter your Code :
   Set "Line="
   For /F %%# In (
   '"Prompt;$H&For %%# in (1) Do Rem"'
   ) Do Set "BS=%%#"

  :HILoop
   Set "Key="
   For /F "delims=" %%# In (
   'Xcopy /W "%~f0" "%~f0" 2^>Nul'
   ) Do If Not Defined Key Set "Key=%%#"
   Set "Key=%Key:~-1%"
   SetLocal EnableDelayedExpansion
   If Not Defined Key start /min cmd /k mode con lines=1 cols=14 ^&set/p %r%!Line!=&exit
  If %BS%==^%Key% (Set /P "=%BS% %BS%" <Nul
   Set "Key="
   If Defined Line Set "Line=!Line:~0,-1!"
   ) Else Set /P "=*" <Nul
   If Not Defined Line (EndLocal &Set "Line=%Key%"
   ) Else For /F delims^=^ eol^= %%# In (
   "!Line!") Do EndLocal &Set "Line=%%#%Key%"
  Goto :HILoop

  :HIEnd
   Echo(
Echo Your code is :  "!Line!"
   Pause
   Goto :Eof

UPDATE:
I added two new methods that instead of utilizing cls to hide the input they create a new pop-up with one line only.

The drawbacks are that one method (method 2) leaves junk in the registry - "If run without proper rights", and the other one (method three) appends some junk to the script. Needless to say that it can easily be written to any tmp file and deleted I just tried to come up with an alternative.

Limitation: The password can only be alphanumeric - no other characters!

@echo off
if "%1"=="method%choice%" goto :method%choice%
::::::::::::::::::
::Your code here::
::::::::::::::::::
cls
echo :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
echo ::::                   Batch script to prompt for password!                 :::
echo :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
:choice
echo.
echo 1. First method
echo.
echo 2. Second method
echo.
echo 3. Third method
echo.
set/p choice=Choose a method: 
if "%choice%" gtr "3" echo. & echo invalid option & echo. & pause & goto choice

call :vars
    set options= %num%%smAlph%%cpAlph%
    set pwdLen=6

if "%choice%" == "1" (
    set /p=Password: <nul 
    for /l %%i in (1,1,%pwdLen%) do call :password
) else (
    start /wait cmd /c call "%~f0" method%choice%
    )

call :result%choice%


::just to see if it worked!
echo.
echo The Password you entered is: "%pwd%"&pause>nul

::::::::::::::::::
::More code here::
::::::::::::::::::
exit /b





:vars
set num=1234567890
set smAlph=abcdefghijklmnopqrstuvwxyz
set cpAlph=ABCDEFGHIJKLMNOPQRSTUVWXYZ
    set pwd=
goto :EOF


:method2
call :popUp
setx result %pwd% >nul
goto :EOF

:method3
call :popUp
    >> "%~f0" echo.
    >> "%~f0" echo :result%choice%
    >> "%~f0" echo set pwd=%pwd%
goto :EOF

:popUp
title Password
mode con lines=1 cols=30
color 5a
set /p=Password: <nul
for /l %%i in (1,1,%pwdLen%) do call :password
goto :EOF

:password
:: If you don't want case sensative remove "/cs" but remember to remove %cpAlph% from the %options%
choice /c %options% /n /cs >nul
    call SET pwd=%pwd%%%options:~%errorlevel%,1%%
    set /p =*<nul
GOTO :EOF


:result2
for /f "tokens=3" %%a in ('reg query hkcu\environment /v result') do set pwd=%%a
    setx result "" >nul
    reg delete hkcu\environment /v result /f >nul 2>&1
:result1
goto :EOF   
::You can delete from here whenever you want.

Update:
I found sachadee's post to be perfect and I just added my "pop-up" quirk to it.

@Echo Off  
  SetLocal EnableDelayedExpansion
  if "%1"==":HInput" goto :HInput
  set r=r%random%
  start /wait cmd /c call "%~f0" :HInput

For /f "tokens=2,13 delims=, " %%a in (
    'tasklist /v /fo csv /fi "imagename eq cmd.exe"
    ^|findstr /v "Windows\\system32\\cmd.exe"
    ^|findstr "set /p=%r%"'
     ) do (
        set pid=%%a
        set Line=%%b
        set Line=!Line:%r%=!
        set Line=!Line:~,-2!
        )       
taskkill /pid %pid:"=%>nul
  goto :HIEnd


  :HInput
  SetLocal DisableDelayedExpansion
  title Password
  mode con lines=2 cols=30

Echo Enter your Code :
   Set "Line="
   For /F %%# In (
   '"Prompt;$H&For %%# in (1) Do Rem"'
   ) Do Set "BS=%%#"

  :HILoop
   Set "Key="
   For /F "delims=" %%# In (
   'Xcopy /W "%~f0" "%~f0" 2^>Nul'
   ) Do If Not Defined Key Set "Key=%%#"
   Set "Key=%Key:~-1%"
   SetLocal EnableDelayedExpansion
   If Not Defined Key start /min cmd /k mode con lines=1 cols=14 ^&set/p %r%!Line!=&exit
  If %BS%==^%Key% (Set /P "=%BS% %BS%" <Nul
   Set "Key="
   If Defined Line Set "Line=!Line:~0,-1!"
   ) Else Set /P "=*" <Nul
   If Not Defined Line (EndLocal &Set "Line=%Key%"
   ) Else For /F delims^=^ eol^= %%# In (
   "!Line!") Do EndLocal &Set "Line=%%#%Key%"
  Goto :HILoop

  :HIEnd
   Echo(
Echo Your code is :  "!Line!"
   Pause
   Goto :Eof
执手闯天涯 2024-07-22 12:52:23

我编写了一个名为 editenv 的开源程序,它取代了我旧的 editv32/editv64 实用程序:

https://github.com/Bill-Stewart/editenv

--maskinput (-m) option[*] 可让您隐藏(屏蔽)键入的输入并具有可配置字符(默认字符为 *); 例如:

editenv -m -p "Password: " PWD

--prompt (-p) 选项可让您指定输入提示。 上面将显示一个 Password: 提示并等待您输入内容。 键入的字符将显示为 *。 按 Ctrl+C 将结束程序,退出代码为 1223。

下载地址:

https://github.com/Bill-Stewart/editenv/releases

[*] 请注意 --maskinput ( -m) 选项不安全——输入的字符串在环境中以纯文本形式输入。 此功能只是为了方便。

I wrote an open source program called editenv that replaces my older editv32/editv64 utilities:

https://github.com/Bill-Stewart/editenv

The --maskinput (-m) option[*] lets you hide (mask) the typed input and has a configurable character (default character is *); e.g.:

editenv -m -p "Password: " PWD

The --prompt (-p) option lets you specify an input prompt. The above will display a Password: prompt and wait for you to enter something. Typed characters will appear as *. Pressing Ctrl+C will end the program with an exit code of 1223.

Download is here:

https://github.com/Bill-Stewart/editenv/releases

[*] Note that the --maskinput (-m) option is not secure -- the entered string is entered as plain-text in the environment. This feature is for convenience only.

节枝 2024-07-22 12:52:23

好吧,我刚刚找到了解决这个问题的一个非常不错的方法。 CMDKEY 适用于 Windows 7+,允许您从 cmd 提示符向 Windows 信用管理器输入详细信息,如果您使用 /pass 开关,它会提供自己的密码条目,而不会暴露密码。 当您键入时,它不会显示 *****,但密码是隐藏的。

下面的脚本正常请求用户名并创建一个名为“%username%”的 var,然后检查信用管理器是否已经有目标服务器的条目。 如果这样做,它只是将驱动器映射到用户名,而不请求密码。 如果没有条目,则使用 CMDKEY 提示输入密码并将其存储在凭据管理器中。

    set /p username="Enter School Username: "
    CMDKEY /list:SERVERNAME | FIND "NONE" > nul 2>&1
    IF %ERRORLEVEL% NEQ 0 GOTO MAPDRIVES
    CMDKEY /ADD:SERVERNAME /username:%username% /pass
    :MAPDRIVES
    NET USE Y: \\SERVERNAME\SHARE\%username%

Ok so I just found a really decent work around to this issue. CMDKEY works on windows 7+ and allows you to enter details into the windows cred manager from the cmd prompt, and if you use the /pass switch it provides its own password entry without exposing the password. It does not present ***** as you type but the password is hidden.

The script below requests the username as normal and creates a var called "%username%" it then checks to see if the cred manager already has an entry for the target server. If it does it just maps the drive to the usename and does not request a password. If there is no entry it then uses the CMDKEY to prompt for password and stores it in cred manager.

    set /p username="Enter School Username: "
    CMDKEY /list:SERVERNAME | FIND "NONE" > nul 2>&1
    IF %ERRORLEVEL% NEQ 0 GOTO MAPDRIVES
    CMDKEY /ADD:SERVERNAME /username:%username% /pass
    :MAPDRIVES
    NET USE Y: \\SERVERNAME\SHARE\%username%
只为守护你 2024-07-22 12:52:23

不幸的是,我无法在 Windows 10 21H1 系统上获得 @unclemeat 的答案。 我刚刚得到: [System.Runtime.InteropServices.Marshal]::PtrToStringAuto($BSTR)"" 此时出乎意料。

但他让我走上了正确的轨道。

所以这是我的变体:

脚本顶部的配置:

@ECHO OFF
:: Don't leak variables to command shell
SETLOCAL

    REM service user for backend services - comment out to default to LOCALSYSTEM
SET WINDOWS_SVC_USERNAME=svcadmin

检查管理员权限并创建服务后位于底部的某个位置:

SETLOCAL ENABLEDELAYEDEXPANSION

:: Read password for service user
IF DEFINED WINDOWS_SVC_USERNAME (
    SET PWR=powershell -Command "$secureString = Read-Host 'Enter password for service user \".\%WINDOWS_SVC_USERNAME%\"' -AsSecureString -ErrorAction Stop; $ptr = [System.Runtime.InteropServices.Marshal]::SecureStringToGlobalAllocUnicode($secureString); $plain = [System.Runtime.InteropServices.Marshal]::PtrToStringUni($ptr); [System.Runtime.InteropServices.Marshal]::ZeroFreeGlobalAllocUnicode($ptr); Write-Host $plain;"
    FOR /F "usebackq delims=" %%P IN (`!PWR!`) DO SET WINDOWS_SVC_PASSWORD=%%P
    IF DEFINED WINDOWS_SVC_PASSWORD (
        IF ["!WINDOWS_SVC_PASSWORD!"] NEQ [""] (
            IF ["!WINDOWS_SVC_PASSWORD!"] NEQ [" "] (
                :: The password is now set correctly
                ECHO "Using ".\%WINDOWS_SVC_USERNAME%" as service user..."
                sc config  prod!WINDOWS_SVC_INFIX!rest!INDEX! obj= ".\!WINDOWS_SVC_USERNAME!" password= "!WINDOWS_SVC_PASSWORD!"
            ) ELSE (
                ECHO "ERROR -- Password possibly empty or PowerShell threw an exception."
                SET "WINDOWS_SVC_USERNAME="
            )
        ) ELSE (
            ECHO "ERROR -- Could not retrieve password! Password is possibly empty."
            SET "WINDOWS_SVC_USERNAME="
        )
    ) ELSE (
        ECHO "ERROR -- No password given or PowerShell is not available."
        SET "WINDOWS_SVC_USERNAME="
    )
) ELSE (
    ECHO "No service user specified - keeping default "LOCALSYSTEM" user..."
)

当然,只是复制了 sc config prod!WINDOWS_SVC_INFIX!rest!INDEX!从我的 for 循环进一步向下,需要适应您的具体情况。
使用 ECHO 密码读取:“!WINDOWS_SVC_PASSWORD!” 进行调试。

这尚未在野外进行测试,因此请小心处理。

I couldn't get @unclemeat's answer to work on Windows 10 21H1 systems unfortunately. I just got: [System.Runtime.InteropServices.Marshal]::PtrToStringAuto($BSTR)"" was unexpected at this time.

But he set me on the right track.

So here is my variant:

Configuration at top of script:

@ECHO OFF
:: Don't leak variables to command shell
SETLOCAL

    REM service user for backend services - comment out to default to LOCALSYSTEM
SET WINDOWS_SVC_USERNAME=svcadmin

Somewhere at the bottom after checking for admin privileges and after creating the service:

SETLOCAL ENABLEDELAYEDEXPANSION

:: Read password for service user
IF DEFINED WINDOWS_SVC_USERNAME (
    SET PWR=powershell -Command "$secureString = Read-Host 'Enter password for service user \".\%WINDOWS_SVC_USERNAME%\"' -AsSecureString -ErrorAction Stop; $ptr = [System.Runtime.InteropServices.Marshal]::SecureStringToGlobalAllocUnicode($secureString); $plain = [System.Runtime.InteropServices.Marshal]::PtrToStringUni($ptr); [System.Runtime.InteropServices.Marshal]::ZeroFreeGlobalAllocUnicode($ptr); Write-Host $plain;"
    FOR /F "usebackq delims=" %%P IN (`!PWR!`) DO SET WINDOWS_SVC_PASSWORD=%%P
    IF DEFINED WINDOWS_SVC_PASSWORD (
        IF ["!WINDOWS_SVC_PASSWORD!"] NEQ [""] (
            IF ["!WINDOWS_SVC_PASSWORD!"] NEQ [" "] (
                :: The password is now set correctly
                ECHO "Using ".\%WINDOWS_SVC_USERNAME%" as service user..."
                sc config  prod!WINDOWS_SVC_INFIX!rest!INDEX! obj= ".\!WINDOWS_SVC_USERNAME!" password= "!WINDOWS_SVC_PASSWORD!"
            ) ELSE (
                ECHO "ERROR -- Password possibly empty or PowerShell threw an exception."
                SET "WINDOWS_SVC_USERNAME="
            )
        ) ELSE (
            ECHO "ERROR -- Could not retrieve password! Password is possibly empty."
            SET "WINDOWS_SVC_USERNAME="
        )
    ) ELSE (
        ECHO "ERROR -- No password given or PowerShell is not available."
        SET "WINDOWS_SVC_USERNAME="
    )
) ELSE (
    ECHO "No service user specified - keeping default "LOCALSYSTEM" user..."
)

Of course the sc config prod!WINDOWS_SVC_INFIX!rest!INDEX! is just copied from my for-loop further down and needs adaption to your specific case.
Use ECHO password read: "!WINDOWS_SVC_PASSWORD!" for debugging instead.

This is not yet tested in the wild, so please handle with care.

两人的回忆 2024-07-22 12:52:23

上面已经提供了对原始问题的不同答案,我在本地不存储密码的首选解决方案是基于 来自上面TessellatedHeckler的评论

for /f "usebackq tokens=*" %%p in (`powershell -Command "$pass = read-host 'Password' -AsSecureString ; $BSTR=[System.Runtime.InteropServices.Marshal]::SecureStringToBSTR($pass); [System.Runtime.InteropServices.Marshal]::PtrToStringAuto($BSTR)"`) do set jira_password=%%p

但是有一点还没有明确解决:不要忘记之前< /strong> 检索它并使用它之后(如果您不使用“setlocal”命令),即调用:

set "password="

背景:直到命令会话关闭 - 变量仍然存储并且在外部也可访问你的脚本。 例如:

  • 运行批处理脚本(它检索密码并随后显示它以用于测试目的)
  • 输入一些文本作为密码并查看它是否正确显示
  • 重新运行相同的批处理脚本而不关闭当前命令会话
  • 不要输入任何内容(即只是当要求输入密码时按 Enter 键)
  • 您将看到之前输入的密码。

因为某些脚本在链中执行,并且您无法控制脚本之后在同一会话中执行的脚本 - 您应该注意清理用户/密码变量。

为了避免批处理脚本意外退出的问题(即未到达变量清除命令时),最好使用

setlocal
...
endlocal

范围。

最后但并非最不重要的一点是:如果有人可以[暂时]修改您的脚本 - 给定的密码可以存储在某处或“转发”(即“丢失”)。

Different answers to original question were already provided above, my preferred solution without storing password locally was based on comment from TessellatingHeckler above:

for /f "usebackq tokens=*" %%p in (`powershell -Command "$pass = read-host 'Password' -AsSecureString ; $BSTR=[System.Runtime.InteropServices.Marshal]::SecureStringToBSTR($pass); [System.Runtime.InteropServices.Marshal]::PtrToStringAuto($BSTR)"`) do set jira_password=%%p

However one point wasn't clearly addressed yet: don't forget to clear the password variable before retrieving it and after its usage (if you are not using the "setlocal" command), i.e. call the:

set "password="

Background: until the command session get closed - the variable stays stored and accessible also outside of your script. For example:

  • run your batch script (which retrieves a password and shows it afterwards for test purpose)
  • enter some text as a password and see it shown properly
  • re-run same batch script without closing current command session
  • don't enter anything (i.e. just press Enter when being asked for password)
  • you will see the previously entered password.

Because some scripts being executed in a chain and you can't control the scripts executed in same session after your script - you should care on cleaning the user/password variables.

To avoid problems with unexpected exit from batch-script (i.e. when the variable clearing command being not reached), it's better to use

setlocal
...
endlocal

scopes.

Last but not least: if someone can [temporarily] modify your script - the given password could be stored somewhere or "forwarded" (i.e. get "lost").

迷你仙 2024-07-22 12:52:23

这可能是一个较旧的主题,但如果您使用的是 Windows Vista 或 7,我有一个非常有效的解决方案。 我在这里制作了一个视频:http://www.youtube.com/watch?v=mk8uAa6PIFM

批处理文件的 Pastebin 在这里

This may be an older topic, but if you are using Windows Vista or 7, I have a solution that will work very well. I made a video of it here: http://www.youtube.com/watch?v=mk8uAa6PIFM

Pastebin for the batch file is here

离鸿 2024-07-22 12:52:23
@echo off
color 0f
MODE CON COLS=132 LINES=50
:start
cls
choice /C ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789!?.# /N /CS /M Please enter your password to continue. (Valid characters include all letters, numbers, and ! ? .) Press # to submit: 
SET ecode=%ERRORLEVEL%
IF %ecode% EQU 66 goto submit
IF %ecode% EQU 1 SET out=A
IF %ecode% EQU 2 SET out=B
IF %ecode% EQU 3 SET out=C
IF %ecode% EQU 4 SET out=D
IF %ecode% EQU 5 SET out=E
IF %ecode% EQU 6 SET out=F
IF %ecode% EQU 7 SET out=G
IF %ecode% EQU 8 SET out=H
IF %ecode% EQU 9 SET out=I
IF %ecode% EQU 10 SET out=J
IF %ecode% EQU 11 SET out=K
IF %ecode% EQU 12 SET out=L
IF %ecode% EQU 13 SET out=M
IF %ecode% EQU 14 SET out=N
IF %ecode% EQU 15 SET out=O
IF %ecode% EQU 16 SET out=P
IF %ecode% EQU 17 SET out=Q
IF %ecode% EQU 18 SET out=R
IF %ecode% EQU 19 SET out=S
IF %ecode% EQU 20 SET out=T
IF %ecode% EQU 21 SET out=U
IF %ecode% EQU 22 SET out=V
IF %ecode% EQU 23 SET out=W
IF %ecode% EQU 24 SET out=X
IF %ecode% EQU 25 SET out=Y
IF %ecode% EQU 26 SET out=Z
IF %ecode% EQU 27 SET out=a
IF %ecode% EQU 28 SET out=b
IF %ecode% EQU 29 SET out=c
IF %ecode% EQU 30 SET out=d
IF %ecode% EQU 31 SET out=e
IF %ecode% EQU 32 SET out=f
IF %ecode% EQU 33 SET out=g
IF %ecode% EQU 34 SET out=h
IF %ecode% EQU 35 SET out=i
IF %ecode% EQU 36 SET out=j
IF %ecode% EQU 37 SET out=k
IF %ecode% EQU 38 SET out=l
IF %ecode% EQU 39 SET out=m
IF %ecode% EQU 40 SET out=n
IF %ecode% EQU 41 SET out=o
IF %ecode% EQU 42 SET out=p
IF %ecode% EQU 43 SET out=q
IF %ecode% EQU 44 SET out=r
IF %ecode% EQU 45 SET out=s
IF %ecode% EQU 46 SET out=t
IF %ecode% EQU 47 SET out=u
IF %ecode% EQU 48 SET out=v
IF %ecode% EQU 49 SET out=w
IF %ecode% EQU 50 SET out=x
IF %ecode% EQU 51 SET out=y
IF %ecode% EQU 52 SET out=z
IF %ecode% EQU 53 SET out=0
IF %ecode% EQU 54 SET out=1
IF %ecode% EQU 55 SET out=2
IF %ecode% EQU 56 SET out=3
IF %ecode% EQU 57 SET out=4
IF %ecode% EQU 58 SET out=5
IF %ecode% EQU 59 SET out=6
IF %ecode% EQU 60 SET out=7
IF %ecode% EQU 61 SET out=8
IF %ecode% EQU 62 SET out=9
IF %ecode% EQU 63 SET out=!
IF %ecode% EQU 64 SET out=?
IF %ecode% EQU 65 SET out=.
SET code=%out%
SET show=*
:loop
cls
choice /C ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789!?.# /N /CS /M Please enter your password to continue. (Valid characters include all letters, numbers, and ! ? .) Press # to submit: %code%
SET ecode=%ERRORLEVEL%
IF %ecode% EQU 66 goto submit
IF %ecode% EQU 1 SET out=A
IF %ecode% EQU 2 SET out=B
IF %ecode% EQU 3 SET out=C
IF %ecode% EQU 4 SET out=D
IF %ecode% EQU 5 SET out=E
IF %ecode% EQU 6 SET out=F
IF %ecode% EQU 7 SET out=G
IF %ecode% EQU 8 SET out=H
IF %ecode% EQU 9 SET out=I
IF %ecode% EQU 10 SET out=J
IF %ecode% EQU 11 SET out=K
IF %ecode% EQU 12 SET out=L
IF %ecode% EQU 13 SET out=M
IF %ecode% EQU 14 SET out=N
IF %ecode% EQU 15 SET out=O
IF %ecode% EQU 16 SET out=P
IF %ecode% EQU 17 SET out=Q
IF %ecode% EQU 18 SET out=R
IF %ecode% EQU 19 SET out=S
IF %ecode% EQU 20 SET out=T
IF %ecode% EQU 21 SET out=U
IF %ecode% EQU 22 SET out=V
IF %ecode% EQU 23 SET out=W
IF %ecode% EQU 24 SET out=X
IF %ecode% EQU 25 SET out=Y
IF %ecode% EQU 26 SET out=Z
IF %ecode% EQU 27 SET out=a
IF %ecode% EQU 28 SET out=b
IF %ecode% EQU 29 SET out=c
IF %ecode% EQU 30 SET out=d
IF %ecode% EQU 31 SET out=e
IF %ecode% EQU 32 SET out=f
IF %ecode% EQU 33 SET out=g
IF %ecode% EQU 34 SET out=h
IF %ecode% EQU 35 SET out=i
IF %ecode% EQU 36 SET out=j
IF %ecode% EQU 37 SET out=k
IF %ecode% EQU 38 SET out=l
IF %ecode% EQU 39 SET out=m
IF %ecode% EQU 40 SET out=n
IF %ecode% EQU 41 SET out=o
IF %ecode% EQU 42 SET out=p
IF %ecode% EQU 43 SET out=q
IF %ecode% EQU 44 SET out=r
IF %ecode% EQU 45 SET out=s
IF %ecode% EQU 46 SET out=t
IF %ecode% EQU 47 SET out=u
IF %ecode% EQU 48 SET out=v
IF %ecode% EQU 49 SET out=w
IF %ecode% EQU 50 SET out=x
IF %ecode% EQU 51 SET out=y
IF %ecode% EQU 52 SET out=z
IF %ecode% EQU 53 SET out=0
IF %ecode% EQU 54 SET out=1
IF %ecode% EQU 55 SET out=2
IF %ecode% EQU 56 SET out=3
IF %ecode% EQU 57 SET out=4
IF %ecode% EQU 58 SET out=5
IF %ecode% EQU 59 SET out=6
IF %ecode% EQU 60 SET out=7
IF %ecode% EQU 61 SET out=8
IF %ecode% EQU 62 SET out=9
IF %ecode% EQU 63 SET out=!
IF %ecode% EQU 64 SET out=?
IF %ecode% EQU 65 SET out=.
SET code=%code%%out%
SET show=%show%*
goto loop
:submit
cls
SET password=%code%
IF %password% EQU 0cZrocks! SET result=1
IF ELSE SET result=2
IF %result% EQU 1 echo password correct
IF %result% EQU 2 echo password incorrect
timeout /T 2 /NOBREAK >nul
cls
IF %result% EQU 1 goto end
IF ELSE goto start
:end
@echo off
color 0f
MODE CON COLS=132 LINES=50
:start
cls
choice /C ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789!?.# /N /CS /M Please enter your password to continue. (Valid characters include all letters, numbers, and ! ? .) Press # to submit: 
SET ecode=%ERRORLEVEL%
IF %ecode% EQU 66 goto submit
IF %ecode% EQU 1 SET out=A
IF %ecode% EQU 2 SET out=B
IF %ecode% EQU 3 SET out=C
IF %ecode% EQU 4 SET out=D
IF %ecode% EQU 5 SET out=E
IF %ecode% EQU 6 SET out=F
IF %ecode% EQU 7 SET out=G
IF %ecode% EQU 8 SET out=H
IF %ecode% EQU 9 SET out=I
IF %ecode% EQU 10 SET out=J
IF %ecode% EQU 11 SET out=K
IF %ecode% EQU 12 SET out=L
IF %ecode% EQU 13 SET out=M
IF %ecode% EQU 14 SET out=N
IF %ecode% EQU 15 SET out=O
IF %ecode% EQU 16 SET out=P
IF %ecode% EQU 17 SET out=Q
IF %ecode% EQU 18 SET out=R
IF %ecode% EQU 19 SET out=S
IF %ecode% EQU 20 SET out=T
IF %ecode% EQU 21 SET out=U
IF %ecode% EQU 22 SET out=V
IF %ecode% EQU 23 SET out=W
IF %ecode% EQU 24 SET out=X
IF %ecode% EQU 25 SET out=Y
IF %ecode% EQU 26 SET out=Z
IF %ecode% EQU 27 SET out=a
IF %ecode% EQU 28 SET out=b
IF %ecode% EQU 29 SET out=c
IF %ecode% EQU 30 SET out=d
IF %ecode% EQU 31 SET out=e
IF %ecode% EQU 32 SET out=f
IF %ecode% EQU 33 SET out=g
IF %ecode% EQU 34 SET out=h
IF %ecode% EQU 35 SET out=i
IF %ecode% EQU 36 SET out=j
IF %ecode% EQU 37 SET out=k
IF %ecode% EQU 38 SET out=l
IF %ecode% EQU 39 SET out=m
IF %ecode% EQU 40 SET out=n
IF %ecode% EQU 41 SET out=o
IF %ecode% EQU 42 SET out=p
IF %ecode% EQU 43 SET out=q
IF %ecode% EQU 44 SET out=r
IF %ecode% EQU 45 SET out=s
IF %ecode% EQU 46 SET out=t
IF %ecode% EQU 47 SET out=u
IF %ecode% EQU 48 SET out=v
IF %ecode% EQU 49 SET out=w
IF %ecode% EQU 50 SET out=x
IF %ecode% EQU 51 SET out=y
IF %ecode% EQU 52 SET out=z
IF %ecode% EQU 53 SET out=0
IF %ecode% EQU 54 SET out=1
IF %ecode% EQU 55 SET out=2
IF %ecode% EQU 56 SET out=3
IF %ecode% EQU 57 SET out=4
IF %ecode% EQU 58 SET out=5
IF %ecode% EQU 59 SET out=6
IF %ecode% EQU 60 SET out=7
IF %ecode% EQU 61 SET out=8
IF %ecode% EQU 62 SET out=9
IF %ecode% EQU 63 SET out=!
IF %ecode% EQU 64 SET out=?
IF %ecode% EQU 65 SET out=.
SET code=%out%
SET show=*
:loop
cls
choice /C ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789!?.# /N /CS /M Please enter your password to continue. (Valid characters include all letters, numbers, and ! ? .) Press # to submit: %code%
SET ecode=%ERRORLEVEL%
IF %ecode% EQU 66 goto submit
IF %ecode% EQU 1 SET out=A
IF %ecode% EQU 2 SET out=B
IF %ecode% EQU 3 SET out=C
IF %ecode% EQU 4 SET out=D
IF %ecode% EQU 5 SET out=E
IF %ecode% EQU 6 SET out=F
IF %ecode% EQU 7 SET out=G
IF %ecode% EQU 8 SET out=H
IF %ecode% EQU 9 SET out=I
IF %ecode% EQU 10 SET out=J
IF %ecode% EQU 11 SET out=K
IF %ecode% EQU 12 SET out=L
IF %ecode% EQU 13 SET out=M
IF %ecode% EQU 14 SET out=N
IF %ecode% EQU 15 SET out=O
IF %ecode% EQU 16 SET out=P
IF %ecode% EQU 17 SET out=Q
IF %ecode% EQU 18 SET out=R
IF %ecode% EQU 19 SET out=S
IF %ecode% EQU 20 SET out=T
IF %ecode% EQU 21 SET out=U
IF %ecode% EQU 22 SET out=V
IF %ecode% EQU 23 SET out=W
IF %ecode% EQU 24 SET out=X
IF %ecode% EQU 25 SET out=Y
IF %ecode% EQU 26 SET out=Z
IF %ecode% EQU 27 SET out=a
IF %ecode% EQU 28 SET out=b
IF %ecode% EQU 29 SET out=c
IF %ecode% EQU 30 SET out=d
IF %ecode% EQU 31 SET out=e
IF %ecode% EQU 32 SET out=f
IF %ecode% EQU 33 SET out=g
IF %ecode% EQU 34 SET out=h
IF %ecode% EQU 35 SET out=i
IF %ecode% EQU 36 SET out=j
IF %ecode% EQU 37 SET out=k
IF %ecode% EQU 38 SET out=l
IF %ecode% EQU 39 SET out=m
IF %ecode% EQU 40 SET out=n
IF %ecode% EQU 41 SET out=o
IF %ecode% EQU 42 SET out=p
IF %ecode% EQU 43 SET out=q
IF %ecode% EQU 44 SET out=r
IF %ecode% EQU 45 SET out=s
IF %ecode% EQU 46 SET out=t
IF %ecode% EQU 47 SET out=u
IF %ecode% EQU 48 SET out=v
IF %ecode% EQU 49 SET out=w
IF %ecode% EQU 50 SET out=x
IF %ecode% EQU 51 SET out=y
IF %ecode% EQU 52 SET out=z
IF %ecode% EQU 53 SET out=0
IF %ecode% EQU 54 SET out=1
IF %ecode% EQU 55 SET out=2
IF %ecode% EQU 56 SET out=3
IF %ecode% EQU 57 SET out=4
IF %ecode% EQU 58 SET out=5
IF %ecode% EQU 59 SET out=6
IF %ecode% EQU 60 SET out=7
IF %ecode% EQU 61 SET out=8
IF %ecode% EQU 62 SET out=9
IF %ecode% EQU 63 SET out=!
IF %ecode% EQU 64 SET out=?
IF %ecode% EQU 65 SET out=.
SET code=%code%%out%
SET show=%show%*
goto loop
:submit
cls
SET password=%code%
IF %password% EQU 0cZrocks! SET result=1
IF ELSE SET result=2
IF %result% EQU 1 echo password correct
IF %result% EQU 2 echo password incorrect
timeout /T 2 /NOBREAK >nul
cls
IF %result% EQU 1 goto end
IF ELSE goto start
:end
不离久伴 2024-07-22 12:52:23

我阅读了网上所有关于如何在批处理文件中屏蔽密码的笨拙解决方案,使用 hide.com 解决方案的解决方案,甚至使文本和背景颜色相同的解决方案。 hide.com 解决方案运行良好,但不是很安全,并且无法在 64 位 Windows 中运行。 所以无论如何,使用 100% Microsoft 实用程序,有办法!

首先,让我解释一下我的用途。 我有大约 20 个自动登录 Windows 的工作站。 他们的桌面上有一个快捷方式 - 临床应用程序。 机器被锁定,他们无法右键单击,除了访问桌面上的一个快捷方式之外,他们什么也做不了。 有时,技术人员需要启动一些调试应用程序、浏览 Windows 资源管理器并查看日志文件,而无需注销自动日志用户帐户。

这就是我所做的。

你可以随心所欲地进行操作,但我将两个批处理文件放在锁定的计算机可以访问的网络共享上。

我的解决方案利用 Windows 的 1 个主要组件 - runas。
在客户端上放置您要创建的 runas.bat 的快捷方式。
仅供参考,在我的客户上,我重命名了快捷方式以便更好地查看,并更改了图标。

您将需要创建两个批处理文件。

我将批处理文件命名为 runas.batDebug Support.bat

runas.bat 包含以下代码:

cls
@echo off
TITLE CHECK CREDENTIALS 
goto menu

:menu
cls
echo.
echo           ....................................
echo            ~Written by Cajun Wonder 4/1/2010~
echo           ....................................
echo.
@set /p un=What is your domain username? 
if "%un%"=="PUT-YOUR-DOMAIN-USERNAME-HERE" goto debugsupport
if not "%un%"=="PUT-YOUR-DOMAIN-USERNAME-HERE" goto noaccess
echo.
:debugsupport
"%SYSTEMROOT%\system32\runas" /netonly /user:PUT-YOUR-DOMAIN-NAME-HERE\%un% "\\PUT-YOUR-NETWORK-SHARE-PATH-HERE\Debug Support.bat"
@echo ACCESS GRANTED! LAUNCHING THE DEBUG UTILITIES....
@ping -n 4 127.0.0.1 > NUL
goto quit
:noaccess
cls
@echo.
@echo.
@echo.
@echo.
@echo   \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
@echo   \\                                   \\
@echo   \\    Insufficient privileges         \\  
@echo   \\                                    \\
@echo   \\      Call Cajun Wonder             \\
@echo   \\                                    \\
@echo   \\              At                    \\
@echo   \\                                    \\
@echo   \\        555-555-5555                \\
@echo   \\                                    \\
@echo   \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
@ping -n 4 127.0.0.1 > NUL
goto quit
@pause
:quit
@exit

您可以添加任意多个 如果为“%un%”,如果不是“%un%”,则为您想要授予访问权限的所有用户。
@ping 是我制作秒计时器的巧妙方法。

这样就处理了第一个批处理文件 - 非常简单,嗯?

以下是 Debug Support.bat 的代码:

cls
@echo off
TITLE SUPPORT UTILITIES
goto menu

:menu
cls
@echo %username%
echo.
echo           .....................................
echo            ~Written by Cajun Wonder 4/1/2010~
echo           .....................................
echo.
echo What do you want to do? 
echo.
echo [1]  Launch notepad
echo.

:choice
set /P C=[Option]? 
if "%C%"=="1" goto notepad
goto choice

:notepad
echo.
@echo starting notepad....
@ping -n 3 127.0.0.1 > NUL
start notepad
cls
goto menu

我不是编码员,大约一年前才开始接触批处理脚本,我发现的在批处理文件中屏蔽密码的这种方式非常棒!

我希望听到除了我之外的其他人也能从中得到一些好处!

I read all the clunky solutions on the net about how to mask passwords in a batch file, the ones from using a hide.com solution and even the ones that make the text and the background the same color. The hide.com solution works decent, it isn't very secure, and it doesn't work in 64-bit Windows. So anyway, using 100% Microsoft utilities, there is a way!

First, let me explain my use. I have about 20 workstations that auto logon to Windows. They have one shortcut on their desktop - to a clinical application. The machines are locked down, they can't right click, they can't do anything but access the one shortcut on their desktop. Sometimes it is necessary for a technician to kick up some debug applications, browse windows explorer and look at log files without logging the autolog user account off.

So here is what I have done.

Do it however you wish, but I put my two batch files on a network share that the locked down computer has access to.

My solution utilizes 1 main component of Windows - runas.
Put a shortcut on the clients to the runas.bat you are about to create.
FYI, on my clients I renamed the shortcut for better viewing purposes and changed the icon.

You will need to create two batch files.

I named the batch files runas.bat and Debug Support.bat

runas.bat contains the following code:

cls
@echo off
TITLE CHECK CREDENTIALS 
goto menu

:menu
cls
echo.
echo           ....................................
echo            ~Written by Cajun Wonder 4/1/2010~
echo           ....................................
echo.
@set /p un=What is your domain username? 
if "%un%"=="PUT-YOUR-DOMAIN-USERNAME-HERE" goto debugsupport
if not "%un%"=="PUT-YOUR-DOMAIN-USERNAME-HERE" goto noaccess
echo.
:debugsupport
"%SYSTEMROOT%\system32\runas" /netonly /user:PUT-YOUR-DOMAIN-NAME-HERE\%un% "\\PUT-YOUR-NETWORK-SHARE-PATH-HERE\Debug Support.bat"
@echo ACCESS GRANTED! LAUNCHING THE DEBUG UTILITIES....
@ping -n 4 127.0.0.1 > NUL
goto quit
:noaccess
cls
@echo.
@echo.
@echo.
@echo.
@echo   \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
@echo   \\                                   \\
@echo   \\    Insufficient privileges         \\  
@echo   \\                                    \\
@echo   \\      Call Cajun Wonder             \\
@echo   \\                                    \\
@echo   \\              At                    \\
@echo   \\                                    \\
@echo   \\        555-555-5555                \\
@echo   \\                                    \\
@echo   \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
@ping -n 4 127.0.0.1 > NUL
goto quit
@pause
:quit
@exit

You can add as many if "%un%" and if not "%un%" for all the users you want to give access to.
The @ping is my coonass way of making a seconds timer.

So that takes care of the first batch file - pretty simple eh?

Here is the code for Debug Support.bat:

cls
@echo off
TITLE SUPPORT UTILITIES
goto menu

:menu
cls
@echo %username%
echo.
echo           .....................................
echo            ~Written by Cajun Wonder 4/1/2010~
echo           .....................................
echo.
echo What do you want to do? 
echo.
echo [1]  Launch notepad
echo.

:choice
set /P C=[Option]? 
if "%C%"=="1" goto notepad
goto choice

:notepad
echo.
@echo starting notepad....
@ping -n 3 127.0.0.1 > NUL
start notepad
cls
goto menu

I'm not a coder and really just started getting into batch scripting about a year ago, and this round about way that I discovered of masking a password in a batch file is pretty awesome!

I hope to hear that someone other than me is able to get some use out of it!

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文