Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations TouchToneTommy on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

How do I get a user's Password without showing it in Clear Text? (No InputBox)

Scripting for the Enterprise

How do I get a user's Password without showing it in Clear Text? (No InputBox)

by  PScottC  Posted    (Edited  )
For various reasons I have needed a visually safe form to allow users or administrators to input their credentials so that a script can perform a function requiring elevated privileges or alternate credentials. Unfortunately, the primary option available to scripters is the ScriptPW.dll, which allows masked input only through CScript (CLI). There is no native "graphical" interface to use.

The first portion of this FAQ will discuss the HTML code and how it works. The second part will present the Subs that you will be able to paste into your own code. I have put a lot of comments in-line so that the functionality will be clear.

Source Articles:
[link http://www.microsoft.com/technet/scriptcenter/resources/qanda/feb05/hey0204.mspx]Hey, Scripting Guy! How Can I Mask Passwords Using an InputBox?[/link]
[link http://msdn.microsoft.com/en-us/library/ms537628.aspx]Mark of the Web[/link]

FAQ Revisions:
Version 1: Thanks to tsuji and PHV for their input in this Tek-Tips Thread: thread329-1464252
Version 2: Thanks to markdmac for taking time to make constructive suggestions. This version incorporates his recommendations about clarity and purpose. Some additional features were added, and are discussed below.

This FAQ brings together ideas that I have had, comments from the forum members listed, and samples from the listed sources. Microsoft's concept gives a good starting point, but ends up being clunky due to the multiple file requirements. Ideas from the forum members really put the polish on.

=============================

Below, is the raw HTML code that I am using for the form.

Code:
<!-- saved from url=(0053)http://msdn.microsoft.com/en-us/library/ms537628.aspx -->
<head><title>Input Credentials</title></head>
<SCRIPT LANGUAGE='VBScript'>
	Sub RunScript
		OKClicked.Value = "OK"
	End Sub

	Sub CancelScript
		OKClicked.Value = "Cancelled"
	End Sub
</SCRIPT>

<SCRIPT LANGUAGE='JavaScript'>
	function CheckKey($key) {
		if ($key == 13) {
			RunScript();
		}
	}
</SCRIPT>

<BODY>
	<table border=0>
		<tr>
			<td>UserName:</td>
			<td><input type='text' name='UserName'></td>
		</tr>

		<tr>
			<td>Password:</td>
			<td><input type='password' name='UserPassword' onKeyPress='CheckKey(window.event.keyCode)'></td>
		</tr>

		<tr>
			<td colspan='2'>
				<center>
					<input id=runbutton class='button' type='button' value=' OK ' name='ok_button' onClick='RunScript'>
					&nbsp;&nbsp;&nbsp;
					<input id=runbutton class='button' type='button' value='Cancel' name='cancel_button' onClick='CancelScript'>
				</center>
			</td>
		</tr>
	</table>

	<input type='hidden' name='OKClicked' size = '20'>
</BODY>

The <BODY> section contains all the visual elements of the web page. The form is a simple table with 3 rows, each row surrounded by "<tr></tr>". The data for each field is surrounded by "<td></td>". (markdmac suggested using a table so that the formatting tags could be removed and the HTML would have greater clarity.) There are 4 types of input on the page, "<input type="password">", "<input type="text">", "<input type="button">", and "<input type="hidden">". The last of these inputs is a place holder so that the underlying VBScript can monitor the web page. The events "onKeyPress" and "onClick" allow the form to call the scripts that are on the page.

The <SCRIPT> sections contain actions to perform when the "onKeyPress" or "onClick" events occur. The CheckKey function looks for the "enter" key to be pressed while the cursor is in the password input box (this feature is new, the code was written by markdmac). The "RunScript" and "CancelScript" subs set values in the hidden input field allowing the underlying VBScript to know when data entry is complete and the values of the input boxes can be retrieved.

At the top of the HTML, a tag called "Mark of the Web" has been inserted. (I happen to be using the URL for the KB article about this subject.) This allows scripts on the page to execute without IE's anti-script defenses kicking in. NOTE: This does not overcome IE Hardening in Windows Server 2003 and 2008. To guarantee operation, I suggest disabling IE Hardening (for Administrators only).

At the bottom of the final code, notice that the HTML has been converted to a subroutine which places a text string into the variable that is passed in. At first glance the carriage returns seem to be superfluous, but they were put in place as a troubleshooting aid. They allow you to right-click on the form and choose "View Source" and have the resulting text be readable.

=============================

Below is the full script. The 2 subs are mostly self contained and can be simply pasted into any other script. You will need to provide a Shell object and whatever variables you want to contain the username and password.

NOTE: The way that the Tek-Tips forum renders the text may cause odd line wraps.

Code:
[green]
'===============================================================================
'
'    NAME: CredentialsSub.vbs
'
'  AUTHOR: P. S. Chapman
'
'    DATE: 5/26/2008
'
' COMMENT: Script creates an IE based credentials input window.  Masks user's
' password.
'
' sUserName and sPassword are passed to sub "ByRef" and are modified by the sub.
' This allows the script to use less memory space by not copying the data from
' variable to variable.
'
' HTM file is permitted to run scripts due to "Mark of the Web" placed at the top.
' Mark of the Web can be any URL.  The one in this script refers to Microsoft's
' MSDN page describing its use.
'
'===============================================================================[/green]
Option Explicit

[green]' Declare variables[/green]
Dim sUserName, sPassword, oShell

[green]' Create Shell object (used to bring IE to the foreground later)[/green]
Set oShell = CreateObject("WScript.Shell")

[green]' Call subroutine, passing variables that will be used/modified by the sub[/green]
Call GetPWInfo(sUserName, sPassword, oShell)

MsgBox "UserName: " & sUserName & VbCrLf & "Password: " & sPassword

[blue]Sub[/blue] GetPWInfo(ByRef sUserName, ByRef sPassword, oShell)
	Dim oIEPW, sPWHTML, ctr

	[green]' Get HTML and place it in a variable[/green]
	Call WriteHTML(sPWHTML)

	[green]' Create Internet Explorer object[/green]
	Set oIEPW = WScript.CreateObject("InternetExplorer.Application", "IE_")

	[green]' Set window properties[/green]
	With oIEPW
		.Navigate "about:blank" [green]' Use blank page as base[/green]
		Do While .ReadyState <> 4 [green]' Wait for IE process to start[/green]
			WScript.Sleep 50
		Loop
		.Document.Open [green]' Create document that will be in IE window[/green]
		.Document.Write (sPWHTML) [green]' Paste in HTML[/green]
		.Document.Close [green]' Complete the page creation[/green]
		.ToolBar = 0 [green]' Disable IE's tool bars[/green]
		.StatusBar = 0 [green]' Disable IE's status bar[/green]
		.Width = 325 [green]' Set window width in pixels[/green]
		.Height = 160 [green]' Set window height in pixels[/green]
		.Left = 72 [green]' Distance in pixels of window left edge to left side of screen[/green]
		.Top = 72 [green]' Distance in pixels of window top edge to top of screen[/green]
		Do While .ReadyState <> 4 [green]' Wait for all properties to be set[/green]
			WScript.Sleep 50
		Loop
		.Visible = 1 [green]' Make IE window visible[/green]
	End With

	[green]' Bring IE window to the top[/green]
	oShell.AppActivate "Input Credentials"

	[green]' Enter a loop to wait for user to enter valid credentials or hit cancel[/green]
	Do
		On Error Resume Next
		[green]' Monitor IE window for a change in value of the "OKClicked" hidden input[/green]
		Do While (oIEPW.Document.Body.All.OKClicked.Value = "")
			[green]' If Window is manually closed by user an error will be generated, exit sub[/green]
			If Err <> 0 Then
				[green]' User forcibly closed window, so set UserName and Password
				' to "cancelled" for calling code to parse[/green]
				sUserName = "cancelled"
				sPassword = "cancelled"
				Exit Sub
			End If
			Wscript.Sleep 250
		Loop
		On Error GoTo 0

		[green]' Check OKClicked value for OK or CANCELED[/green]
		If oIEPW.Document.Body.All.OKClicked.Value = "OK" Then
			[green]' Verify user input a value in the UserName input box[/green]
			If oIEPW.Document.Body.All.UserName.Value <> "" Then
				[green]' Capture UserName and Password values[/green]
				sUserName = oIEPW.Document.Body.All.UserName.Value
				sPassword = oIEPW.Document.Body.All.UserPassword.Value
				[green]' When ctr is set to 1, the script will be able to exit the loop[/green]
				ctr = 1
			Else
				[green]' User failed to put in a user name, modify the HTML to make UserName text appear red[/green]
				sPWHTML = Replace(sPWHTML,_
					"<td>UserName:</td>", _
					"<td><font color='red'>UserName: </font></td>", _
					1, 1, vbbinarycompare)

				[green]' Change the HTML document and update window[/green]
				With oIEPW
					.Document.Open
					.Document.Write (sPWHTML)
					.Document.Close
				End With
				[green]' Bring IE window back to the foreground[/green]
				oShell.AppActivate "Input Credentials"
			End If
		Else
			[green]' User clicked CANCEL, so set UserName and Password
			' to "cancelled" for calling code to parse[/green]
			sUserName = "cancelled"
			sPassword = "cancelled"
			[green]' Set ctr to 1 so that code can get out of loop[/green]
			ctr = 1
		End If
	Loop Until ctr = 1

	[green]' Shut down the IE process and associated window[/green]
	oIEPW.Quit
[blue]End Sub

Sub[/blue] WriteHTML(ByRef sPWHTML)
	[green]' ByRef passing of variable allows script to use less memory[/green]
	sPWHTML = _
		"<!-- saved from url=(0054)http://msdn2.microsoft.com/en-us/library/ms537628.aspx -->" & vbcrlf & _
		"<head><title>Input Credentials</title></head>" & vbcrlf & _
		"<SCRIPT LANGUAGE='VBScript'>" & vbcrlf & _
		"	Sub RunScript" & vbcrlf & _
		"		OKClicked.Value = ""OK""" & vbcrlf & _
		"	End Sub" & vbcrlf & _
		"	Sub CancelScript" & vbcrlf & _
		"		OKClicked.Value = ""Cancelled""" & vbcrlf & _
		"	End Sub" & vbcrlf & _
		"</SCRIPT>" & vbcrlf & _
		"<SCRIPT LANGUAGE='JavaScript'>" & vbcrlf & _
		"	function CheckKey($key) {" & vbcrlf & _
		"		if ($key == 13) {" & vbcrlf & _
		"			RunScript();" & vbcrlf & _
		"		}" & vbcrlf & _
		"	}" & vbcrlf & _
		"</SCRIPT>" & vbcrlf & _
		"<BODY>" & vbcrlf & _
		"	<table border=0>" & vbcrlf & _
		"		<tr>" & vbcrlf & _
		"			<td>UserName:</td>" & vbcrlf & _
		"			<td><input type='text' name='UserName'></td>" & vbcrlf & _
		"		</tr>" & vbcrlf & _
		"		<tr>" & vbcrlf & _
		"			<td>Password:</td>" & vbcrlf & _
		"			<td><input type='password' name='UserPassword' onKeyPress='CheckKey(window.event.keyCode)'></td>" & vbcrlf & _
		"		</tr>" & vbcrlf & _
		"		<tr>" & vbcrlf & _
		"			<td colspan='2'>" & vbcrlf & _
		"				<center>" & vbcrlf & _
		"					<input id=runbutton class='button' type='button' value=' OK ' name='ok_button' onClick='RunScript'>" & vbcrlf & _
		"					&nbsp;&nbsp;&nbsp;" & vbcrlf & _
		"					<input id=runbutton class='button' type='button' value='Cancel' name='cancel_button' onClick='CancelScript'>" & vbcrlf & _
		"				</center>" & vbcrlf & _
		"			</td>" & vbcrlf & _
		"		</tr>" & vbcrlf & _
		"	</table>" & vbcrlf & _
		"	<input type='hidden' name='OKClicked' size = '20'>" & vbcrlf & _
		"</BODY>"
[blue]End Sub[/blue]
Register to rate this FAQ  : BAD 1 2 3 4 5 6 7 8 9 10 GOOD
Please Note: 1 is Bad, 10 is Good :-)

Part and Inventory Search

Back
Top