Tales from the Script - September 2003

By The Scripting Guys

Scripting Environment – Transform Your Workstation into a Scripting Dynamo


Maybe you're one of those people who read our previous Tales from the Script column shamelessly hyping the Windows 2000 Scripting Guide and, in a fit of irrational exuberance, ran out and bought the thing. And maybe you're so disciplined that you actually read and performed the stuff on upgrading to Windows Script Host 5.6 and setting up Cscript.exe as your default script host, and all those other details that allow you to optimize your scripting environment.

If this describes you, we bet you used to be one of those kids who knew the name of the largest city in Estonia and memorized pi to 10 decimal places, the kind of kid who raised your hand high, replied confidently to the teacher, and later got pounded in the parking lot after school for wrecking the curve.

If, on the other hand, you're like the Scripting Guys, you probably leafed impatiently through the book; then, noticing an alluring script example, you sauntered over to your box, typed the script into Notepad with a flourish and let 'er rip. And finally, after clicking OK on 14 message boxes and trying to decipher a succession of cryptic "Access denied" errors, you scratched your head, threw the book behind the rack-mounts, and headed out to salve your battered ego with a quadruple skinny caramel macchiato with a shot of Irish Cream syrup and a spoonful of foam (this is Seattle-ese for "coffee").

If that happened to you, don’t feel bad. Part of the discreet charm of Windows scripting is that making it work for the first time is not a slam dunk. It takes a bit of forethought to set up your administrative workstation so that you can run scripts effectively and take full advantage of the power of -- take a deep breath now -- Visual Basic Scripting Edition (VBScript), Windows Script Host (WSH), Windows Management Instrumentation (WMI), and Active Directory Service Interfaces (ADSI). But it's worth the trouble, and you might even learn some scripting in the bargain.

Note: How do we know it’s worth the trouble to do this? Well, for one thing, we get scores of letters each month that say things like, “I tried running your script that shows how to use the Exec method, but I got an error saying this method wasn’t supported,” or, “I tried running your WMI script on my Windows 98 laptop, and got an error message saying the object couldn’t be created.” Knowing exactly which scripting technologies you do and do not have installed on a computer will help you understand why certain scripts run on some computers but not on others.

If your first steps into Windows scripting included a pratfall or two, we feel your pain and hope this column will help relieve it. We even wrote a script to help you figure it all out. We hope this will remove some of the stumbling blocks so that you can focus on harnessing all those acronyms to automate the soul-numbing drudgery that used to bring on -- uh, what do you call it when you hate your job so much you get claustrophobia on the way to work? Oh, yeah -- carpool tunnel syndrome.

On This Page

Update your Scripting Technologies
Log on with Administrative Privileges
Change the Default Script Host to Cscript
Use a Script to Audit Your Scripting Environment
Stock up on Scripting Resources
Microsoft System Administration Scripting Resources
Third-Party System Administration Scripting Sites
Technology Downloads

Update your Scripting Technologies

To take full advantage of the power of scripting, your workstation should be running the most current releases of VBScript, WSH, WMI and ADSI available for your version of Windows. Windows Server 2003 provides everything you need. Windows XP includes an earlier build of Windows Script 5.6 (which includes VBScript and Jscript) than the one on Windows Server 2003; the functionality is essentially the same between the two versions, but the latest release includes some minor bug fixes. Windows XP also includes the same version of ADSI as that found on Windows Server 2003, and a similar version of WMI (although there are some additional classes in Windows Server 2003 that you won’t find on Windows XP).

With any version of Windows 2000, which includes WSH 2.0, you can run most of the script examples on the TechNet Script Center and in the Windows 2000 Scripting Guide. But some of those scripts do require WSH 5.6, so you may want to upgrade to it.

Don’t believe us? Here’s a script that does nothing more than change the current directory. This script will work great, as long as you have WSH 5.6 installed. If you don’t, it won’t work at all:

