Executive Summary:
Kb.ps1 is Windows PowerShell script that uses Windows Management Instrumentation (WMI) to check whether a specific patch is installed on computers and provides the results in an onscreen report. To make it easier to spot problematic computers, this Windows PowerShell script displays the names of the computers that aren't patched in red and the names of the computers that are successfully patched in green. |
Each time Microsoft Software Update
Services (SUS) downloads patches,
there are always a few machines not
properly patched due to unforeseeable
problems. Because SUS doesn’t
have any reporting tools, it’s difficult
to determine which machines aren’t
patched. Thus, administrators at my
company have been using KB.vbs to
report the status of patches on more
than 600 Windows client machines.
In my Reader to Reader article “Does
SUS Make You Want to Send an SOS?”
(www.windowsitpro.com/Articles/ArticleID/46953/46953.html), I present
this VBScript script, which I wrote.
Although KB.vbs works well, I
decided to rewrite the script in PowerShell
last July because I wanted to
experience the power in PowerShell
firsthand. More important, I never
want to stop learning. I feel it’s important
to learn to apply PowerShell to
current problems.
The result is kb.ps1. Like KB.vbs,
kb.ps1 first attempts to ping the
machines listed in an input file
named pclist.txt. If a PC is online,
the script determines whether the
specified patch exists and reports
the results. To make it easier to spot
problematic computers, the names
of the computers that aren’t patched
are displayed in red and the names of
the computers that are successfully
patched are displayed in green. The
script also reports ping failures.
Figure 1 shows a sample input file. The
path to this input file and the patch to search
for are specified on the command line when
you launch the script. The launch syntax is
powershell.exe Path\kb.ps1
InputFilePath kbxxxxxx
where Path is the folder in which kb.ps1 is
stored, InputFilePath is the pathname of the
input file, and kbxxxxxx is the ID of patch you
want to search for. Alternatively, if kb.ps1 and
pclist.txt are in the same folder in the default
PowerShell directory (e.g., D:\PowerShellscripts), you can type
Path>powershell .\kb.ps1
.\pclist.txt kbxxxxxx
where Path is the folder in which kb.ps1 and
pclist.txt are stored and kbxxxxxx is the ID of
patch you want to search for.
As Listing 1 shows, kb.ps1 starts by
executing two commands that you wouldn’t
typically see at the beginning of PowerShell
scripts. The first command
$erroractionpreference = `
“SilentlyContinue”
completely suppresses error output. By
default, when an error occurs, PowerShell
issues an error message, then continues to
the next line. When you set the $Error-
ActionPreference automatic variable to
SilentlyContinue, the processing continues
but an error message isn’t issued. Suppressing
error messages eliminates distractions for
the administrators when they’re reviewing
the onscreen patch-status report. Because
kb.ps1 is a tried-and-true script that we’ve
been using continually for the past 6 months,
the benefits of suppressing error messages
outweigh the risks.
The second command
clear-host
clears the PowerShell window. Typically,
the Clear-Host function is used at the end
of scripts, but I used it at the beginning of
kb.ps1 to clear the screen before any processing
begins. Once again, that helps generate
a clean, easily readable electronic report for
administrators to review.
After clearing the PowerShell window,
kb.ps1 counts the number of commandline
arguments. If there aren’t exactly two,
it displays the syntax for the launch command.
If two arguments are present, the
script retrieves them, assigning the input file
pathname to the $filename variable and the
patch ID to the $kb variable.
Using the Get-Content cmdlet, kb.ps1 reads
in the names of the computers in $filename, one at a time. For each computer, the script
uses Windows Management Instrumentation’s
(WMI’s) Win32_PingStatus class to ping the
computer. The Get-WmiObject cmdlet with the
-query parameter is used to execute the WMI
Query Language (WQL) statement that pings
the machine. The script determines whether
the ping succeeded (i.e., returned a value of 1)
by checking the value in the StatusCode property
of the Win32_PingStatus class.
If the ping didn’t succeed, kb.ps1 uses the
Write-Host cmdlet to log the computer’s name
and the message Ping failed. I didn’t use the
Write-Error cmdlet to write the ping-failure
information because it mangles the information
almost to the point of being unreadable.
After writing the error message, the script ends
so that the Help desk can determine why the
machine is offline and fix the problem.
If the ping succeeded, the script uses the
Get-WmiObject cmdlet with WMI’s Win32_
QuickFixEngineering class to retrieve the
patches installed on that computer. The script
pipes the results to the Where-Object cmdlet,
which filters the results for information about
the specified patch. The results of that filter
operation are then piped to the Select-Object
cmdlet, which retrieves the patch’s HotFixID
and Description properties.
As callout A shows, kb.ps1 checks to
see whether the HotFixID property’s value
is the same as the $kb variable’s value. If
they match, the script writes the computer’s
name and the patch’s description in green
text. If they don’t match, the script writes the
computer’s name and the message Patch not
found in red text.
To write the patch-status information,
the script again uses Write-Host. This cmdlet
writes information directly to the host interface,
which makes the output unusable for
pipelining. However, we don’t need the output
piped anywhere. Equally important, if the
script were to let standard output handle the
patch display, you’d get lots of pages containing
extraneous information. For our purposes
(i.e., generating a clean, easily readable electronic
report), using Write-Host works best.
As you can see, there’s nothing fancy
about kb.ps1. However, it’s shorter and faster
than KB.vbs. Plus, the color-coded results
make the report easier to read and more presentable
for administrators.
See Associated Figure
Just my two cents
Thanks for the script!
doubleplay1 December 10, 2008 (Article Rating: