Chapter 1. Introduction

The Windows Server operating system (OS) has come a long way in the past ten years. In the early days of Windows NT, system crashes were common annoyances that administrators had to learn to deal with. There were few tools to manage the OS, and the ones that were available, which mainly consisted of the graphical variety, were limited in functionality and didn’t scale well. Also at that time, Microsoft was not yet serious about providing intuitive scripting interfaces, which would enable administrators to automate repetitive tasks. The result was that administrators were forced to do a lot with a little.

The tides changed dramatically with the release of Windows 2000, which turned out to be much more scalable and manageable. Microsoft began to improve in the management areas it had previously lacked by adding more tools and introducing several new scripting interfaces that were robust and easy to use.

But in many ways, Windows 2000 felt like a first version release of a major piece of software, which it was. Windows 2000 did a lot of things right, but there were still major gaps in terms of manageability. Windows Server 2003, Microsoft’s latest server OS, is a much more mature platform. It isn’t as big of an upgrade as Windows NT to Windows 2000, but Microsoft smoothed out a lot of the rough edges that were present in Windows 2000.

So what are we left with? If I had to sum it up into a single sentence: Windows Server 2003, and Windows 2000 to a lesser degree, is a sophisticated OS that has been built from the ground up to be both scalable and manageable, and supports all of the major information technology services you need to run a business or organization. The result is that administrators now have to do a lot with a lot.

You can’t get all of this capability wrapped up into a single OS without some trade-offs. To be able to take full advantage of Windows 2000 Server or Windows Server 2003, you have to know lots of gory technical details. You have to know how to navigate through the hundreds of dialogs and menus. You have to know which command-line utilities are available to accomplish various specific tasks, where to find them, and which options you should use for each utility. You have to know what scripting interfaces are available to automate tasks so you can keep your support costs low. We take it for granted, but that is a lot for any one person to know. I’ve been doing Windows system administration for eight years and I still have a difficult time recalling the correct tool or command or scripting interface for certain tasks.

And that is the purpose of this book: to be a comprehensive reference so I don’t have to waste time (and brain cells) trying to remember that Windows Management Instrumentation (WMI) doesn’t have any scripting interfaces for creating or modifying page files; or how to use Group Policy to run a task on a group of workstations; or how to find all of the files that are currently open on a system. This book covers general system administration duties, but it also covers a great deal more. There are dedicated chapters on many of the major services you’ll end up running at one point including IIS, DNS, DHCP, Active Directory, and Exchange.

Approach to the Book