Set objShell = WScript.CreateObject("WScript.Shell")
Wscript.Echo "Initial Working Directory:"
Wscript.Echo objShell.CurrentDirectory
objShell.CurrentDirectory = "C:\"
Wscript.Echo "Working Directory After Change:"
Wscript.Echo objShell.CurrentDirectory

By downloading the latest version of Windows Script 5.6 from Microsoft Developers Network (MSDN) — click the link in Table 1 — and installing it on machines running Windows XP and Windows 2000, you can provide a uniform and up-to-date WSH environment across the three most recent Windows operating systems. Table 1 also provides links to downloads of WMI and ADSI upgrades.

Note: Of course, your response to this is probably: “Cool. Now how do I get a uniform and up-to-date WMI and ADSI environment across the three most recent Windows operating systems?” Well, to be perfectly honest, you can’t. ADSI is largely equivalent across the board, but there are a few differences. For example, using ADSI to script security descriptors in Windows XP and Windows Server 2003 is easy. Using ADSI to script security descriptors in other versions of Windows is possible, but downright scary. Unfortunately, though, there is currently no way to upgrade the version of ADSI found on your Windows 2000 computer to the same version found on Windows Server 2003. Likewise, the WMI classes found on, say, Windows 98 represents a very small subset of the classes found on Windows XP. Again, there is currently no way to upgrade your Windows 98 WMI to match the Windows XP WMI.

Incidentally, we recognize how frustrating this can be to people who have a mixture of computers, some running Windows NT 4.0, some running Windows 2000, others running Windows XP. How in the world can you know whether a WMI script will work on any (let alone all) of those platforms? Well, don’t lose any sleep over this; instead, stay tuned to the Script Center, and keep your eyeballs peeled for the upcoming Comparomatic utility, which will compare the cimV2 WMI classes on Windows 98, Windows NT 4.0, Windows 2000, Windows XP, and Windows Server 2003.

Table 1 Scripting technologies / operating system matrix

Operating System

Windows Script included


WMI included


ADSI included


Windows Server 2003





Windows XP Professional

download upgrade





Windows 2000 (Professional & Server)

2.0 (also known as WSH 5.1)

download upgrade



2.5 (also known as ADSI 5.0.2195)

2.5 (also known as ADSI 5.0.2195)

Windows Millennium



download upgrade



Not installed

Active Directory Client Extensions (aka DSClient - requires IE 4.01 or later)

download upgrade (also available on any Windows 2000 Server family CD-ROM.)

Windows NT 4.0 (Workstation & Server)

Not installed

(Version 1.0 and higher versions were available through Service Packs, IE and IIS)

5.6.8515 (must have Internet Explorer 3.02 or 4.0 installed)

download upgrade

Not installed

CORE 1.5

download upgrade (requires IE 5.0 or later and Service Pack 4 or later)

Not installed

Active Directory Client Extensions (aka DSClient - requires IE 4.01 or later) - available on any Windows 2000 Server family CD-ROM.

download upgrade

Windows 98

1.0 (Optional system component, not installed by default)


download upgrade

Not installed

CORE 1.5

download upgrade (requires IE 5.0 or later)

Not installed

Active Directory Client Extensions (aka DSClient - requires IE 4.01 or later)

download upgrade (also available on any Windows 2000 Server family CD-ROM.)

Note: Although upgrades for WMI and ADSI are still available for Windows 95, no Windows Script upgrade for it is currently available and not much information is available on scripting it, so we have not included it in this table.

What’s that you say? You just got hired, and you don’t know what versions of WSH, WMI, and ADSI have been installed on your computer? You’re wondering, “Isn’t there a way for you Scripting Guys to tell me which versions have been installed on my computer?” Well, of course there is; in fact, we’ve provided you with a script that will do this very thing. And if you can hang on for a minute or two, we’ll even provide you with some insight into how that script works.

Log on with Administrative Privileges

Let’s assume you’ve got your workstation set up with the latest and greatest scripting technologies. That’s a good first step, and a great way to impress your friends. (“Wow, you have WSH 5.6?!? Man, you are so cool!”) But while showing off to the neighbors is always neat, half the fun of owning a Porsche is actually driving it. And half the fun of having WSH 5.6 is actually using it to run scripts.

