web-dev-qa-db-ja.com

batファイルの入力テキストをマスクできますか

他のプログラムを実行するためのバッチファイルを作成しています。この場合、パスワードを要求する必要があります。入力テキストをマスクする方法はありますか。入力文字の代わりに*******文字を印刷する必要はありません。 Linuxのパスワードプロンプトの動作(入力中は何も印刷しない)で十分です。

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

これは入力を読み取りますが、このアプローチを使用してテキストをマスクすることはできません。

XPおよびServer 2003までは、別の付属ツール(VBScript)を使用できます。次の2つのスクリプトが目的の作業を実行します。

まず、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コマンドスクリプトは少し複雑ですが、基本的には次のように機能します。

"<nul: set /p passwd=Password: "コマンドの効果は、末尾の改行文字なしでプロンプトを出力することです。これは、bashシェルから"echo -n"コマンドをエミュレートする卑劣な方法です。 passwdを無関係な副作用として空の文字列に設定し、nul:デバイスから入力を取得するため、入力を待機しません。

"for /f "delims=" %%i in ('cscript /nologo getpwd.vbs') do set passwd=%%i"ステートメントは最も扱いにくいビットです。 Microsoftの「広告」なしでVBScriptを実行するため、唯一の行出力はパスワードです(VBscript "Wscript.StdOut.WriteLine strPassword"から)。

スペースを含む入力行全体をキャプチャするには、区切り文字を何も設定しないでください。そうしないと、最初のWordが取得されます。 "for ... do set ..."ビットは、passwdをVBScriptからの実際のパスワード出力に設定します。

次に、空白行をエコーし​​て("Password: "行を終了する)、コードの実行後にパスワードがpasswd環境変数に格納されます。


さて、前述のように、scriptpw.dllはXP/2003までしか利用できません。これを修正するには、scriptpw.dllファイルをXP/2003システムのWindows\System32フォルダーからご使用のシステムのWinnt\System32またはWindows\System32フォルダーにコピーするだけです。 DLLをコピーしたら、次を実行して登録する必要があります。

regsvr32 scriptpw.dll

Vista以降でDLLを正常に登録するには、管理者特権が必要です。私はそのような移動の合法性を調べていないので、洞窟学者。


過度に古いDLLファイルを追跡して登録しようとする場合(便宜上または法的理由により)、別の方法があります。それ以降のバージョンのWindows(do n'tに必要なDLLが含まれているもの)には、Powershellが利用可能である必要があります。

実際、cmd.exeよりもはるかに優れたスクリプト言語であるため、スクリプトを完全に使用するようにアップグレードすることを検討する必要があります。ただし、コードの大部分をcmd.exeスクリプトとして保持したい場合(変換したくないコードのlotがある場合など)、同じトリック。

まず、cmdスクリプトを変更して、CScriptではなくPowershellを呼び出すようにします。

@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自体から。

49
paxdiablo

はい-4年遅れています。

しかし、外部スクリプトを作成せずに1行でこれを行う方法を見つけました。バッチファイルからpowershellコマンドを呼び出します。

TessellatingHecklerのおかげで-テキストファイルに出力せずに(forループ内の1つの長い行でかなり乱雑なので、変数にpowershellコマンドを設定しています)。

@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%

もともと、テキストファイルに出力するために作成し、そのテキストファイルから読み取りました。しかし、上記の方法の方が優れています。 1つの非常に長い、ほとんど理解できない行で:

@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を使用して入力を取得します。次の2行は、その安全な文字列をプレーンテキストに変換し、出力(プレーンテキストパスワード)が>.tmp.txtを使用してテキストファイルに送信されます。そのファイルは変数に読み込まれ、削除されます。

143
unclemeat

1。純粋なバッチソリューションXCOPYコマンドとその/P /Lスイッチを使用(ab)する 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 replaceコマンドに基づく別の方法

@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. 自己コンパイルされた.netハイブリッド .Againは .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);
23
npocmaka

私はおそらくただやるでしょう:

..
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に切り替えるか、スクリプトの代わりに実行可能ファイルを作成します。

私はこれらのどれも完璧なサウションではないことを知っていますが、おそらくあなたにとっては十分です:)

12
Blorgbeard

別の選択肢は、EditV32(x86)またはEditV64(x64)コマンドラインツールです。例えば:

editv32 -m -p "Password: " PWD

-mは「マスクされた入力」を意味し、-pはプロンプトです。ユーザーの入力は、PWD環境変数に保存されます。ここから入手できます:

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

6
Bill_Stewart

もしソースコードの欠如があなたを悩ますなら、私には別の選択肢があります。

@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 から取得できます。ソースコードが含まれています。

5
Bill_Stewart

すべての種類の書式付き入力にReadFormattedLineサブルーチンを使用できます。たとえば、次のコマンドは8文字のパスワードを読み取り、画面にアスタリスクを表示し、Enterキーを押す必要なく自動的に続行します。

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

このサブルーチンは純粋なバッチで記述されているため、追加のプログラムは不要です。また、数字だけの読み取り、文字の大文字への変換など、いくつかのフォーマットされた入力操作が可能です。ReadFormattedLineサブルーチンは 特定の形式


2018-08-18EDIT「見えない」パスワードを入力する新しい方法

FINDSTRコマンドには、このコマンドを使用して文字をカラーで表示し、そのようなコマンドの出力を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%"
4
Aacini

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
4
lutecki

非表示の文字に必要なものを呼び出すバッチファイルを作成し、呼び出されるバッチファイルのショートカットを作成します。

右クリック

物性

text == black

背景==黒

適用する

oK

希望がこうしてあなたを助ける!!!!!!!!

1
cmd

UPDATE:
clsを使用して入力を非表示にする代わりに、1行のみの新しいポップアップを作成する2つの新しいメソッドを追加しました。

欠点は、1つの方法(方法2)がレジストリにジャンクを残す-「適切な権限なしで実行された場合」、もう1つ(方法3)がスクリプトにジャンクを追加することです。言うまでもなく、任意の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
1
Ir Relevant

私は、Blogbeardの上記のソリューションを使用しましたが、これは私の意見では実際に素晴らしいです。次に、次のように拡張しました。

  1. Google ansicon
  2. Zipファイルとサンプルテキストファイルをダウンロードします。
  3. インストール(つまり、2つのファイルをsystem32にコピーします)

次のように使用します。

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

これにより、パスワード入力のためにコンソールがグレーオングレーに切り替わり、完了したら元に戻ります。 ESCは実際には印刷できない文字である必要があり、ダウンロードしたサンプルテキストファイル(メモ帳の左矢印のように表示されます)からバッチファイルにコピーできます。サンプルテキストファイルを使用して、すべての色の組み合わせのコードを見つけることができます。

マシンの管理者でない場合は、システム以外のディレクトリにファイルをインストールできる可能性が高いため、プログラムを呼び出してエスケープシーケンスを使用する前に、スクリプトのPATHにディレクトリを追加する必要があります。いくつかのファイルのみの非管理者配布可能パッケージが必要な場合、これはおそらく現在のディレクトリになります。

1
marcingo

これは古いトピックかもしれませんが、Windows Vistaまたは7を使用している場合、非常にうまく機能するソリューションがあります。ここでビデオを作成しました: http://www.youtube.com/watch?v=mk8uAa6PIFM

バッチファイルのPastebin ここにあります

0
Nathansswell