Posso mascarar um texto de entrada em um arquivo bat?


102

Estou escrevendo um arquivo em lote para executar alguns outros programas. Nesse caso, preciso solicitar uma senha. Eu tenho alguma maneira de mascarar o texto de entrada? Não preciso imprimir caracteres ******* em vez de caracteres de entrada. O comportamento do prompt de senha do Linux (não imprimir nada ao digitar) é suficiente.

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

Isso lerá a entrada, mas não consigo mascarar o texto usando essa abordagem.


Respostas:


50

Até o XP e o Server 2003, você pode usar outra ferramenta incluída (VBScript) - os dois scripts a seguir fazem o trabalho que você deseja.

Primeiro getpwd.cmd:

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

Então getpwd.vbs,:

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

O getpwd.vbssimplesmente usa o objeto de senha para inserir a senha do usuário e depois imprime na saída padrão (o próximo parágrafo irá explicar por que isso não aparece no terminal).

O getpwd.cmdscript de comando é um pouco mais complicado, mas basicamente funciona da seguinte maneira.

O efeito do "<nul: set /p passwd=Password: "comando é produzir o prompt sem nenhum caractere de nova linha à direita - é uma maneira sorrateira de emular o "echo -n"comando do bashshell. Ele é definido passwdcomo uma string vazia como um efeito colateral irrelevante e não espera pela entrada, pois está recebendo a entrada do nul:dispositivo.

A "for /f "delims=" %%i in ('cscript /nologo getpwd.vbs') do set passwd=%%i"declaração é a parte mais complicada. Ele executa o VBScript sem "publicidade" da Microsoft, de modo que a única saída de linha é a senha (do VBscript "Wscript.StdOut.WriteLine strPassword".

Definir os delimitadores para zero é necessário para capturar uma linha de entrada inteira com espaços, caso contrário, você apenas obterá a primeira palavra. O "for ... do set ..."bit é definido passwdcomo a saída de senha real do VBScript.

Em seguida, ecoamos uma linha em branco (para encerrar a "Password: "linha) e a senha estará na passwdvariável de ambiente após a execução do código.


Agora, conforme mencionado, scriptpw.dllestá disponível apenas até XP / 2003. Para corrigir isso, você pode simplesmente copiar o scriptpw.dllarquivo da Windows\System32pasta de um sistema XP / 2003 para a pasta Winnt\System32ou Windows\System32em seu próprio sistema. Depois que a DLL for copiada, você precisará registrá-la executando:

regsvr32 scriptpw.dll

Para registrar com êxito a DLL no Vista e posterior, você precisará de privilégios de administrador. Eu não examinei a legalidade de tal movimento, então leitor das cavernas.


Se você não estiver muito interessado em rastrear e registrar arquivos DLL mais antigos (por conveniência ou por motivos legais), existe outra maneira. Versões posteriores do Windows (aquelas que não têm a DLL necessária) devem ter o Powershell disponível para você.

E, de fato, você realmente deve considerar atualizar seus scripts para usá-los totalmente, já que é uma linguagem de script muito mais capaz do que cmd.exe. No entanto, se você deseja manter a maior parte do seu código como cmd.exescripts (por exemplo, se você tiver muitos códigos que não deseja converter), pode usar o mesmo truque.

Primeiro, modifique o cmdscript para que ele chame Powershell em vez de CScript:

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

O script Powershell é igualmente simples:

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

embora com algum empacotamento para obter o texto da senha real.

Lembre-se de que, para executar scripts Powershell locais não assinados em sua máquina, você pode precisar modificar a política de execução do padrão (draconiano, embora muito seguro), com algo como:

set-executionpolicy remotesigned

de dentro do próprio Powershell.


2
Uau, esse <nul: set / p é muito legal. Não sabia disso até agora :-). Mas o VBScript não funciona para mim: Erro de tempo de execução do Microsoft VBScript: O componente ActiveX não pode criar o objeto: 'ScriptPW.Password'. Windows 7 Beta x64 aqui.
Joey de

Interessante, ele deveria estar disponível a partir do XP. Suspeito que o Win7 ainda não esteja concluído se não funcionar lá (ou você terá que fazer algum outro truque para fazê-lo funcionar). Um pouco de pesquisa mostra por quê: veja minha atualização.
paxdiablo

2
Agradável. Também é bom observar que você pode substituir o arquivo VBS por qualquer linguagem equivalente que possa ser chamada a partir da linha de comando. Por exemplo, você pode substituir a seção cscript por: 'python -c "from getpass import getpass; pwd = getpass (); print pwd;"'
Cerin

1
Eu costumava usar esse caminho quando essa questão era nova - respondi abaixo uma maneira de fazer isso sem scripts extras.
impuro

1
@Bill: Daí minha seção começando com "Agora, infelizmente, ..." :-) No entanto, adicionei mais opções à resposta para torná-la melhor. Especificamente, o uso de PowerShell em vez de scriptpw.dll.
paxdiablo

153

Sim - estou 4 anos atrasado.

Mas descobri uma maneira de fazer isso em uma linha, sem precisar criar um script externo; chamando comandos do PowerShell de um arquivo em lote.

Graças a TessellatingHeckler - sem enviar para um arquivo de texto (eu defini o comando powershell em uma variável, porque é muito confuso em uma linha longa dentro de um loop 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%

Originalmente, eu o escrevi para gerar um arquivo de texto e depois li esse arquivo de texto. Mas o método acima é melhor. Em uma linha extremamente longa e quase incompreensível:

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

Vou dividir isso - você pode dividir em algumas linhas usando o cursor ^, que é muito melhor ...

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

Este artigo explica o que os comandos do PowerShell estão fazendo; essencialmente, ele obtém a entrada usando Read-Host -AsSecureString- as duas linhas a seguir convertem aquela string segura de volta em texto simples, a saída (senha em texto simples) é então enviada para um arquivo de texto usando >.tmp.txt. Esse arquivo é então lido em uma variável e excluído.


5
A resposta original foi ótima, mas acho que esta deve ser a definitiva agora
James Wiseman

30
Isto é brilhante. Mas a maneira como ele salva uma senha de texto simples no disco me deixa desconfortável. Evite fazer isso ao invés disso: for /f "usebackq tokens=*" %%p in (``powershell -Command "$pword = read-host 'Enter Password' -AsSecureString ; $BSTR=[System.Runtime.InteropServices.Marshal]::SecureStringToBSTR($pword); [System.Runtime.InteropServices.Marshal]::PtrToStringAuto($BSTR)"``) do set password=%%pe então echo %password%. NB. Não consigo fazer com que este comentário escape de crases corretamente - antes de "powershell" e antes do final ")" são duas crases, mas devem ser uma crase.
TessellatingHeckler

1
@TessellatingHeckler Boa ideia, atualizei minha resposta. Uma versão ligeiramente modificada de sua sugestão. Obrigado.
unclemeat

É possível impedir que esse método exiba "*" (estrela) a cada pressionamento de tecla? ou seja, não quero que um observador saiba quanto tempo a senha tem.
Sam Hasler

1
@RegieBaguio Não, você precisará do Powershell habilitado. Dê uma olhada na solução em lote pura da npocmaka abaixo. É muito mais complicado, mas deve funcionar para você.
impuro,

26

1. Solução em lote pura que (ab) usa o XCOPYcomando e suas /P /Lopções encontradas aqui (algumas melhorias podem ser encontradas aqui ):

:: 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 Outra forma baseada no comando de substituição

@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. Submissor de senha que usa um pop-up HTA . Este é um arquivo hybrit .bat / jscript / mshta e deve ser salvo como um .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. Um .net híbrido auto-compilado .Again deve ser salvo como .bat. Ao contrário de outras soluções, ele criará / compilará um pequeno arquivo .exe que será chamado (se desejar, pode excluí-lo). Também requer estrutura .net instalada, mas isso não é um problema:

@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);

6
Meu sentido hacky está formigando, especialmente no híbrido!
Mark K Cowan

2
Essa primeira solução é muito inteligente - bela +1.
impuro de

O método 2.1 baseado no comando replace perderá os pressionamentos de tecla se você digitar rapidamente
Sam Hasler

@SamHasler - sim. Vou tentar consertar isso. Embora não tenha conseguido reproduzir o problema com o 2.1. Também atualizei o HTA para verificar se a tecla Enter foi pressionada.
npocmaka

1
@npocmaka a última versão do método 1.2 (última atualização: 20150405) está aqui: consolesoft.com/batch/password_input/password_input.cmd
carlos

16

Eu provavelmente faria apenas:

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

Assim, você recebe um prompt e a tela é limpa depois de inserida.

Observe que a senha inserida será armazenada no histórico do CMD se o arquivo em lote for executado a partir de um prompt de comando (Obrigado @Mark K Cowan ).

Se isso não fosse bom o suficiente, eu mudaria para o python ou escreveria um executável em vez de um script.

Eu sei que nenhuma dessas são soluções perfeitas, mas talvez uma seja boa o suficiente para você :)


4
Observe que a senha inserida será armazenada no histórico do CMD se o arquivo em lote for executado a partir de um prompt de comando. Nenhum voto negativo, pois você disse que o cmd é a ferramenta errada para o trabalho.
Mark K Cowan

Você pode executar doskey /reinstallpara limpar o buffer de comando anterior imediatamente após cls, se o histórico de comando no console não for importante para você.
RuntimeException