And that’s where some people get into trouble. We hate to disappoint all you budding hackers and crackers, but scripts don’t provide a way for you to get around security: if you don’t have the right to do something (say, install a printer) using the GUI, then you won’t have the right to do something using a script. Scripts respect Windows security, and that can be a problem: we get lots of questions from people who can’t get a script to run, and it often times turns out that the script is trying to do something those people don’t have the right to do. Because of that, it’s important to understand a little about the security context needed to run your scripts.

To run scripts locally or remotely, you must first be logged onto your workstation as a member of the local Administrators group. At a minimum, To run a WMI script on a remote computer:

  • There must be an account on the remote computer with the same username and password as the local account under which the script is run.

  • This remote account must also be a member of its local Administrators group.

On Windows XP and Windows Server 2003, WMI does not allow this account to have a blank password. Although WMI on Windows 2000 and earlier Windows operating systems does not enforce this requirement, a blank password on an administrative account would create serious security vulnerabilities, so use a strong password on all platforms.

To run a script on remote computers that are members of a domain, the best approach is to use domain-based credentials.

If you need to run a script on other machines under a different account, you can use the ConnectServer method of WMI's SWbemLocator object to specify a different username and password. However, ConnectServer sends the password over the wire as plain text by default, another obvious security risk.

If you want to run scripts remotely on machines running Windows NT 4.0 with an earlier version of WMI than 1.5, you must use different levels of impersonation and authentication from the defaults. The WMI SDK's topic on "Connecting to WMI on a Remote Computer" at http://msdn.microsoft.com/en-us/library/aa389290(VS.85).aspx explains the details. Before running WMI scripts on Windows 98 and 95 you must perform special setup procedures to enable those operating systems to accept remote DCOM connections.

If you are using ADSI, you need domain-based credentials with sufficient access to perform the tasks in a script on all targeted machines. These will depend on the particular security policies of your Active Directory implementation. For example, if you have the right to reset user passwords, then you can run a script that will reset user passwords. If you don’t have that right, then there’s no point even trying to run a reset passwords script; it’s not going to work.

The easiest way to deal with this, of course, is to simply log on as a domain administrator. However, logging in as a domain administrator may also raise security issues. Depending on security policies on your network, it may make more sense to log on as a user without administrative privileges and use the Runas command to run scripts using alternative credentials that have administrative privileges.

Change the Default Script Host to Cscript

We recommend that you set the WSH options to run scripts at the command prompt by default. The default WSH script host is Wscript.exe, which runs scripts in the GUI -- this means that all input and output takes place in popup message boxes, which require user intervention to click OK before the script can continue with its work.

Cscript.exe, the command-line script host, is usually more suitable for system administration tasks, which often need to report a lot of information (and thus could result in you having to click a lot of message boxes). To make Cscript.exe the default script host, open a command window and, at the prompt, type:

cscript //h:cscript //nologo //s

This command-line:

  • sets Cscript, the console-based script host, as your default

  • suppresses the logo that appears by default, and

  • saves these options for the current user.

If you do not run this command-line, you must type "cscript" before the filename of a script to run it in a command window, for example:

cscript anyoldscript.vbs

For a full list of WSH options that can be set at the command prompt, type:

cscript /?

Use a Script to Audit Your Scripting Environment

Because we've just hit you with a boxcar load of new scripting technologies and because we believe in practicing what we preach, or "eating our own dog food," as we say at Microsoft, we've provided a script (to run on your local computer) to help sort things out. It tells you what operating system is installed on your computer and whether the installed versions of WSH, WMI and ADSI are the most up-to-date ones for that OS. If they are not all current, then see the "Technology Downloads" section below for URLs from which you can download the most recent versions.

Scriptenv.vbs, the companion script for this column, uses several approaches to dig out the different kinds of data it displays. It creates a separate function to perform each task, a convenient way provided by VBScript (and nearly all scripting languages) to break down a complicated script into manageable pieces.

