Introduction to Windows Script Technologies

Microsoft® Windows® 2000 Scripting Guide

This is a book about scripting for system administrators. If you are like many system administrators, you might be wondering why this book is targeted towards you. After all, scripting is not the sort of thing system administrators do. Everyone knows about scripting: scripting is hard; scripting is time-consuming; scripting requires you to learn all sorts of technical jargon and master a whole host of acronyms - WSH, WMI, ADSI, CDO, ADO, COM. System administrators have neither the time nor the requisite background to become script writers.

Or do they? One of the primary purposes of this book is to clear up misconceptions such as these. Is scripting hard? It can be. On the other hand, take a look at this script, which actually performs a useful system administration task:

Set objNetwork = CreateObject("WScript.Network")
objNetwork.MapNetworkDrive "X:", "\\atl-fs-01\public"

Even if you do not know the first thing about scripting and even if you are completely bewildered by line 1 of the script, you can still make an educated guess that this script must map drive X to the shared folder \\atl-fs-01\public. And that is exactly what it does. If you already understand system administration - that is, if you know what it means to map a drive and you understand the concept of shared folders and Universal Naming Convention (UNC) paths - the leap from mapping drives by using the graphical user interface (GUI) or a command-line tool to mapping drives by using a script is not very big.


  • If you are already lost - because you are not sure what is meant by scripting in the first place - think of scripting in these terms:

  • Do you ever find yourself typing the same set of commands over and over to get a certain task done? Do you ever find yourself clicking the same set of buttons in the same sequence in the same wizard just to complete some chore - and then have to repeat the same process for, say, multiple computers or multiple user accounts?

  • Scripts help eliminate some of this repetitive work. A script is a file you create that describes the steps required to complete a task. After you create the script, you can "run" that script, and it will perform all of the steps for you, saving you a great deal of time and energy. You need only create the script once, and then you can reuse it any time you need to perform that task.

Admittedly, not all scripts are as simple and intuitive as the one just shown. But if you thumb through this book, you will find that the vast majority of scripts - almost all of which carry out useful system administration tasks - are no more than 15 or 20 lines long. And with a great many of those, you can read the code and figure out what is going on regardless of your level of scripting experience.

Does scripting take too much time? It can: If you write a script that is 500 lines long (and you probably never will), the typing alone will take some time. But it is important to balance the time it takes to write a script with the time that can be saved by using that script. For example, here is a script that backs up and clears all the event logs on a computer:

strComputer = "."
Set objWMIService = GetObject("winmgmts:" _
    & "{impersonationLevel=impersonate, (Backup, Security)}!\\" _
        & strComputer & "\root\cimv2")
Set colLogFiles = objWMIService.ExecQuery _
    ("Select * from Win32_NTEventLogFile")