1
se você não quiser usar doskey / reinstalar e limpar o histórico de comandos, outra opção é executar o código acima em uma janela de terminal separada e sair imediatamente. Observe que isso ainda não substitui sua String digitada por asteriscos. A solução acima é uma opção se você não quiser executar o PowerShell. C:\>start "console" cmd /c ireadconsole.bat
RuntimeException

9

Você pode usar a sub-rotina ReadFormattedLine para todos os tipos de entrada formatada. Por exemplo, o comando abaixo lê uma senha de 8 caracteres, exibe asteriscos na tela e continua automaticamente sem a necessidade de pressionar Enter:

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

Esta sub-rotina é escrita em puro Lote, portanto, não requer nenhum programa adicional e permite várias operações de entrada formatadas, como ler apenas números, converter letras em maiúsculas, etc. Você pode baixar a sub-rotina ReadFormattedLine em Ler uma linha com formato específico .


EDITAR 18/08/2018 : Novo método para inserir uma senha "invisível"

O comando FINDSTR tem um bug estranho que acontece quando este comando é usado para mostrar caracteres em cores E a saída de tal comando é redirecionada para o dispositivo CON. Para obter detalhes sobre como usar o comando FINDSTR para mostrar texto em cores, consulte este tópico .

Quando a saída desta forma do comando FINDSTR é redirecionada para CON, algo estranho acontece depois que o texto é gerado na cor desejada: todo o texto depois dele é produzido como caracteres "invisíveis", embora uma descrição mais precisa é que o texto é saída como texto preto sobre fundo preto. O texto original aparecerá se você usar o comando COLOR para redefinir as cores de primeiro e segundo plano de toda a tela. Porém, quando o texto está "invisível" podemos executar um comando SET / P, de forma que todos os caracteres inseridos não apareçam na tela.

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

5

outra alternativa são minhas ferramentas de linha de comando EditV32 (x86) ou EditV64 (x64). Por exemplo:

editv32 -m -p "Password: " PWD

-m significa "entrada mascarada" e -p é o prompt. A entrada do usuário é armazenada na variável de ambiente PWD. Você pode obtê-lo aqui:

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


5
Esta não é a única solução de código fechado (o Windows é um código fechado!). Você está livre para não usá-lo, é claro ...
Bill_Stewart

Se a falta de código-fonte o incomoda, veja minha outra resposta sobre ReadLine.exe .
Bill_Stewart

Um bom! A licença permite que você o use. Além disso, é fácil de integrar. Apenas para lidar com o código de saída 1. Erro na linha de comando, 2 A linha de entrada estava em branco, 3 A variável de ambiente não foi alterada, 4 Programa abortado com Ctrl-C
James Jithin

Nota: Os utilitários editenv32 / editenv64 e readline foram substituídos pelo utilitário editenv de código aberto.
Bill_Stewart

4

Se a falta de código-fonte o incomoda, tenho outra alternativa.

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

Você pode obtê-lo em https://westmesatech.com/?page_id=49 . O código-fonte está incluído.


Nota: Os utilitários editenv32 / editenv64 e readline foram substituídos pelo utilitário editenv de código aberto.
Bill_Stewart

3

Se você tiver o Python instalado, poderá usar:

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

a saída:

Enter the CVS password:
PASS: 123

2

Eu usei a solução de Blorgbeard acima, que é realmente ótima na minha opinião. Então eu o aprimorei da seguinte maneira:

  1. Google para ansicon
  2. Baixe o arquivo zip e o arquivo de texto de amostra.
  3. Instalar (isso significa copiar 2 arquivos no system32)

Use-o assim:

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

Isso muda o console para cinza em cinza para a entrada da senha e volta quando você terminar. O ESC deve ser, na verdade, um caractere não imprimível, que você pode copiar do arquivo de texto de amostra baixado (aparece como uma seta para a esquerda no Bloco de notas) para o arquivo em lote. Você pode usar o arquivo de texto de amostra para encontrar os códigos para todas as combinações de cores.

Se você não for o administrador da máquina, provavelmente conseguirá instalar os arquivos em um diretório que não seja do sistema, então terá que anexar o diretório ao PATH em seu script antes de chamar o programa e usar as sequências de escape. Provavelmente, este pode até ser o diretório atual, se você precisar de um pacote distribuível não administrativo de apenas alguns arquivos.


Não posso testar isso, mas espero que a senha digitada apareça no histórico do cmd posteriormente.
Mark K Cowan

@MarkKCowan É exatamente o que acontece.
sjngm

1

faça um arquivo em lote que chame aquele necessário para caracteres invisíveis e, em seguida, faça um atalho para o arquivo em lote que está sendo chamado.

clique direito

propriedades

cores

texto == preto

fundo == preto

Aplique

Está bem

espero assim te ajude !!!!!!!!


