First published on TechNet on Jan 23, 2012
In my role, I often get to review failover clusters. Typically we look for configuration problems or deviations from best practices. One of the most challenging aspects of managing and maintaining a failover cluster is keeping the nodes identically configured. This means identical drivers, driver versions, service packs, hotfixes, services and applications across all cluster nodes.
Failover clusters are usually deployed with each node identically configured; however, as time passes the nodes tend to diverge. Drivers get updated on one node, but not the others. Hotfixes get installed on one node, but not the others. Your challenge, should you choose to accept it, is to keep the nodes the same. What you need are some tools to audit the configuration across the nodes, to look for differences.
In Windows Server 2008 and Windows Server 2008 R2 there are built in capabilities to compare failover cluster nodes. The tool is called “Validate a Configuration Wizard”. Simply run the validation wizard and it will (among other things) compare cluster nodes for differences in BIOS, drivers and hotfixes. (Note that the cluster validation wizard is much more powerful than simply comparing the cluster nodes. If you administer (or plan to administer) 2008 failover clusters you should get to know validation wizard).
Validate a New or Existing Failover Cluster
http://technet.microsoft.com/en-us/library/cc772450.aspx
What do you do, though, if you want to compare Windows Server 2003 cluster nodes, or systems that aren’t cluster nodes?
(Note: All examples use PowerShell v.2.0)
If you can extract information from two systems, PowerShell can do the comparison for you. For example, use the Get-Hotfix cmdlet to pull hotfix information from two different computers, and then use the Compare-Object cmdlet to compare them.
Start by pulling the hotfix information from a remote computer “ParentDC1”.
Get-Hotfix –computer ParentDC1
Notice all the “File 1” garbage? Let’s get rid of that.
Get-Hotfix –computer ParentDC1 | where{$_.HotfixID –like “KB*”}
Now, let’s hold that data in a variable so we can use it to compare to another system.
$a = Get-Hotfix –computer ParentDC1 | where{$_.HotfixID –like “KB*”}
Then, do likewise to collect information from another computer “ChildDC2”.
$b = Get-Hotfix –computer ChildDC2 | where{$_.HotfixID –like “KB*”}
Now, simply compare the two collections with Compare-Object. Note the use of the –property switch so we only compare hotfixIDs (and not hostnames, installed dates or installed by).
Compare-Object $a $b –property HotfixID
To interpret the output from Compare-Object you note the direction of the SideIndicator. When we called Compare-Object we put $a (ParentDC1) on the left and $b (ChildDC2) on the right. Thus, if the SideIndicator points to the left, the hotfix appears on ParentDC1 (and not ChildDC2). If the SideIndicator points to the right, the hotfix appears on ChildDC2 (and not ParentDC1).
That’s pretty cool and relatively easy. How about comparing services across systems? Same logic, but use the Get-Service cmdlet to get the data.
$a = Get-Service –computer ParentDC1
$b = Get-Service –computer ChildDC2
Compare-Object $a $b
Now things start getting a little interesting (or not, depending on your tastes). Unfortunately, there is no Get-Driver cmdlet. So we need to go into the weeds, and get some data using WMI. Basically, we combine two WMI queries. The first one, gets a list of installed drivers on a system.
$Query = “SELECT Name, PathName FROM Win32_SystemDriver WHERE PathName IS NOT NULL”
$driverList = Get-WmiObject –Query $Query –ComputerName ParentDC1
$driverlist
The second WMI query can take a pathname and return details about the driver (including version):
$Query2 = “SELECT Name, Version, Manufacturer, LastModified FROM CIM_DataFile WHERE Name = ‘C:\\Windows\\system32\\Drivers\\afd.sys”
$DriverInfo = Get-WMIObject –Query $Query2 –Computername ParentDC1
$DriverInfo
So you’ll need to create a collection of driver information on the first system by walking through the driver list. Then create a second collection of driver information for the second system by walking through its driver list. Then you use Compare-Object to compare the two collections. You could report differences in driver names, to report drivers installed on one system, but not the other. Or you could report differences in driver versions, to report differences in driver versions across systems.
If you’ve read this far, you’ve probably figured out that you’ll need to script the solution so you put in the necessary loops and create the custom data collections. I’ll spare you the details, and let you look through the attached script (drivers.ps1). To use the script you can either specify a single hostname and the script will report on driver information for that host.
.\Drivers.ps1 ParentDC1
Or, you can include two hostnames and the script will show you a difference in drivers installed on the systems.
.\Drivers.ps1 MNTools1 MNTools2
Or, you can include two hostnames with the –versions switch to only report differences in driver versions (a driver installed on both systems, of a different version).
.\Drivers.ps1 ParentDC1 ParentDC2 -versions
Finally, you could pass the script two hostnames with the –both switch to report both driver differences and driver version differences. Note that the script will report if no differences are found.
.\Drivers.ps1 ParentDC1 ChildDC2 –both
I hope you enjoy the script. Remember all the usual caveats apply to the script, so use it at your own risk. I hope you now have some tools to keep your cluster nodes more closely configured with respect to hotfixes, services and drivers.
Disclaimer
The sample scripts are not supported under any Microsoft standard support program or service. The sample scripts are provided AS IS without warranty of any kind. Microsoft further disclaims all implied warranties including, without limitation, any implied warranties of merchantability or of fitness for a particular purpose. The entire risk arising out of the use or performance of the sample scripts and documentation remains with you. In no event shall Microsoft, its authors, or anyone else involved in the creation, production, or delivery of the scripts be liable for any damages whatsoever (including, without limitation, damages for loss of business profits, business interruption, loss of business information, or other pecuniary loss) arising out of the use of or inability to use the sample scripts or documentation, even if Microsoft has been advised of the possibility of such damages.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.