For Each objLogfile in colLogFiles
    strBackupLog = objLogFile.BackupEventLog _
        ("c:\scripts\" & objLogFile.LogFileName & ".evt")

Admittedly, this script is not as intuitive as the drive-mapping script. Furthermore, to write a script like this, you will need to learn a little bit about scripting in general, and about Windows Management Instrumentation (WMI) in particular. And then you still have to type it into Microsoft® Notepad, all 11 lines worth. This one might take you a little bit of time.

But think of it this way: How much time does it take you to manually back up and clear each event log on a computer. (And that assumes that you actually do this; the manual process can be so tedious and time-consuming that many system administrators simply forgo backing up and clearing event logs, even though they know this task should be done on a regular basis.) With a script, you can back up and clear event logs in a minute or two, depending on the size of those logs. And what if you take an extra half hour or so and add code that causes the script to back up and clear all the event logs on all your computers? You might have to invest a little time and energy in learning to script, but it will not be long before these scripts begin to pay for themselves.

Point conceded. But even though scripting does not have to be hard and does not have to be time-consuming, it still requires you to learn all the technical mumbo-jumbo, right? Sure, if you want to be an expert in scripting. But consider this script, which returns the names of all the services installed on a computer:

strComputer =  "."
Set objWMIService = GetObject("winmgmts:" & _
"{impersonationLevel=Impersonate}!\\" & strComputer & "\root\cimv2")
Set colItems = objWMIService.ExecQuery("Select * from Win32_Service")
For Each objItem in colItems
    Wscript.Echo objItem.Name

Under the covers, this is a fairly complicated script. Among other things, it:

  • Makes use of Automation object methods and properties.

  • Utilizes Microsoft® Visual Basic® Scripting Edition (VBScript) constructs such as the For Each loop to iterate through the elements within a collection.

  • Requires a COM (Common Object Model) moniker.

  • Uses WMI object paths, namespaces, and classes.

  • Executes a query string written in the WMI Query Language.

That is an awful lot to know and remember just to write a seven-line script. No wonder people think scripting is hard.

But the truth is, you do not have to fully understand COM and Automation to write a script like this. It does help to know about these things: As in any field, the more you know, the better off you are. But suppose what you really want is a script that returns the names of all the processes currently running on a computer instead of one that returns the names of all the installed services. Here is a script that does just that:

strComputer =  "."
Set objWMIService = GetObject("winmgmts:" & _
"{impersonationLevel=Impersonate}!\\" & strComputer & "\root\cimv2")
Set colItems = objWMIService.ExecQuery("Select * from Win32_Process")
For Each objItem in colItems
    Wscript.Echo objItem.Name

What is so special about this script? Nothing. And that is the point. Look closely at the single item in boldface (Win32_Process). This is the only part of the process script that differs from the service script. Do you know anything more about COM monikers or WMI object paths than you did a minute ago? Probably not, and yet you can still take a basic script template and modify it to return useful information. Want to know the name of the video card installed on a computer? Try this script:

strComputer =  "."
Set objWMIService = GetObject("winmgmts:" & _
"{impersonationLevel=Impersonate}!\\" & strComputer & "\root\cimv2")
Set colItems = objWMIService.ExecQuery("Select * from Win32_VideoController")
For Each objItem in colItems
    Wscript.Echo objItem.Name

Is it always this easy? No, not always. And these examples sidestep a few issues (such as, "How do I know to type in Win32_VideoController rather than, say, Win32_VideoCard?" or, "What if I want to know more than just the name of the video card?"). The point is not that you can start writing scripts without knowing anything; the point is that you can start writing scripts without knowing everything. If you want to master COM monikers and WMI object paths before you write your first script, that's fine. And if you prefer to just start writing scripts, perhaps by building on the examples in this book, that's fine too. You can always start writing and using scripts today, and then go back and learn about COM monikers and WMI object paths tomorrow.

How Did Scripting Acquire Such a Bad Reputation?

If scripting is so easy, then, how did it gain a reputation for being so hard? And if it is so valuable, why aren't more system administrators using it? After all, few system administrators knowingly turn their backs on something that will make their lives easier.

There are probably many reasons for this, but at least part of the problem dates back to the birth of the Microsoft® Windows® Script Technologies. Both VBScript and Microsoft® JScript® (the two scripting languages included with the Microsoft® Windows® operating system) began as a way to add client-side scripting to Web pages. This was great for Internet developers, but of little use to the typical system administrator. As a result, scripting came to be associated with Web page development. (Even today, many of the code samples in the official Microsoft documentation for VBScript show the code embedded in a Web page.)

Later on, Windows Script Host (WSH) was born. WSH provided a way for scripting languages and scripting technologies to be used outside Internet Explorer; in fact, WSH was aimed squarely at system administration. Nevertheless, scripting still failed to take the system administration world by storm.

Initially, this was probably due to a lack of documentation and a lack of proper positioning. It was difficult to find information about using VBScript or JScript as a tool for system administration; it was next-to-impossible to find information about technologies such as WMI or Active Directory Service Interfaces (ADSI). Even when these technologies were documented (typically in software development kits), the documentation was aimed at programmers; in fact, code samples were usually written in C++ rather than a scripting language. For example, suppose you are a typical system administrator (with substantial knowledge of Windows and minimal knowledge of programming). And suppose you looked up scripting on Microsoft's Web site and saw sample code that looked like this:

int main(int argc, char **argv)
   HRESULT hres;
   hres =  CoInitializeEx(0, COINIT_MULTITHREADED); // Initialize COM.
  if (FAILED(hres))
     cout << "Failed to initialize COM library. Error code = 0x"
          << hex << hres << endl;
     return 1;                  // Program has failed.
   hres =  CoInitializeSecurity(NULL, -1, NULL, NULL,
        NULL, EOAC_NONE, 0

Needless to say, very few system administrators saw WMI or ADSI as a tool that would be useful for them.

Today, of course, there is no dearth of scripting-related literature; a recent search of a major online bookstore with the keyword "VBScript" returned 339 titles. That is the good news. The bad news is that most of those titles take one of two approaches: Either they continue to treat scripting as a tool for Web developers, or they focus almost exclusively on VBScript and WSH. There is no doubt that VBScript and WSH are important scripting technologies, but by themselves the two do not enable you to carry out many useful system administration tasks. Of the 339 scripting books found in the search, only a handful look at scripting as a tool for system administration, and only a few of those cover the key technologies - WMI and ADSI - in any depth. A system administrator who grabs a scripting book or two at random might still fail to understand that scripting can be extremely useful in managing Windows-based computers.

How This Book Helps

So is the Microsoft® Windows® 2000 Scripting Guide simply scripting book number 340, or does it somehow differ from its predecessors? In many ways, this book represents a new approach to scripting and system administration. In fact, at least four characteristics help distinguish this book from many of the other books on the market:

  • The focus is on scripting from the point of view of system administration. This book includes many of the same chapters found in other scripting books; for example, it has a chapter devoted to VBScript. The difference is that the chapter is focused on the VBScript elements that are most useful to system administrators. System administrators need to work extensively with COM, so the VBScript chapter features detailed explanations of how to bind to and make use of COM objects within a script. System administrators have little use for calculating arctangents and cosines. Hence, these subjects are not covered at all, even though it is possible to make these calculations using VBScript.

  • This book is task-centered rather than script-centered. In some respects, the scripts included in this book are an afterthought. Sometimes a book author will create a bunch of interesting scripts and then compose the text around those items. This book takes a very different approach: Instead of starting with scripts, the authors identified key tasks that system administrators must do on a routine basis. Only after those tasks were identified and categorized did they see whether the tasks could even be scripted. In that sense, this is not so much a book about scripting as it is a book about efficiently managing Windows-based computers. As it happens, the suggested ways to carry out these tasks all involve scripts. But the scripts could easily be removed from the book and replaced with command-line tool or GUI equivalents, and the book would still have value.

  • This book combines tutorial elements with practical elements. Some books try to teach you scripting; thus they focus on conceptual notions and, at best, pay lip service to practical concerns. Others take the opposite approach. In those cases, the focus is on the practical: The books present a host of useful scripts, but make little effort to help you understand how the scripts work and how you might modify them. This book tries to combine the best of both worlds; for example, any time a useful system administration script is presented, the script is accompanied by a step-by-step explanation of how the script works and how it might be adapted to fit your individual needs.

  • This book recognizes that, the larger the organization, the more pressing the need to automate procedures. If you are the system administrator for an organization that has a single computer, you might still find the scripts in this book useful. To be honest, though, you would probably find it faster and easier to manage your lone computer by using the GUI. If you have 100 computers, however, or 1,000 computers, the value of scripts and scripting suddenly skyrockets. In recognition of this fact, the book includes an entire chapter - "Creating Enterprise Scripts" - that discusses how the sample scripts in this book can be modified for use in organizations with many computers.

How Do You Know if This Book is for You?

Officially, this book was written for "system administrators in medium to large organizations who want to use scripting as a means to manage their Windows-based computers." That group (amorphous as it might be) will likely make up the bulk of the readership simply because 1) the book revolves around scripting system-administration tasks, and 2) system administrators in medium to large organizations are the people most likely to need to use scripts.