Identifying the Default Script Host

For starters, the GetWshHost() function determines which script host is the current default, Wscript.exe or Cscript.exe. This function parses the string returned by Wscript's FullName property, which returns the full path to the script host executable file something like this:


Using VBScript's Right() and LCase() functions, it changes the whole string to lower case (to eliminate case variations from the comparison) and extracts the rightmost 11 characters from the end of the string, which happen to be the filename of the default script host.

The following stripped-down code forms the core of the function (minus the LCase() function, which converts the name to all lowercase letters):

strFullName = WScript.FullName
strWshHost = Right(strFullName, 11)
WScript.Echo "Default script host: " & strWshHost

The ChangeToCscript subroutine then checks to see if the default script host is Wscript. If it is, the sub then does something seemingly crazy, but actually useful. It opens a new window and starts a new instance of itself (Scriptenv.vbs), this time running under Cscript, and then terminates the original version of itself (the change from Wscript will not take effect until the first instance closes). Why? Well, running the script with Wscript would mean having to click OK to around 10 pop-up windows to read the information. (And, of course, each time you clicked a message box, that data would then disappear from view.) This way, the script forces itself to run under CScript, meaning you won't be assaulted by a swarm of message boxes and, when the script is finished, all the data will still be displayed in the command window. Here's what the code looks like:

If strWshHost = "wscript.exe" Then
  Set objShell = CreateObject("WScript.Shell")
  objShell.Run _
   "%comspec% /k ""cscript //h:cscript&&cscript scriptenv.vbs""", _
  If Err.Number <> 0 Then
    WScript.Echo "Error 0x" & hex(Err.Number) & " occurred. " & _
     Err.Description & ". " & VbCrLf & _
     "Could not temporarily change the default script host to Cscript."
  End If
End If

Note: No matter which script host you are using, the object you will use in your scripts is called WScript.

Identifying the Version of Windows Installed on a Computer

If you want to find out what operating system and version are running on a computer, you can open up the System Properties dialog box for My Computer and find them right at the top of the General tab. But what if you want to use this information in a script?

Note: Why would you want to find out what operating system and version are running on a computer? Well, for one thing, you can install WSH 5.6 on a Windows 98 computer and you can also install it on a Windows 2000 computer. However, the setup file required to install WSH 5.6 on a Windows 98 computer is not the same as the one required to install WSH 5.6 on a Windows 2000 machine. Before you can do all your fancy upgrading, you need to know which operating system you’re dealing with.

WMI offers a class, Win32_OperatingSystem, that lets you retrieve the name, version and service pack of the your operating system, along with over 50 other properties including the install date, language and serial number.

To simply display the operating system name and version on the screen, you could use the following code:

Set objWMIService = GetObject("winmgmts:" & _
Set colOperatingSystems = objWMIService.ExecQuery _
    ("SELECT * FROM Win32_OperatingSystem")
For Each objOperatingSystem in colOperatingSystems
    Wscript.Echo "OS Name: " & objOperatingSystem.Caption
    Wscript.Echo "Version: " & objOperatingSystem.Version

When you run this script under CScript, you’ll get back information similar to this:

OS Name: Microsoft Windows XP Professional
Version: 5.1.2600

This code example calls GetObject to bind to WMI's root\cimv2 namespace, where the Win32_OperatingSystem class is located, uses the ExecQuery method with a WMI Query Language (WQL) query (similar to SQL) as the parameter to return information on all operating systems on the computer, and then echoes the name and version number to the display.

Scriptenv.vbs wraps similar code into a function called GetOSVer(), which returns a unique integer representing the operating system version to the main body of the script.

Win32_OperatingSystem, however, does not provide a unique number for older operating system versions. So Scriptenv.vbs uses two of its properties, OSType and Version, and nested Select Case statements to produce an integer, intOSVer, that's used later in the script. Select Case is VBScript's way of making a decision based on more numerous criteria than you can easily handle with If … Then … Else If … Else … End If. A pared down version of this code is shown in the following example.

Set objWMIService = GetObject("winmgmts:" & _
Set colOperatingSystems = objWMIService.ExecQuery _
  ("Select * from Win32_OperatingSystem")
For Each objOperatingSystem In colOperatingSystems
    intOSType = objOperatingSystem.OSType
    strOSVer = Left(objOperatingSystem.Version, 3)
Select Case intOSType
    Case 16 'Windows 95
        intOSVer = 1
    Case 17 'Windows 98
        intOSVer = 2
    Case 18
        Select Case strOSVer
            Case 4.0
                intOSVer = 4 'Windows NT 4.0
            Case 5.0
                intOSVer = 5 'Windows 2000
            Case 5.1
                intOSVer = 6 'Windows XP
            Case 5.2
                intOSVer = 7 'Windows Server 2003
            Case Else
                intOSVer = 0 'Older or newer version
            End Select
    Case Else
        intOSVer = 0 'Older or newer version
End Select

Note: Win32_OperatingSystem.OSType and .Version do not provide a value for Windows Millennium.

Next, the script gets the versions of WSH, WMI and ADSI to compare against the most recent versions for the particular OS.

Identifying the Versions of WSH, WMI, and ADSI Installed on a Computer

The GetWSHVer function takes an integer with the version of the operating system and a string with the name of the default script host (now Cscript) as parameters. It uses built-in properties of WSH to display the default script host, the path to it, and the WSH Version and BuildVersion properties. It then checks these properties against the operating system to determine if the version of WSH is the most up-to-date for that OS, returning the Boolean value of True if it is and False if it is not. When you strip away error handling and comparison code, the heart of this function looks like this:

WScript.Echo _
  "WSH Path:                " & WScript.FullName & VbCrLf & _
  "WSH Version:             " & WScript.Version & VbCrLf & _
  "WSH Build Version:       " & WScript.BuildVersion & VbCrLf

To check the WMI version, the GetWMIVer function uses a similar approach to that of GetWSHVer. It takes only one parameter, though: an integer representing the OS version. GetWMIVer uses the Win32_WMISetting class to obtain a collection of the WMI settings on the machine (there will be only one). It displays the build version and the default WMI scripting namespace. Then it uses an If … Then … Else .. End If statement with a Boolean logic tree comparing the class's BuildVersion property with the OS version integer to decide whether the version is most current. Depending on the result, it returns True or False.

A Scripting Guy Tip

Sure, in all these cases we could have just reported back the version number and then left it up to you to read through the returned data and determine whether or not you had the latest and the greatest scripting technology installed. But why not let the script do that work for you? For example, suppose you’re going to install a new application on all your computers, or at least on all those computers that have 256 MB or more of RAM. Instead of just getting back a bunch of RAM values (128, 256, 128, 512, 1024, 256), why not have the script report something like “Sufficient memory” if RAM is 256 or greater or “Insufficient memory” if RAM is less than 256? This requires a little extra coding on your part, but a lot less analysis later on. (Particularly useful if you write the script, but someone else will be running it.)

You can get the basic WMI information with the following code snippet:

Set objWMIService = GetObject _
Set colWMISettings = objWMIService.ExecQuery _
 ("Select * from Win32_WMISetting")
For Each objWMISetting In colWMISettings
  Wscript.Echo _
   "WMI Build Version:           " & _
   objWMISetting.BuildVersion & vbCrLf & _
   "Default scripting namespace: " & _

The function that checks the ADSI version, GetADSIVer, has to perform more contortions than the previous ones to get its information. It uses the built in WshShell object to read two registry entries and deduces the ADSI version from the results. Then it uses the ADSI namespace provider to obtain a list of installed ADSI providers, the modules that let you access the namespaces of different kinds of protocols and directory services such as LDAP and NDS. Finally, it uses a Boolean logic tree similar to that used by GetWMIVer to compare the ADSI version against the OS version, and returns True or False. Here's the basic code:

Set objShell = CreateObject("WScript.Shell")
strAdsiVer = _
objShell.RegRead("HKLM\SOFTWARE\Microsoft\Active Setup\Installed " & _
If strAdsiVer = vbEmpty Then
    strAdsiVer = _
    If strAdsiVer = vbEmpty Then
        strAdsiVer = "ADSI is not installed."
        strAdsiVer = "2.0"
    End If
ElseIf Left(strAdsiVer, 3) = "5,0" Then
   If intOSVer = 5 Then
       strAdsiVer = "5.0.2195"
   ElseIf intOSVer = 6 Then
       strAdsiVer = "5.1.2600"
   ElseIf intOSVer = 7 Then
       strAdsiVer = "5.2.3790"
   End If
End If
WScript.Echo "ADSI Version: " & strAdsiVer & VbCrLf
If strAdsiVer <> "ADSI is not installed." Then
    Set colProvider = GetObject("ADs:")
    Wscript.Echo "ADSI Providers" & VbCrLf & _
    For Each objProvider In colProvider
        Wscript.Echo objProvider.Name
End If

Finally, the ListUpToDate subroutine takes the Boolean values returned by GetWSHVer, GetWMIVer and GetADSIVer as parameters and puts each through a nested If … Then … Else loop. Each loop either informs you that the version of that technology is up-to-date for your operating system or tells you which more recent version you should install.

Stock up on Scripting Resources

You're almost ready to rock-and-roll, but there are a few more steps that will make your early forays into system administration scripting more productive. Certain resources are useful enough that they (or a prominent link to their URL) are worth having on your workstation. "Microsoft System Administration Scripting Resources" and "Third-Party System Administration Scripting Sites" below list some of these.

Microsoft System Administration Scripting Resources


One-stop shopping for Windows system administration scripting


Windows 2000 Scripting Guide

TechNet - full online content


MS Press site - how to purchase book



Instructional aid that helps you write WMI scripts


A Scripting Guy Advertisement

Coming soon to a Script Center near you: the all-new, all-cool Scriptomatic 2.0!


Instructional aid that helps you write ADSI scripts


MSDN Scripting Clinic

More advanced scripting topics.


Windows Script home page on MSDN

Documentation on VBScript, Jscript, WSH, Script Runtime and other scripting components.



Online on MSDN


Download (part of Platform SDK)


Choose the "WMI SDK" link under "Windows SDK" in the left column.

WMI Tools

WMI CIM Studio, WMI Object Browser, WMI Event Registration Tool and WMI Event Viewer



Online on MSDN



News server: news.microsoft.com

Third-Party System Administration Scripting Sites

Desktop Engineer's Junk Drawer

Windows Scripting Solutions Journal

Technology Downloads

Windows Script 5.6 Downloads

Includes VBScript 5.6, JScript 5.6, Windows Script Host 5.6, and Windows Script Runtime 5.6.


For Windows 2000 and XP

This download includes a newer build (8515) of Windows Script 5.6 than that shipped with Windows XP.

http://www.microsoft.com/downloads/details.aspx? FamilyId=C717D943-7E4B-4622-86EB-95A22B832CAA&displaylang=en

For Windows 98, Millennium and NT 4.0.

http://www.microsoft.com/downloads/details.aspx? FamilyId=0A8A18F6-249C-4A72-BFCF-FC6AF26DC390&displaylang=en

Documentation for all Windows Script 5.6 components

http://www.microsoft.com/downloads/details.aspx? FamilyId=01592C48-207D-4BE1-8A76-1C4099D7BBB9&displaylang=en

WMI CORE 1.5 Download

For Windows NT 4.0

http://www.microsoft.com/downloads/details.aspx? FamilyID=c174cfb1-ef67-471d-9277-4c2b1014a31e&DisplayLang=en

For Windows 95 and 98

http://www.microsoft.com/downloads/details.aspx? FamilyID=afe41f46-e213-4cbf-9c5b-fbf236e0e875&DisplayLang=en

Active Directory Client Extensions for Windows NT 4.0

These client extensions can also be installed on Windows 95 and 98.


For a list and additional information on all Tales from the Script columns, click here.