If you are familiar with the O’Reilly Cookbook format that you can find in other popular books such as Active Directory Cookbook, Perl Cookbook, or DNS and BIND Cookbook, then the layout of this book will not be new to you. It is composed of 17 chapters, each containing 10-30 recipes that describe how to perform a particular task. Most recipes contain four sections: Problem, Solution, Discussion, and See Also. The Problem section briefly describes the task the recipe addresses and when you might need to use it. The Solution section contains step-by-step instructions on how to accomplish the task. Depending on the task, there could be up to three different sets of solutions covered. The Discussion section goes into detail about the solution(s). The See Also section contains references to additional sources of information that can be useful if you still need more information after reading the discussion. The See Also section may reference other recipes, Microsoft Knowledge Base (MS KB) (http://support.microsoft.com/) articles, or documentation from the Microsoft Developers Network (MSDN) (http://msdn.microsoft.com).

At Least Three Ways to Do It

People like to work in different ways. Some prefer graphical interfaces (GUIs) while others like to work from the command-line interface (CLI). And experienced system administrators like to automate tasks using scripts. Since people prefer different methods, and no one method is necessarily better than another, I decided to write solutions to recipes using one of each. That means instead of a single solution per recipe, I include up to three solutions using GUI, CLI, and scripting examples. That said, some recipes cannot be accomplished with one of the three methods or it may be very difficult to do with a particular method. In that case, I cover only the applicable methods.

In the GUI and CLI solutions, I use standard tools that are readily accessible. There are other freeware, shareware, or commercial tools that I could have used that would have made some of the tasks easier to accomplish, but I wanted to make this book as useful as possible without requiring you to hunt down the tools or purchase an expensive software package.

I took a similar approach with the scripting solutions. While I prefer Perl, I use VBScript due to its widespread use among Windows administrators. It is also the most straightforward from a coding perspective when using WMI and Windows Script Host (WSH). For those familiar with other languages, such as Visual Basic, Perl, and JScript, it is very easy to convert code from VBScript. See the sidebar “Differences Between VBScript and Perl” for more information on how to convert between those two languages.

For those of you who wish that all of the solutions were written with Perl instead of VBScript, you are in luck. I’ve posted companion Perl scripts for each VBScript example on the book’s web site. Go to http://www.rallenhome.com/books/ to download the code.

Windows 2000 Versus Windows Server 2003

Another challenge with writing this book was determining which operating system version to cover. Many organizations still run Windows 2000, but Windows Server 2003 has been a big seller (at least according to Microsoft). Since Windows Server 2003 is the latest and greatest version and includes a lot of new tools that aren’t present in Windows 2000, my approach is to make everything work under Windows Server 2003 first, and Windows 2000 second. In fact, the majority of the solutions will work unchanged with Windows 2000. For the recipes or solutions that are specific to a particular version, I include a note mentioning the version it targets. Most GUI and scripting solutions work unchanged with either version, but Microsoft introduced several new command-line tools with Windows Server 2003, many of which cannot be run on Windows 2000 as certain system application programming interfaces (APIs) have changed from Windows 2000 to Windows Server 2003. Typically, you can still use these newer tools on a Windows XP or Windows Server 2003 computer to manage Windows 2000.

Where to Find the Tools

For the GUI and CLI solutions to mean much to you, you need access to the tools that are used in the examples. For this reason, in the majority of cases and unless otherwise noted, I used only tools that are part of the default operating system or available in the Resource Kit or Support Tools. There are two exceptions to this rule that I’ll explain shortly.

The Resource Kits for Windows 2000 Server and Windows Server 2003 are invaluable sources of information, and provide numerous tools that aid administrators in their daily tasks. More information on the Resource Kits can be found at the following web site: http://www.microsoft.com/windows/reskits/. Some tools are freely available online, but others must be purchased as part of a Resource Kit. The Windows 2000 Support Tools, which are called the Windows Support Tools in Windows Server 2003, contain many “must have” tools for people that work with Windows Server. The installation MSI for the Windows Support Tools can be found on a Windows 2000 Server or Windows Server 2003 CD in the \support\tools directory.

Tip

Even though many of the same tools are available in both the Windows 2000 Support Tools and Windows Server 2003 Support Tools, several have been enhanced in the latter version including LDP, Dsacl, and LDIFDE.

The biggest source of tools that I use that don’t come from Microsoft can be found on the Sysinternals web site: http://www.sysinternals.com/. Mark Russinovich and Bryce Cogswell have developed a suite of extremely useful tools that every Windows Server system administrator should be familiar with. These tools are free and they often come with complete source code for the tool.

Another good source of tools, especially for Active Directory, is Joe Richards’ Joeware site: http://www.joeware.net/. Joe wrote many of his tools, some in executable form and others in Perl, to help in daily system administration tasks, so they are all very practical and useful. And like Sysinternals, most are free.

Running Tools with Alternate Credentials

A best practice for managing Windows Server systems is to create separate administrator accounts with elevated privileges, instead of letting administrators use the same user account with which they access network resources. This is beneficial because an administrator who wants to use elevated privileges must explicitly log on with his admin account instead of having the rights all the time, which could lead to accidental changes. Assuming you employ this method, you have to provide alternate credentials when using tools to administer systems unless you log on (locally or with Terminal Services) to the target machine with the admin credentials.

There are several ways to specify alternate credentials when running tools. Many GUI and CLI tools have an option to specify a user and password for authentication. If the tool you want to use does not have that option, you can use the runas.exe command instead. The following command runs the enumprop.exe command under the credentials of the administrator account in the rallencorp.com domain:

> runas /user:administrator@rallencorp.com /netonly "enumprop LDAP://dc1/
dc=rallencorp,dc=com"

Sometimes it is convenient to create a MMC console that runs under administrator privileges. In this case, simply use mmc.exe as the command to run from runas:

> runas /user:administrator@rallencorp.com /netonly "mmc.exe"

This will create an empty MMC console from which you can add consoles for any snap-in that has been installed on the local computer. This is beneficial because all of the consoles that you add will be run under that administrative account. If you don’t want to type that command over and over, simply create a shortcut on your desktop and put the command as the target path. By doing this, you eliminate one of the common complaints about using alternate credentials; that is, it makes the job more tedious.

Tip

The /netonly option is necessary if the user you are authenticating with does not have local logon rights on the computer from which you are running the command, or if you want to authenticate with an account from a nontrusted domain.

There is another option for running MMC snap-ins or any GUI program with alternate credentials. Click on the Start menu and browse to the tool you want to open, hold down the Shift key, and then right-click on the tool. If you select Run As, you will be prompted to enter alternate credentials with which to run the tool.

A Brief Word on Windows Scripting

Much has been said over the years about how unfriendly Windows Server is to experienced system administrators who want to automate tasks with scripts. I’m pleased to say that Microsoft has made some great strides in this area over the past three or four years so that now there are very few tasks that you cannot automate with a script.

Microsoft has developed three primary scripting interfaces over the years: WSH, WMI, and ADSI. Note that I said that these are interfaces, not languages. In generic terms, a scripting interface is just a framework for how a script calls functions or methods to perform tasks. WSH is the scripting engine that acts as the interpreter for the scripting languages that are native to Windows (i.e., VBScript and Jscript). It has an interface for doing basic scripting such as printing out to a console or displaying a dialog box, processing command-line arguments, and other basic system administration tasks such as reading and writing files and manipulating the Registry. WMI is the high-octane system management interface. With it you can query and often configure many of the components within Windows. WMI is to computers what ADSI is to Active Directory. ADSI is the primary scripting interface for querying and manipulating objects in Active Directory. You can also use it to manage local users and groups on a computer as well as the IIS Metabase.

For a more thorough introduction to each of these interfaces, check out Appendix A, Appendix B, and Appendix C.

Getting the Most Out of Your Scripts

With the VBScript solutions, my intention is to provide the answer in as few lines of code as is reasonable. Since this book is not a pure programming book, I did not want to overshadow the graphical and command-line solutions by providing pages of code or detailed explanations on how to use WSH, WMI, or ADSI. If you are looking for such material, I recommend my book Active Directory Cookbook (O’Reilly) or Windows 2000 Scripting Guide by Microsoft Corporation (MSPress). The code in this book is meant to show you the basics for how a task can be automated and let you run with it. Most examples will take only minor tweaking to make them do something useful in your environment.

To make the code as simple as possible, I had to remove error checking and other features that are standard scripting best practices. Next, I’ll describe how to incorporate these things into your own scripts so that you can quickly turn any code in this book into a robust script with all the trimmings.

Running Scripts Using Alternate Credentials

Just as you might need to run the graphical and command-line tools with alternate credentials, you may also need to run your scripts and programs with alternate credentials. One way is to use the runas utility when you invoke a script from the command line. Another option is to use the Scheduled Tasks service to run the script under credentials you specify when creating the scheduled task. And yet another option is to hardcode the credentials in the script. Obviously this is not very appealing in many scenarios because you do not want the username and password contained in the script to be easily viewable by others. Nevertheless, at times it is a necessary evil, especially when working against multiple servers, and I’ll describe how it can be done with WMI, ADSI, and ADO.

WMI

Here is example WMI code that prints the list of disk drives on a system:

strComputer = "."  ' localhost
set objWMI = GetObject("winmgmts:\\" & strComputer & "\root\cimv2")
set objDisks = objWMI.InstancesOf("Win32_LogicalDisk")
for each objDisk in objDisks
    Wscript.Echo "DeviceID: " &  objDisk.DeviceID       
    Wscript.Echo "FileSystem: " &  objDisk.FileSystem   
    Wscript.Echo "FreeSpace: " & objDisk.FreeSpace      
    Wscript.Echo "Size: " & objDisk.Size        
    WScript.Echo ""
next

This code does the same thing, except it targets a remote computer (srv01) and authenticates as the administrator account on that system:

set objLocator = CreateObject("WbemScripting.SWbemLocator")
set objWMI = objLocator.ConnectServer("srv01", "root\cimv2", _
                                      "srv01\administrator", "Adm1nPa33wd")
set objDisks = objWMI.InstancesOf("Win32_LogicalDisk")
for each objDisk in objDisks
    Wscript.Echo "DeviceID: " &  objDisk.DeviceID       
    Wscript.Echo "FileSystem: " &  objDisk.FileSystem   
    Wscript.Echo "FreeSpace: " & objDisk.FreeSpace      
    Wscript.Echo "Size: " & objDisk.Size        
    WScript.Echo ""
next

To authenticate as an alternate user in WMI, you simply need to replace the GetObject call with two statements. The first is a call to CreateObject, which instantiates a SWbemLocator object. With this object, you can then call the ConnectServer method and specify the credentials for authentication. The first parameter is the server name, the second is the WMI provider path, the third is the user, and the fourth is the user’s password.

ADSI

With ADSI, you can use the IADsOpenDSObject::OpenDSObject method to specify alternate credentials. For example, a solution to print out the description of a domain might look like the following:

set objDomain = GetObject("LDAP://dc=rallencorp,dc=com")
WScript.Echo "Description: " & objDomain.Get("description")

Using OpenDSObject, it takes only one additional statement to make the same code authenticate as the administrator account in the domain.

set objLDAP = GetObject("LDAP:")
set objDomain = objLDAP.OpenDSObject( _
    "LDAP://dc=rallencorp,dc=com", _
    "administrator@rallencorp.com", _
    "MyPassword", _
    0)
WScript.Echo "Description: " & objDomain.Get("description")

ADO

It is just as easy to authenticate in ADO code. Take the following example, which queries all computer objects in the rallencorp.com domain:

strBase    =  "<LDAP://dc=rallencorp,dc=com>;"
strFilter  = "(&(objectclass=computer)(objectcategory=computer));" 
strAttrs   = "cn;"
strScope   = "subtree"
   
set objConn = CreateObject("ADODB.Connection")
objConn.Provider = "ADsDSOObject"
objConn.Open "Active Directory Provider"
set objRS = objConn.Execute(strBase & strFilter & strAttrs & strScope)
objRS.MoveFirst
while Not objRS.EOF
    Wscript.Echo objRS.Fields(0).Value
    objRS.MoveNext
wend

Now, by adding two lines (shown in bold), we can authenticate with the administrator account:

strBaseDN  =  "<LDAP://dc=rallencorp,dc=com>;"
strFilter  = "(&(objectclass=computer)(objectcategory=computer));" 
strAttrs   = "cn;"
strScope   = "subtree"
   
set objConn = CreateObject("ADODB.Connection")
objConn.Provider = "ADsDSOObject"
objConn.Properties("User ID")  = "administrator@rallencorp.com"
                  objConn.Properties("Password") = "MyPassword"
objConn.Open "Active Directory Provider"
set objRS = objConn.Execute(strBaseDN & strFilter & strAttrs & strScope)
objRS.MoveFirst
while Not objRS.EOF
    Wscript.Echo objRS.Fields(0).Value
    objRS.MoveNext
wend

To authenticate with ADO, you need to set the User ID and Password properties of the ADO connection object. I used the user principal name (UPN) of the administrator for the user ID in this example. Active Directory allows connections with a UPN (administrator@rallencorp.com), NT 4.0-style account name (e.g., RALLENCORP\Administrator), or distinguished name (e.g., cn=administrator,cn=users,dc=ral-lencorp,dc=com) for the user ID.

Defining Variables and Error Checking

An important part of any script is error checking. Error checking allows your programs to gracefully identify any issues that arise during execution and take appropriate action. Another good practice when writing scripts is to define variables before you use them and clean them up after you are done with them. In this book, most of the programmatic solutions do not include any error checking, predefined variables, or variable clean up. While admittedly this does not set a good example, if I included extensive error checking and variable management, it would have made this book considerably longer with little value to you, the reader.

Error checking with VBScript is pretty straightforward. At the beginning of the script, include the following declaration:

On Error Resume Next

This tells the script interpreter to continue even if errors occur. Without that declaration, whenever an error is encountered, the script will abort. When you use On Error Resume Next, you need to use the Err object to check for errors after any step where a fatal error could occur. The following example shows how to use the Err object.

On Error Resume Next
set objDomain = GetObject("LDAP://dc=rallencorp,dc=com")
if Err.Number <> 0 then
   Wscript.Echo "An error occured getting the domain object: " & Err.Description
   Wscript.Quit
end if

Two important properties of the Err object are Number, which if nonzero signifies an error, and Description which contains the error message (when present).

As far as variable management goes, it is always a good practice to include the following at the beginning of every script:

Option Explicit

When this is used, every variable in the script must be declared or an exception will be generated when you attempt to run the script. This prevents a mistyped name from causing hard-to-trace errors. Variables are declared in VBScript using the Dim keyword. After you are done with a variable, it is a good practice to set it to Nothing so you release any resources bound to the variable, and don’t accidentally reuse the variable with its previous value. The following code shows a complete example for printing the display name for a domain with error checking and variable management included:

Option Explicit
On Error Resume Next
   
Dim objDomain
set objDomain = GetObject("LDAP://cn=users,dc=rallencorp,dc=com")
if Err.Number <> 0 then
   Wscript.Echo "An error occured getting the domain object: " & Err.Description
   Wscript.Quit
end if
   
Dim strDescr
strDescr = objDomain.Get("description")
if Err.Number <> 0 then
   Wscript.Echo "An error occured getting the description: " & Err.Description
   Wscript.Quit
end if
   
WScript.Echo "Description: " & strDescr
   
set objDomain = Nothing
set strDescr  = Nothing

Using Command-Line Options in a Script

Most code samples you’ll see in this book use hardcoded variables. That means when you want to change the value of a variable, you have to modify the script. A much more flexible solution is to obtain the desired value of those variables via command-line options. All good command-line programs work this way.

With WSH, you can retrieve the command-line options that are passed to a script by enumerating the WScript.Arguments object. Here is an example:

set objArgs = WScript.Arguments
WScript.Echo "Total number of arguments: " & WScript.Arguments.Count
for each strArg in objArgs
    WScript.Echo strArg
next

This works OK, but there is no structure to it. You can’t retrieve the value of the /foo option by name. You can only access elements of a WScript.Arguments collection by index number. But never fear, WSH 5.6 introduced named and unnamed arguments. Let’s say we invoked the following command:

> d:\scripts\dostuff.vbs /c:test /verbose:4

This bit of code shows how you can access the /c and /verbose options:

WScript.Echo WScript.Arguments.Named.Item("c")
WScript.Echo WScript.Arguments.Named.Item("verbose")

Writing the Output of a Script to a File

In most of the code in this book, I simply print the output to STDOUT using the WScript.Echo method. This is OK if you need an interactive script, but what if you want to schedule one to run periodically? Printing the output to STDOUT won’t do much good. An alternative is to write the output to a file instead. This is pretty easy using WSH. The following code appends some text to a file:

' ------ SCRIPT CONFIGURATION ------
strFile = "<FilePath>"   ' e.g. c:\output.txt
' ------ END CONFIGURATION ---------
constForAppending = 8
set objFSO = CreateObject("Scripting.FileSystemObject")
set objFile = objFSO.OpenTextFile(strFile, constForAppending, True)
objFile.WriteLine("Script completed: " & Now)
objFile.Close

There is nothing magical here. The Scripting.FileSystemObject interface is used for working with files. The OpenTextFile method supports different access options. The following script is a variation of the earlier script except it opens a file for writing out all of the running processes (overwriting any existing data in the file):

' ------ SCRIPT CONFIGURATION ------
strFile = "<FilePath>"   ' e.g. c:\output.txt
' ------ END CONFIGURATION ---------
constForWriting = 2
set objFSO = CreateObject("Scripting.FileSystemObject")
set objFile = objFSO.OpenTextFile(strFile, constForWriting, True)
   
objFile.WriteLine("Script started: " & Now)
objFile.WriteLine("List of processes:")
   
set objWMI = GetObject("winmgmts:root\cimv2")
for each objProcess in objWMI.InstancesOf("Win32_Process")
    objFile.WriteLine(vbTab & objProcess.Name)
next
   
objFile.WriteLine("Script completed: " & Now)
objFile.Close

Instead of WScript.Echo, you have to use the WriteLine method of the Scripting.FileSystemObject object. If you also wanted to print the results to STDOUT, there is nothing to prevent you from putting a WScript.Echo statement right before or after a WriteLine statement.

Sending the Output of a Script in Email

When you automate a task, you are being proactive. Part of being proactive is trying to identify issues before they turn into major problems. If your scripts simply append their status to a log file, it is unlikely you’ll learn about any problems in a timely manner unless you are vigilantly watching over your log files. Fortunately, you can send emails very easily from VBScript so that instead of writing to a file, you can choose to send an email when there is a serious issue.

Here is an example script that just sends simple email:

' This code sends an email via SMTP
' ------ SCRIPT CONFIGURATION ------
strFrom = "script@rallencorp.com"
strTo   = "rallen@rallencorp.com"
strSub  = "Script Output"
strBody = "The script ran successfully"
strSMTP = "smtp.rallencorp.com"
' ------ END CONFIGURATION ---------
   
set objEmail = CreateObject("CDO.Message")
objEmail.From = strFrom
objEmail.To = strTo
objEmail.Subject = strSub
objEmail.Textbody = strBody
objEmail.Configuration.Fields.Item( _
         "http://schemas.microsoft.com/cdo/configuration/sendusing") = 2
objEmail.Configuration.Fields.Item( _
         "http://schemas.microsoft.com/cdo/configuration/smtpserver") = _
         strSMTP
objEmail.Configuration.Fields.Update
objEmail.Send
WScript.Echo "Email sent"

This code requires the use of a SMTP-enabled mail server. The email is directed toward the mail server, which relays it to the correct destination. This script also requires Microsoft Collaboration Data Objects (CDO) to be installed on the client computer. This can be done by installing Outlook or by installing CDO separately from the Microsoft site (search for “CDO” on http://msdn.microsoft.com/).

Reading and Writing from Excel

A common question I see on newsgroups has to do with reading and writing Excel spreadsheets from scripts. Why would you want to do this, you might ask? Well, let’s suppose that I manage over 20 servers. I put together a small spreadsheet to keep track of them. Now, if I want to perform a task on all of my servers with a script, all I need to do is read information about each of the servers from the Excel spreadsheet and I don’t have to worry about hardcoding the servers within the script.

This next script shows how to iterate over the rows in a worksheet until the script comes across a row that does not have the first cell populated:

' ------ SCRIPT CONFIGURATION ------
strExcelPath = "c:\data.xls"
intStartRow = 2
' ------ END CONFIGURATION ---------
On Error Resume Next
set objExcel = CreateObject("Excel.Application")
if Err.Number <> 0 then
  Wscript.Echo "Excel application not installed."
  Wscript.Quit
end if
On Error GoTo 0
   
objExcel.WorkBooks.Open strExcelPath
set objSheet = objExcel.ActiveWorkbook.Worksheets(1)
   
intRow = intStartRow
do while objSheet.Cells(intRow, 1).Value <> ""
  WScript.Echo "Row " & intRow
  WScript.Echo "Cell 1: " & objSheet.Cells(intRow, 1).Value
  WScript.Echo "Cell 2: " &  objSheet.Cells(intRow, 2).Value
  WScript.Echo "Cell 3: " &  objSheet.Cells(intRow, 3).Value
  WScript.Echo "Cell 4: " &  objSheet.Cells(intRow, 4).Value
  intRow = intRow + 1
  WScript.Echo
loop
   
objExcel.ActiveWorkbook.Close
objExcel.Application.Quit
Wscript.Echo "Done"

In this case, I just printed the values from the first four cells. You could obviously do more complex stuff with that information.

Now suppose I wanted to analyze the process information of a system. I could use the taskmgr.exe program, but it doesn’t really give me the flexibility I need. Instead I can write a script to output that information to a spreadsheet. Here is the code to do that:

' ------ SCRIPT CONFIGURATION ------
strComputer = "."
strExcelPath = "d:\procs.xls"
' ------ END CONFIGURATION ---------
   
On Error Resume Next
set objExcel = CreateObject("Excel.Application")
if Err.Number <> 0 then
  Wscript.Echo "Excel application not installed."
  Wscript.Quit
end if
On Error GoTo 0
   
' Create a new workbook.
objExcel.Workbooks.Add
   
' Bind to worksheet.
Set objSheet = objExcel.ActiveWorkbook.Worksheets(1)
objSheet.Name = "Processes"
   
' Populate spreadsheet cells with user attributes.
objSheet.Cells(1, 1).Value = "Process Name"
objSheet.Cells(1, 2).Value = "Command Line"
objSheet.Cells(1, 3).Value = "PID"
objSheet.Cells(1, 4).Value = "Owner"
objSheet.Range("A1:D1").Font.Bold = True
   
' Query process information
set objWMI = GetObject("winmgmts:\\" & strComputer & "\root\cimv2")
intProcessCount = 1
for each objProcess in objWMI.InstancesOf("Win32_Process")
   ' For each process, write the name, command-line options and process ID
   ' to the spreadsheet
   intProcessCount = intProcessCount + 1
   objSheet.Cells(intProcessCount,1).Value = objProcess.Name
   objSheet.Cells(intProcessCount,2).Value = ObjProcess.CommandLine
   objSheet.Cells(intProcessCount,3).Value = ObjProcess.ProcessID
   objProcess.GetOwner strUser,strDomain
   objSheet.Cells(intProcessCount,4).Value = strDomain & "\" & strUser
next
   
' This formats the columns
objExcel.Columns(1).ColumnWidth = 20
objExcel.Columns(2).ColumnWidth = 50
objExcel.Columns(3).ColumnWidth = 5
objExcel.Columns(4).ColumnWidth = 30
   
' Save the spreadsheet, close the workbook and exit.
objExcel.ActiveWorkbook.SaveAs strExcelPath
objExcel.ActiveWorkbook.Close
objExcel.Application.Quit
   
WScript.Echo "Done"

I included comments in the code to help you follow along with what is happening. Pretty straightforward, isn’t it? Keep in mind that Excel must be installed on the computer in order to run this script.

Where to Find More Information

While it is my hope that this book provides you with enough information to perform the majority of Windows system administration tasks you are likely to do, it is not realistic to think every possible task can be covered. In fact, there are easily another five or six chapters I could have included in this book, but due to space and time considerations it was not possible for this edition. There is a wealth of additional resources and information you can find on the Internet or in a bookstore. In this section I cover some of the ones I use most frequently.

Help and Support Center

Windows Server 2003 comes with a new feature called the Help and Support Center, which is available directly off the Start menu. It is a great resource of information and it serves as the central location to obtain help information about the operating system, applications, and installed utilities.

Command-Line Tools

If you have any questions about the complete syntax or usage of a command-line tool used in the book, you should first look at the help information available with the tool. The vast majority of CLI tools provide syntax information by simply passing /? as a parameter. For example:

> netsh /?

Microsoft Knowledge Base

The Microsoft Help and Support web site is a great source of information and is home to the Microsoft Knowledge Base (MS KB) articles. Throughout the book I include references to pertinent MS KB articles where you can find more information on a topic. You can find the complete text for a KB article by searching on the KB number at the following web site: http://support.microsoft.com/default.aspx. You can also append the KB article number to the end of this URL to go directly to the article: http://support.microsoft.com/?kbid=.

Microsoft Developers Network

MSDN contains a ton of information on Windows Server and programmatic interfaces such as WMI. Throughout the book, I’ll sometimes reference MSDN pages in recipes where applicable. Unfortunately, there is no easy way to reference the exact page I’m referring to unless I provided the URL or navigation to the page, which would more than likely change by the time the book was printed. Instead, I provide the title of the page, which you can search for via the following site: http://msdn.microsoft.com/library/.

Web Sites

These web sites are great starting points for information that helps you perform the tasks covered in this book:

Microsoft Windows Server home pages (http://www.microsoft.com/windowsserver2003/default.mspx; http://www.microsoft.com/windows2000/)

These sites are the starting point for Windows Server information provided by Microsoft. They contain links to whitepapers, case studies, and tools.

Microsoft webcasts (http://support.microsoft.com/default.aspx?scid=fh;EN-US;pwebcst)

Webcasts are on-demand audio/video technical presentations that cover a wide range of Microsoft products. There are numerous webcasts related to Windows Server technologies that cover such topics as disaster recovery, Windows Server 2003 upgrade, and Terminal Services deployment.

Google (http://www.google.com/)

Google is my primary starting point for locating information. Google is often quicker and easier to use to search the Microsoft web sites (e.g., MSDN) than the search engines provided on those sites.

MyITForum (http://www.myitforum.com)

The MyITForum site has very active online forums for various Microsoft technologies. It also has a large repository of scripts.

LabMice (http://www.labmice.net/)

The LabMice web site contains a large collection of links to information on Windows Server including MS KB articles, whitepapers, and other useful web sites.

Robbie Allen’s home page (http://www.rallenhome.com/)

This is my personal web site, which has information about the books I’ve written and links to download the code contained in each (including this book).

Microsoft Technet script center (http://www.microsoft.com/technet/community/scriptcenter/default.mspx)

This site contains a large collection of WSH, WMI, and ADSI scripts.

Newsgroups

Most of the Windows Server-related Microsoft newsgroups are very active and have one or more of Microsoft’s Most Valuable Professionals (MVPs) actively responding to questions. If you have a question and can’t find an answer, try posting to the pertinent newsgroup.

These are general-purpose Windows Server newsgroups:

  • microsoft.public.windows.server.general

  • microsoft.public.win2000.general

Each of these newsgroups covers a specific Windows Server technology:

  • microsoft.public.windows.server.security

  • microsoft.public.win2000.security

  • microsoft.public.inetserver.iis

  • microsoft.public.windows.server.active_directory

  • microsoft.public.win2000.active_directory

  • microsoft.public.windows.server.dns

  • microsoft.public.win2000.dns

  • microsoft.public.exchange2000.general

These are the scripting-related newsgroups:

  • microsoft.public.scripting.vbscript

  • microsoft.public.scripting.wsh

  • microsoft.public.windows.server.scripting

  • microsoft.public.win32.programmer.wmi

  • microsoft.public.adsi.general

  • microsoft.public.active.directory.interfaces

If you have a question about a particular topic, a good starting point is to search the newsgroups using Google Groups (http://groups.google.com/). Just like Google’s web search engine, Google’s group search engine is an invaluable resource. Another good resource is the following Yahoo! Group: http://groups.yahoo.com/group/adsianddirectoryservices.

Books

In addition to the Resource Kit books, the following books are invaluable resources for Windows Server system administration:

The Ultimate Windows Server 2003 System Administrator's Guide by Robert Williams and Mark Walla (Addison-Wesley)

This book is a good all-purpose tutorial on Windows Server 2003.

Windows Server 2003 in a Nutshell by Mitch Tulloch (O’Reilly)

This is a great reference guide for Windows Server 2003.

Microsoft Windows 2000 Scripting Guide by Microsoft Windows Server Resource Kit Team (MS Press)

This book is one of the best available on scripting with Windows 2000.

Active Directory Cookbook by Robbie Allen (O’Reilly)

If you like the book you are reading now and want to learn more about Active Directory, you’ll want to check out this book.

Magazines

A good way to stay current with the latest industry trends and system administration techniques is by reading magazines. Here are a few good ones you should consider subscribing to:

Windows IT Pro Magazine (http://www.windowsitpro.com/)

This is a general-purpose monthly magazine for system administrators that support Microsoft products. The articles contributed by industry experts are informative and provide unique insight into common issues system administrators face.

Windows Scripting Solutions (http://www.winnetmag.com/WindowsScripting/)

This is a useful monthly newsletter that covers all aspects of scripting in the Windows environment. You’ll see a little bit of everything in this newsletter.

Security Administrator (http://www.winnetmag.com/WindowsSecurityIndex.cfm)

Security is an important part of any system administrator’s job these days. With this newsletter you’ll be able to stay abreast of the latest Windows security issues.

Get Windows Server Cookbook now with the O’Reilly learning platform.

O’Reilly members experience live online training, plus books, videos, and digital content from nearly 200 publishers.