However, the book should be useful to anyone interested in learning how to script. The techniques discussed throughout the book, while focused on medium to large organizations, are likely to prove useful in small organizations as well. These techniques are typically used to carry out system administration tasks, but many of them can be adapted by application programmers or Web developers. The book does not discuss scripting as a method of managing Microsoft Exchange Server; however, Microsoft Exchange Server can be managed using WMI. Because of this, Exchange administrators might be interested not only in the chapter "WMI Scripting Primer" but also in the chapter "VBScript Primer," which discusses generic techniques for working with Automation objects.

This book also tries to provide information that will be useful to people with varying levels of scripting knowledge and experience. No scripting background is assumed, and if you read the book from cover to cover, you will start with the fundamental principles of scripting and gradually work your way through more complicated scenarios. But what if you already know VBScript but do not know much about ADSI? Skip directly to "ADSI Scripting Primer." What if you understand the basic principles of WMI but need to know how to create and terminate processes using WMI? Go right to the "Processes" chapter.

There is something for everyone in this book: No knowledge or experience is required, but that does not mean that the book does not occasionally discuss a task or technique that might be a bit more advanced. And what if you have already mastered every scripting technique ever created? In that case, the book will likely be useful as a reference tool; after all, even those who know everything about WMI have rarely taken the time to memorize all the class names, methods, and properties. For those people, the tables in the task-based chapters might well make up for the fact that some of the explanations are aimed at beginners instead of experts.

