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.
FAQ Revisions: Version 1: Thanks to tsuji and PHV for their input in this Tek-Tips Thread: thread329-1464252: Username / Password entry with masking 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.
<!-- 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>
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.
'=============================================================================== ' ' 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. ' '=============================================================================== Option Explicit
' Declare variables Dim sUserName, sPassword, oShell
' Create Shell object (used to bring IE to the foreground later) Set oShell = CreateObject("WScript.Shell")
' Call subroutine, passing variables that will be used/modified by the sub Call GetPWInfo(sUserName, sPassword, oShell)
Sub GetPWInfo(ByRef sUserName, ByRef sPassword, oShell) Dim oIEPW, sPWHTML, ctr
' Get HTML and place it in a variable Call WriteHTML(sPWHTML)
' Create Internet Explorer object Set oIEPW = WScript.CreateObject("InternetExplorer.Application", "IE_")
' Set window properties With oIEPW .Navigate "about:blank" ' Use blank page as base Do While .ReadyState <> 4 ' Wait for IE process to start WScript.Sleep 50 Loop .Document.Open ' Create document that will be in IE window .Document.Write (sPWHTML) ' Paste in HTML .Document.Close ' Complete the page creation .ToolBar = 0 ' Disable IE's tool bars .StatusBar = 0 ' Disable IE's status bar .Width = 325 ' Set window width in pixels .Height = 160 ' Set window height in pixels .Left = 72 ' Distance in pixels of window left edge to left side of screen .Top = 72 ' Distance in pixels of window top edge to top of screen Do While .ReadyState <> 4 ' Wait for all properties to be set WScript.Sleep 50 Loop .Visible = 1 ' Make IE window visible End With
' Bring IE window to the top oShell.AppActivate "Input Credentials"
' Enter a loop to wait for user to enter valid credentials or hit cancel Do On Error Resume Next ' Monitor IE window for a change in value of the "OKClicked" hidden input Do While (oIEPW.Document.Body.All.OKClicked.Value = "") ' If Window is manually closed by user an error will be generated, exit sub If Err <> 0 Then ' User forcibly closed window, so set UserName and Password ' to "cancelled" for calling code to parse sUserName = "cancelled" sPassword = "cancelled" Exit Sub End If Wscript.Sleep 250 Loop On Error GoTo 0
' Check OKClicked value for OK or CANCELED If oIEPW.Document.Body.All.OKClicked.Value = "OK" Then ' Verify user input a value in the UserName input box If oIEPW.Document.Body.All.UserName.Value <> "" Then ' Capture UserName and Password values sUserName = oIEPW.Document.Body.All.UserName.Value sPassword = oIEPW.Document.Body.All.UserPassword.Value ' When ctr is set to 1, the script will be able to exit the loop ctr = 1 Else ' User failed to put in a user name, modify the HTML to make UserName text appear red sPWHTML = Replace(sPWHTML,_ "<td>UserName:</td>", _ "<td><font color='red'>UserName: </font></td>", _ 1, 1, vbbinarycompare)
' Change the HTML document and update window With oIEPW .Document.Open .Document.Write (sPWHTML) .Document.Close End With ' Bring IE window back to the foreground oShell.AppActivate "Input Credentials" End If Else ' User clicked CANCEL, so set UserName and Password ' to "cancelled" for calling code to parse sUserName = "cancelled" sPassword = "cancelled" ' Set ctr to 1 so that code can get out of loop ctr = 1 End If Loop Until ctr = 1
' Shut down the IE process and associated window oIEPW.Quit End Sub