boa abordagem de pensamento lateral, mesmo que nem sempre seja prática em uma situação de lote devido a ter que configurar o ambiente com antecedência. Oh, espere, talvez isso funcione: stackoverflow.com/a/14447306/14420 ou talvez stackoverflow.com/questions/4339649/…
matt wilkie

1

ATUALIZAÇÃO:
adicionei dois novos métodos que, em vez de utilizar cls para ocultar a entrada, criam um novo pop-up com apenas uma linha.

As desvantagens são que um método (método 2) deixa lixo no registro - "Se executado sem os direitos apropriados", e o outro (método três) adiciona lixo ao script. Desnecessário dizer que ele pode ser facilmente gravado em qualquer arquivo tmp e excluído. Eu apenas tentei pensar em uma alternativa.

Limitação: A senha só pode ser alfanumérica - sem outros caracteres!

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

Atualização: achei a postagem de sachadee perfeita e acabei de adicionar minha peculiaridade "pop-up" a ela.

@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

Eu escrevi um programa de código aberto chamado editenvque substitui meus editv32/ editv64utilitários mais antigos :

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

A opção --maskinput( -m) [*] permite ocultar (mascarar) a entrada digitada e tem um caractere configurável (o caractere padrão é *); por exemplo:

editenv -m -p "Password: " PWD

A opção --prompt( -p) permite especificar um prompt de entrada. O Password:item acima exibirá um prompt e esperará que você insira algo. Os caracteres digitados aparecerão como *. Pressionar Ctrl+ Cencerrará o programa com um código de saída 1223.

O download está aqui:

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

[*] Observe que a opção --maskinput( -m) não é segura - a string inserida é inserida como texto simples no ambiente. Este recurso é apenas para conveniência.



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

Você não explicou o código e apenas o copiou. Esta não é uma boa maneira de fazer isso, pois você precisa atualizar a tela e a senha deve ter x caracteres.
Anic17

-1

Outra opção, na mesma linha que Blorgbeard está fora de questão, é usar algo como:

SET /P pw=C:\^>

O ^escapa do >para que o prompt de senha pareça um prompt de console cmd padrão.


1
A questão não é como ocultar / disfarçar o prompt de senha, mas evitar que a senha apareça durante a digitação. Portanto, isso não (tenta) responder à pergunta.
Stephan

Nem a resposta que eu vinculei (que no momento da escrita tinha 13 votos positivos). Minha resposta é apenas expandir isso, já que esta pode ser uma alternativa útil para alguns (como o Blogbeard está fora de questão para mim). (Eu teria adicionado como um comentário, mas o site não permite.)
nimbell

Essa não é uma boa resposta. Você não está mascarando nem escondendo a senha. Comente assim que tiver uma boa solução ou resposta.
Anic17

-3

Eu li todas as soluções desajeitadas na rede sobre como mascarar senhas em um arquivo em lote, as que usam uma solução hide.com e até as que fazem o texto e o fundo da mesma cor. A solução hide.com funciona decentemente, não é muito segura e não funciona no Windows de 64 bits. De qualquer forma, usando utilitários 100% Microsoft, existe uma maneira!

Primeiro, deixe-me explicar meu uso. Tenho cerca de 20 estações de trabalho que fazem logon automático no Windows. Eles têm um atalho em sua área de trabalho - para um aplicativo clínico. As máquinas estão bloqueadas, eles não podem clicar com o botão direito, eles não podem fazer nada além de acessar o atalho em sua área de trabalho. Às vezes, é necessário que um técnico execute alguns aplicativos de depuração, navegue no Windows Explorer e examine os arquivos de log sem fazer logoff da conta do usuário do autolog.

Então aqui está o que eu fiz.

Faça como quiser, mas coloquei meus dois arquivos em lote em um compartilhamento de rede ao qual o computador bloqueado tem acesso.

Minha solução utiliza 1 componente principal do Windows - runas. Coloque um atalho nos clientes para o runas.bat que você está prestes a criar. Para sua informação, em meus clientes, renomeei o atalho para uma melhor visualização e mudei o ícone.

Você precisará criar dois arquivos em lote.

Chamei os arquivos em lote de runas.bat e Debug Support.bat

runas.bat contém o seguinte código:

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

Você pode adicionar tantos se "% un%" e se não "% un%" para todos os usuários aos quais deseja dar acesso. O @ping é minha maneira de fazer um cronômetro de segundos.

Então isso cuida do primeiro arquivo em lote - muito simples, não é?

Aqui está o código para 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

Não sou um programador e na verdade comecei a trabalhar com scripts em lote há cerca de um ano, e essa maneira geral que descobri de mascarar uma senha em um arquivo em lote é incrível!

Espero ouvir que outra pessoa além de mim possa tirar algum proveito disso!

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.