|When existing solutions don't work, you sometimes need to come up with your own. That exactly what a Windows engineer did when he couldn't use Microsoft Systems Management Server (SMS) 2003 or Windows Server Update Services (WSUS) for managing patches on the servers in the Active Directory (AD) environment. Part of that solution, MBSA_Scan.vbs, scans servers for updates and creates a file that lists the Windows patches (as prescribed by Microsoft TechNet) needed on those servers.|
Sometimes in an Active Directory (AD) environment the architecture isn't optimal and products aren't being used for the tasks for which they're best suited. For example, at my company, Microsoft Systems Management Server (SMS) 2003 servers are being used for workstation management, leaving the servers out in the cold when it comes to patch management.
Although Microsoft offers Windows Server Update Services (WSUS), it's not a viable solution for us. WSUS doesn't give you much control over what updates are installed. WSUS follows only its own “approved lists” when updating all member machines. This isn't flexible enough for our environment, which contains third-party applications that don't work with all Microsoft updates.
When you're in a situation like this, you need to come up with an alternative solution. In our case, I created a script, MBSA_Scan.vbs, that scans servers for updates and creates a file that lists the Windows patches (as prescribed by Microsoft TechNet) needed on those servers. Although I use the file as input for another script that performs the necessary updates, you can use MBSA_Scan.vbs to determine which servers need updates. (Because the follow-up script uses the command line to install patches, it takes a lot of administrative work compared to SMS. So, I won't be discussing that script here.)
As its name suggests, MBSA_Scan.vbs uses Microsoft Baseline Security Analyzer (MBSA). To use this script, you need to have the latest version of MBSA (version 2.0 as of this writing), Windows Script Host (WSH), and Windows Management Instrumentation (WMI) installed on the machine running the script. In addition, the MBSA offline scan file (wsusscn2.cab) must be up-to-date. MBSA_Scan.vbs runs on Windows Server 2003 (32 and 64 bit), Windows XP (32 and 64 bit), and Windows 2000 platforms. Let's look at how to use this script, how MBSA's command-line interface— mbsacli.exe—works, and how the script works.
How to Use the Script
To use MBSA_Scan.vbs, you need to perform several steps:
- Download MBSA_Scan.vbs by clicking the Download the Code Here button at the top of the page.
- Make sure that the latest version of MBSA is installed in the default location on the machine running the script. Also make sure that the offline scan file (wsusscn2.cab) is up-to-date. You can download the most recent .cab file from http://go.microsoft.com/fwlink/?LinkId=76054.
- Create a text file named servers.dat and place it in the same directory as the script. In the text file, enter each remote server in the format
ServerID1 Domain\Username Passwordwhere ServerID1 is the name of the remote server you want to check, Domain/Username is the username with which you want to log on to that server, and Password is the password for that user. There must be exactly one space between each of the three elements. If you have Domain Admin rights or a connection already authenticated to a remote server, you don't need to include the username or password for that server. So, for example, if you have an authenticated connection to ServerID2, your text file would look like
ServerID2 Domain\Username Password
ServerID3 Domain\Username Password
ServerID1 Domain\Username Password
ServerID3 Domain\Username Password
- Run MBSA_Scan.vbs, using either WScript or CScript. If you use WScript, a message box noting its completion time will pop up when the script finishes running. If you use CScript, a text prompt will appear.
- Open the Scan Results.txt file in a text editor to view the output. This file will be in the same location as the script.
How Mbsacli.exe Works
Before you can understand how MBSA_Scan.vbs works, you need to know how to use MBSA's command-line interface. Mbsacli.exe has many command-line options. For our purposes, the command syntax to follow is
/u username /p password
/nvc /nm /nd
The /target server_name parameter tells MBSA that it will be scanning a remote server. Server_name can be a NetBIOS name, Fully Qualified Domain Name (FQDN), or IP address. The script uses the /u username and /p password parameters when the target server requires alternate credentials. The script makes this determination from the information provided in the servers.dat file.
Because the newest MBSA version and the latest offline scan file are already present on the machine performing the scan, the script uses three parameters—/nvc, /nm, and /nd—to reduce the length of time it takes to scan each server. Specifically, the /nvc parameter tells MBSA to skip the online check for a new MBSA version. The /nm parameter tells MSBA not to use Microsoft Update for scanning during the process. The /nd parameter tells MSBA not to download any files from the Microsoft Web site while scanning. Without these parameters, you could experience extremely long scan times (especially if there are restrictions on outbound network traffic) because the script would have to wait to timeout before moving to the next step in the scan process.
When you launch MBSA from the command line, you can use the /nai parameter to tell MBSA to skip updating the Windows Update Agent. However, if the Update Agent is out-of-date, the scan will fail. Thus, to ensure proper scanning, MBSA_Scan.vbs doesn't include this parameter so that MBSA checks for the latest Update Agent.
By default, MBSA scans for weak passwords (Password mode), security updates and patches (Updates mode), and administrative vulnerabilities in Windows OSs (OS mode), Microsoft SQL Server (SQL mode), and Microsoft IIS (IIS mode). Because we want to check for security updates and patches only, the script includes the /n Password+OS+IIS+SQL parameter so that MBSA doesn't scan for weak passwords and administrative vulnerabilities in the Windows OS, SQL Server, and IIS. For a more detailed explanation of these modes, see MBSA's online Help.
Finally, the redirect symbol (>) followed by the outputfile parameter tells MBSA to dump its results into the specified output file. You can use this symbol to capture and redirect any command's output.
How the Script Works
MBSA_Scan.vbs begins like most scripts in that it declares and sets the variables and constants that it will be using. The script then checks for MBSA in the default install location and for the servers.dat file. Next, using a large For…Next statement, which Listing 1 shows, the script parses each line in servers.dat to obtain each server's information and performs several tasks on each server.
The first task is checking for a username and password. As callout A in Listing 1 shows, if a username and password are present, the script sets them to the strUsername and strPassword variables, respectively. After retrieving the server name, the script pieces together a string that includes the server name, the /u parameter followed by the account name, and the /p parameter followed by the password. The string is assigned to the strMBSAPath variable, which will be used in the command to run MBSA. When a username and password aren't present, the script ignores the code in callout A and instead just sets strMBSAPath to the server name.
Next, MBSA_Scan.vbs creates a remote WMI connection to obtain the numeric OS representation for that server. This information is used in the follow-up script and not of interest here.
Callout B highlights where the script uses the strMBSAPath variable as part of the mbsacli.exe command that will run MBSA. Note the liberal use of the Chr function with the character code of 34. Chr(34) evaluates to a double quote (") at runtime. In the Windows command shell, a space is the default delimiter. So, when a command has an argument that contains an embedded space, you need to enclose that argument in double quotes. Otherwise, the command processor will interpret that one argument as two arguments and the code will fail. To tell the VBScript runtime engine to interpret that double quote as a literal character rather than a reserved character, the double quote is escaped with another double quote. (For more information about problems that spaces can cause, see the articles in the Learning Path section in upper right corner of this Web page.)
The code after callout B creates a WSH WshShell object and uses that object's Run method to execute the mbsacli.exe command. The call to the Run method includes four arguments. The first argument—"COMSPEC% /k"—forces the mbsacli.exe command to run in its own command-shell window. The second argument—strExecute—is the variable that contains the mbsacli.exe command. The third argument—" && Exit"—closes the command-shell window after the MBSA operation completes. The fourth argument—7—minimizes the command-shell window. The last argument—True—tells the VBScript engine to wait until the MBSA operation completes before proceeding to the next line in the script.
Note that there are several ways you can execute a program such as MBSA in VBScript code. For example, you might use the WshShell object's Exec method. I used the Run method so that I could take advantage of the option to minimize the command-shell window. The Exec method doesn't offer this level of active window manipulation. However, you might find that using the Exec method is a better alternative for your scripts.
After MBSA runs, it dumps its output into a temporary log (~templog.dat). Figure 1 shows an example of what the MBSA output looks like. When the script reads that output into a string, it counts how many lines are in it.
Figure 2 shows an example of the script's final output file, Scan Results.txt file. The only information that Scan Results.txt includes from the MBSA results are the Microsoft Security Bulletin numbers of the patches that need to be installed.
To create Scan Results.txt, the script begins by writing the information for each server on a separate line. As callout C shows, the information, which is delimited by spaces, includes the server name, numeric Windows version, username, and password. Note that the numeric Windows version, username, and password are used by the follow-up script. For the purposes here, you can ignore this information. Also note that in most instances, you wouldn't want a script to write passwords to an output file for security reasons. However, in my company's situation, including the passwords was necessary. Other security measures have been put in place to safeguard the passwords.
After the server information is written in Scan Results.txt, the script determines whether the MBSA operation succeeded on that server by checking to see whether the MBSA output has more than five lines. When the line count isn't greater than five, you know the MBSA operation failed because the first five lines hold the MBSA header and scanning prompt, as Figure 1 shows.
If the MBSA operation was successful, the script starts iterating through the MBSA output in the For…Next loop that callout D shows. The script uses the NewTrim function to remove leading and trailing spaces from a line in the output, then searches that line for the string Issue: Windows Security Updates. If that string is found, the script exits the For…Next loop and sends the MSBA output to the For…Next loop in callout E.
In the For…Next loop in callout E, the script iterates through the MSBA output and once again uses the NewTrim function to remove leading and trailing spaces from each line. Next, the script splits the trimmed line using a vertical bar (|) as a delimiter and reads the third element to get the installation status. If the status is anything other than Installed, the script writes the Microsoft Bulletin number to Scan Results.txt.
This process continues until all the Microsoft Bulletin numbers for missing patches are in Scan Results.txt. In the sample file in Figure 2, Scan Results.txt indicates that the five servers need three patches installed: MS07-040, MS07-039, and 890830.
As I just mentioned, the For…Next loops in both callout D and callout E use the NewTrim function. As Listing 2 shows, this function uses Chr(9) to remove tabs and Chr(32) to remove spaces. I use Chr(9) instead of the vbTab constant because vbTab isn't always recognized as a character and hence ignored. The ASCII character of 9 is recognized by most all computer languages as a tab, whereas vbTab is recognized only by Visual Basic (VB) and VB-derived languages such as VBScript. If you aren't too familiar with using ASCII characters in your code, I highly recommend you learn about them. Output files from third-party utilities and HTML files are just a few of the many files that use ASCII characters. By using the Chr function, you can use any character you like in your VBScript code. You'll often find Chr(34) used in VBScript code to add a double quote and Chr(13) used to add a carriage return. For information about using ASCII codes with the Chr function, see the VBScript online Help for the Chr function or the articles in the Learning Path section in upper right corner of this Web page.
Not SMS, But a Good Start
Using Scan Results.txt, you can very quickly and effectively get a comprehensive list of the Microsoft patches your servers need with little administrative intervention. It doesn't perform the installation process, but it can assist you in preparing your environment for getting your servers up-to-date in a short amount of time.