Solución:
Sí, llego 4 años tarde.
Pero encontré una manera de hacer esto en una línea sin tener que crear un script externo; llamando a los comandos de PowerShell desde un archivo por lotes.
Gracias a TessellatesHeckler, sin generar un archivo de texto (configuré el comando powershell en una variable, porque es bastante complicado en una línea larga dentro de un bucle 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 lo escribí para enviarlo a un archivo de texto, luego lo leí desde ese archivo de texto. Pero el método anterior es mejor. En una línea extremadamente larga, casi incomprensible:
@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%
Desglosaré esto: puedes dividirlo en unas pocas líneas usando el símbolo de intercalación ^
, que es mucho mejor …
@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 artículo explica qué están haciendo los comandos de PowerShell; esencialmente obtiene entrada usando Read-Host -AsSecureString
– las siguientes dos líneas convierten esa cadena segura de nuevo en texto sin formato, la salida (contraseña de texto sin formato) se envía a un archivo de texto usando >.tmp.txt
. Luego, ese archivo se lee en una variable y se elimina.
Hasta XP y Server 2003, puede utilizar otra herramienta incluida (VBScript): los dos scripts siguientes hacen el trabajo que desea.
Primero, getpwd.cmd
:
@echo off
<nul: set /p passwd=Password:
for /f "delims=" %%i in ('cscript /nologo getpwd.vbs') do set passwd=%%i
echo.
Luego, getpwd.vbs
:
Set oScriptPW = CreateObject("ScriptPW.Password")
strPassword = oScriptPW.GetPassword()
Wscript.StdOut.WriteLine strPassword
los getpwd.vbs
simplemente usa el objeto de contraseña para ingresar la contraseña del usuario y luego imprimirla en la salida estándar (el siguiente párrafo explicará por qué eso no aparece en la terminal).
los getpwd.cmd
El script de comando es un poco más complicado, pero básicamente funciona de la siguiente manera.
El efecto de la "<nul: set /p passwd=Password: "
comando es generar el símbolo del sistema sin un carácter de nueva línea final; es una forma astuta de emular el "echo -n"
comando desde el bash
cascarón. Establece passwd
a una cadena vacía como un efecto secundario irrelevante y no espera la entrada ya que está tomando su entrada del nul:
dispositivo.
los "for /f "delims=" %%i in ('cscript /nologo getpwd.vbs') do set passwd=%%i"
La declaración es la parte más complicada. Ejecuta VBScript sin “publicidad” de Microsoft, por lo que la única salida de línea es la contraseña (de VBscript "Wscript.StdOut.WriteLine strPassword"
.
No es necesario establecer los delimitadores en nada para capturar una línea de entrada completa con espacios; de lo contrario, solo obtiene la primera palabra. los "for ... do set ..."
conjuntos de bits passwd
para que sea la salida de contraseña real de VBScript.
Luego hacemos eco de una línea en blanco (para terminar el "Password: "
línea) y la contraseña estará en el passwd
variable de entorno después de que se haya ejecutado el código.
Ahora, como se mencionó, scriptpw.dll
sólo está disponible hasta XP / 2003. Para rectificar esto, simplemente puede copiar el scriptpw.dll
archivo de la WindowsSystem32
carpeta de un sistema XP / 2003 a la WinntSystem32
o WindowsSystem32
carpeta en su propio sistema. Una vez que se haya copiado la DLL, deberá registrarla ejecutando:
regsvr32 scriptpw.dll
Para registrar correctamente la DLL en Vista y versiones posteriores, necesitará privilegios de administrador. No he examinado la legalidad de un movimiento así, lector de cuevas.
Si no estás demasiado interesado en intentar rastrear y registrar archivos DLL más antiguos (por conveniencia o razones legales), hay otra forma. Versiones posteriores de Windows (las que no tiene la DLL requerida) debe tener Powershell disponible para usted.
Y, de hecho, debería considerar actualizar sus scripts para usarlos por completo, ya que es un lenguaje de scripts mucho más capaz que cmd.exe
. Sin embargo, si desea mantener la mayor parte de su código como cmd.exe
guiones (por ejemplo, si tiene un lote de código que no desea convertir), puede usar el mismo truco.
Primero, modifique el cmd
script para que llame a Powershell en lugar de CScript:
@echo off
for /f "delims=" %%i in ('powershell -file getpwd.ps1') do set passwd=%%i
El script de Powershell es igualmente simple:
$password = Read-Host "Enter password" -AsSecureString
$password = [Runtime.InteropServices.Marshal]::SecureStringToBSTR($password)
$password = [Runtime.InteropServices.Marshal]::PtrToStringAuto($password)
echo $password
aunque con algunas referencias para obtener el texto real de la contraseña.
Recuerde que, para ejecutar scripts de Powershell locales sin firmar en su máquina, es posible que deba modificar la política de ejecución del valor predeterminado (draconiano, aunque muy seguro), con algo como:
set-executionpolicy remotesigned
desde el propio Powershell.
1.Solución por lotes pura que (ab) usa XCOPY
comando y su /P /L
interruptores que se encuentran aquí (algunas mejoras en esto se pueden encontrar aquí):
:: 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 Otra forma basada en el comando reemplazar
@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.Remitente de contraseña que utiliza una ventana emergente de HTA
. Este es un archivo hybrit .bat / jscript / mshta y debe guardarse como .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.Un híbrido .net autocompilado .De nuevo debe guardarse como .bat
A diferencia de otras soluciones, creará / compilará un pequeño archivo .exe que se llamará (si lo desea, puede eliminarlo). También requiere un marco .net instalado, pero eso no es un 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.NETFramework*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);