What Is in This Book

The Windows 2000 Scripting Guide is divided into three parts:

  • Conceptual chapters. The conceptual chapters offer comprehensive primers on the primary scripting technologies from Microsoft, including Windows Script Host (WSH), VBScript, WMI, ADSI, and the Script Runtime library. These are tutorial-type chapters, all written from the standpoint of a system administrator, and all written under the assumption that the reader has little, if any, scripting experience.

  • Task-based chapters. For the task-based chapters, core areas of system administration were identified, including such things as managing services, managing printers, and managing event logs. Within each of these core areas, 25 or so common tasks were also identified, such as starting and stopping services, changing service account passwords, and identifying the services running on a computer. Each task includes 1) a brief explanation of the task and why it is important, 2) a sample script that performs the task, and 3) a step-by-step explanation of how the script works and how you might modify it to fit your own needs.

  • Enterprise chapters. The enterprise chapters cover a range of topics, including guidelines for setting up a scripting infrastructure and best practices to consider when writing scripts as part of an administrative team. These chapters also describe different ways to enterprise-enable a script, for example, writing a script that performs an action on all your domain controllers or on all your user accounts, or a script that accepts arguments from a text file or a database.

You do not have to begin on page 1 and read the entire book from start to finish. The book is designed so that you can skip around and read only the content that interests you. Are you less interested in a conceptual understanding of WMI than you are in learning how to manage services by using scripts? Then start off by reading the "Services" chapter; there is no reason to read all of the preceding chapters. If you are new to scripting, you might find it useful to read about VBScript and WMI first, but this is not a requirement. Consider this book to be a smorgasbord of scripting techniques: You are free to pick and choose as you please.

In fact, if you are as interested in using scripts as you are in writing them, you might want to start with the task-based chapters. Read a chapter, copy and run the scripts, and see what happens. If you then want to better understand how the scripts work or would like to modify them so that they better fit your individual needs, go back and read up on the conceptual information.

About the Scripts Used in This Book

Most of the people who saw draft copies of this book expressed surprise - and gratitude - that the scripts were so short; many were used to scripting books in which a sample script might cover two or three pages, and had no idea that scripting could be so simple.

However, some people were shocked by the fact that the scripts were so bare-boned. For example, very few of the scripts in the book include error handling; why would you write a production-level system administration script without including things such as error handling?

The answer is simple: The scripts in this book were never intended to be production-level system administration scripts. Instead, they are included for educational purposes, to teach various scripting techniques and technologies. Most of them can be used as-is to carry out useful system administration tasks, but that is just a happy coincidence; this book and the script samples are designed to teach you how to write scripts to help you manage your computing infrastructure. They were never intended to be a management solution in and of themselves.

Finding All the Pieces

Keeping the scripts simple does not mean that concepts such as error handling are ignored; script writers definitely have a need for error handling, they have a need for parsing command-line arguments, and they have a need for creating scripts that run against more than one computer (for example, against all their Dynamic Host Configuration Protocol [DHCP] servers or against all the computers with accounts in a particular Active Directory container). Because of that, these techniques are covered in considerable detail in "Creating Enterprise Scripts" and "Scripting Guidelines" in this book.

In other words, although this book does not include any 500-line scripts that make use of every possible scripting technique, all of these scripting techniques are demonstrated somewhere in the book. If you wanted to, you could easily take a number of the small sample scripts and stitch them together to create a 500-line production-level super script.

By leaving out such things as error handling, the scripts were kept as short as possible, and the focus remained on the task at hand. Consider the first script shown in this chapter, the one designed to map a network drive on the local computer:

Set objNetwork = CreateObject("WScript.Network")
objNetwork.MapNetworkDrive "X:", "\\atl-fs-01\public"

This script is about as simple as it can be, which is exactly the point: You do not have to study it very long before you say to yourself, "Oh, so that's how I map network drives using a script." Admittedly, in a production environment you might want to modify the script so that the user can specify any drive letter and any shared folder. This can be done, but you will need code for parsing command-line arguments. Likewise, the sample script will fail if drive X is already mapped to a shared folder. This can be accounted for too, but now you need code to check which drive letters are in use and then to prompt the user to enter a new drive letter. You might also need code that checks to make sure that the shared folder \\atl-fs-01\public actually exists. To account for all these activities would turn a 2-line script into a 22-line script; even worse, the whole idea of showing the script in the first place - demonstrating how to map network drives - would then be buried somewhere in the middle of a relatively large script.

Keeping the scripts short and simple also drives home the point that scripts do not have to be complicated to be useful. If you are creating a script that will be used by many different people throughout your organization, it might be advisable to include argument parsing and error handling. But what if this is a script that only you will use? In this case, you may not need these features. You should never feel compelled to do something in a script just because someone else did it that way. The only thing that matters is that the script carries out its appointed task.

A Note Regarding VBScript

All the scripts in this book were written using VBScript. The decision to use VBScript rather than another scripting language or combination of languages was based on three factors:

  • With the possible exception of Perl, VBScript is the most popular language used for writing system administration scripts. It made sense to choose a language that many people are at least somewhat familiar with.

  • Unlike Perl, VBScript (along with Jscript) is automatically installed on all Windows 2000-based computers. Thus there is nothing to buy and nothing to install.

  • VBScript is easier to learn than Jscript. As a sort of added bonus, VBScript is very similar to Visual Basic, a programming language that many system administrators have a nodding acquaintance with.

In other words, VBScript is easy to use, requires no additional purchase, download, or installation, and has a large user base. This makes it ideal for introducing people to system administration scripting.

To be honest, though, in many ways the scripting language is irrelevant. By itself, VBScript offers very little support for system administration; VBScript is most useful when it works with WSH, WMI, ADSI, and other scripting technologies that offer extensive support for system administration. In this respect, it is similar to other scripting languages. The vast majority of the scripts in this book rely on WMI or ADSI; the scripting language is almost incidental. Do you prefer working in JScript or ActiveState ActivePerl? Great; all you have to do is learn how to connect to WMI or ADSI using those languages and then take it from there.

For example, here is a WMI script that retrieves and then displays the name of the BIOS installed on the computer. This script is written in VBScript.

strComputer = "."
Set objWMIService = GetObject("winmgmts:\\ " _
    & strComputer & "\root\cimv2")
Set colItems = objWMIService.ExecQuery _
    ("Select * from Win32_BIOS")
For Each objItem in colItems
    Wscript.Echo objItem.Name

Here is the same script, written in JScript. As you can see, the syntax and language conventions are different, but the key elements (shown in boldface) - connecting to WMI, retrieving information from the Win32_BIOS class, echoing the value of the BIOS name - are almost identical. In that respect, the language is largely a matter of individual choice; you can use WMI and VBScript to retrieve BIOS information, or you can use WMI and JScript to retrieve BIOS information.

var strComputer = ".";
var objWMIService = GetObject("winmgmts:\\\\ " +
    strComputer + "\\root\\cimv2");
var colItems = objWMIService.ExecQuery
    ("Select * from Win32_BIOS");
var e = new Enumerator(colItems);
for (;!e.atEnd();e.moveNext()) { var objItem = e.item();


  • In reality, there are some minor differences among scripting languages that affect what you can and cannot do with system administration scripts. However, these differences are not important to this discussion.

System Requirements

This book is targeted toward computers running any Microsoft® Windows® 2000 operating system (including Microsoft® Windows 2000 Professional, and Microsoft® Windows 2000 Server, Windows® 2000 Advanced Server, and Windows® 2000 Datacenter Server). In addition to having Windows 2000 installed, these computers should be running Windows Script Host version 5.6, which was released after Windows 2000. Some of the scripts in the book rely on features found only in version 5.6. For more information about WSH version 5.6, see "WSH Primer" in this book.


  • If you do not have WSH 5.6, an installation file for Windows 2000 is included on the compact disc that accompanies this book. If your computer is running an operating system other than Windows 2000, see the Windows Script Technologies link on the Web Resources page at and click the Microsoft Windows Script 5.6 download link. If you are not sure which version of WSH you have on your computer, see "WSH Primer" in this book for information about determining the WSH version number.

If you are working with multiple operating systems, particularly Windows XP, it is also recommended that you install Windows 2000 Service Pack 2. Without this service pack, scripts running on a Windows 2000-based computer are unable to retrieve information from a Windows XP-based computer (although the Windows XP computers can retrieve information from the Windows 2000 computers).

In addition, most of these scripts require you to be logged on with administrative credentials; this is a requirement for most WMI and ADSI operations. If you want to run a script against a remote computer, you need to be an administrator both on your computer and on that local computer.

Beyond that, no fancy scripting tools, editors, or integrated development environments (IDEs) are required. As long as you have Notepad installed, you are ready to start writing scripts.