Mr. Script

No More Prying Eyes

Encoding scripts to prevent unauthorized access.

I like scripts to be as informative as possible, with vast amounts of data, status of operations and the like echoed back to me as the script runs. That’s one reason I use the CScript.exe engine rather than the WScript.exe engine to execute my scripts (WScript echoes everything in a MessageBox and requires users to click OK after every echo—it gets tedious after awhile). But there’s at least one operation where I don’t want anything echoed back to me: passwords. Whenever a password is entered to log onto Windows or access protected content on Web sites (or anything else), that password is obscured. Of course it is! We don’t want any prying eyes seeing what we’re typing in to gain access to protected systems. Why is it then—considering how powerful and potentially devastating they can be—we don’t secure our scripts with passwords? Answer: In certain cases, we should.

As demonstrated last month, some administrative tasks simply can’t be performed remotely using WMI. There are times when you must actually walk over to the user’s machine and execute the script locally. Indeed, this might happen quite regularly. In these cases, there are two choices:

  1. Copy the script over every time you need it and delete it afterward (or bring it with you on a floppy disk).
  2. Secure the script by encoding it and requiring a password before execution begins.

If you choose the former, more power to you. If circumstances require choosing the latter (i.e., perhaps you’re not the only admin running the scripts, and the other admins don’t have access to your “diskette locker”), then I can help. To be reminded how to encode scripts to prevent unauthorized access (as best as possible with scripting), refer to my March through May columns. For enabling password prompts in scripts that don’t echo typed characters back to the screen, read on.

Windows has a special object created for just this purpose: ScriptPW.Password. It has only one method—GetPassword, which collects input from the user, allowing that value to be assigned to a variable.

Dim objScriptPW '... and other objects
Dim strPassword, strValidPWord

Set objScriptPW=CreateObject("ScriptPW.Password")
WScript.Echo "Enter password to run script:"

If strPassword <> strValidPWord Then WScript.Quit

'... rest of script

Note: The ScriptPW object comes with Windows XP and Windows Server 2003. However, because it’s a standard DLL, it should work fine in Windows 2000 and even Win9x. Simply copy the file “scriptpw.dll” from an XP or Windows 2003 machine to the desired target machine. Then register the .dll:

'C:\Windows\System32> regsvr32 scriptpw.dll'"

The above script demonstrates a very straightforward use for the Password object: Obscure something that’s being typed in and compare it to something else. Once validated, script execution continues. However, there are many other uses for this object.

In the October column, WMI was used to connect remotely using different user credentials. I said, “...hard wiring an admin account and password into a script is generally a very bad idea.” Well, the Password object can be used to avoid hard wiring this information into your scripts. In this case, the script wouldn’t need to be encoded to be secure and effective, because the entering and comparing of passwords occurs at runtime. Once the script terminates, all password information is destroyed. A user could look at your source code all day and not be able to figure out your password. Here’s a code snippet to illustrate this point:

Set objWMI=objLocator.ConnectServer _
("remotecomputer", "root\cimv2", strUser, strPWord)

It can also be used to obscure any information you don’t want others to see while working on their systems. Quick story: Where I previously worked, we had a user we called “Nosy Nellie.” She was the squeaky wheel that always got the grease from management. Whenever she had any system trouble (which was quite often), she would sit there and pretend not to watch as we fixed her system. Sometimes this repair involved accessing password-protected resources. She would then go directly to management and demand access to that resource “... or I simply can’t get my work done!” Next thing, we’d get a memo to give her access to this or that database, resource and so on. With this new authority, she would proceed to really screw things up. It got to the point where we’d pretend to be stumped anytime our repair to her system involved accessing a resource that she didn’t need to know about. We’d then return to her desk while she was at lunch and finish fixing her system.

The point is, there are all sorts of reasons to obscure data input. Using the Password object makes performing this task from within a script a breeze. As with most things, there are a couple of caveats. First, the Password object can only be used with CScript.exe. You’ll get an error if you try to run your script using WScript.exe. Second, the Password object doesn’t echo back “placeholder” characters like asterisks. Rather, it simply doesn’t echo anything, so type carefully.

Critical Update: There’s a new version of the Windows Script Host available. Actually, it’s not a new version but a new build revision. Still, as it’s important to stay current, I’ve included a link to download the current version. First, here’s how you determine what version you’re running:

WScript.Echo "Version: " & WScript.Version
WScript.Echo "Build: " & WScript.BuildVersion

The version should be (better be) 5.6. Chances are that your current build version is 6626 (unless you’re already running Server 2003, which has build 8515). Build 8515 (the latest build for all platforms-XP/Win2K/NT/98) can be downloaded at

About the Author

Chris Brooke, MCSE, is a contributing editor for Redmond magazine and director of enterprise technology for ComponentSource. He specializes in development, integration services and network/Internet administration. Send questions or your favorite scripts to [email protected].


comments powered by Disqus

Subscribe on YouTube