Welcome to TechNet Blogs Sign in | Join | Help

Syndication

News

Locations of visitors to this page These postings are provided "AS IS" without warranty, and confer no rights.
Check that driver file versions match on all your cluster nodes via Powershell


This is more of a proof of concept, but I've used it with success internally.  Take it and do with it what you want.  Many thx to Brandon who did the "heavy lifting" when I got stuck!

Overview:

Ever run into cluster issues and wanted to see if the driver file versions matched on all the nodes of the cluster to rule out a mismatch on a driver level?  Well I did!  The basic gist is that you can show all the file versions for each node by just running the script against a node name.  If you want to see only the drivers that don’t match then you’d use the pipeline with where-object (?).

Typical output:

When All drivers match:
PS C:\Debuggers> Test-MSCluster.ps1 ServerSQL11 | ?{!$_.IsSame}
Getting Nodes via WMI
Getting the drivers on: ServerSQL11
Getting the file versions for the drivers on: ServerSQL11
Getting the drivers on: ServerSQL12
Getting the file versions for the drivers on: ServerSQL12
PS C:\Debuggers>

One Mismatch:
PS C:\Debuggers> Test-MSCluster.ps1 ServerAX | ?{!$_.IsSame}
Getting Nodes via WMI
Getting the drivers on: ServerAX
Getting the file versions for the drivers on: ServerAX
Getting the drivers on: ServerBX
Getting the file versions for the drivers on: ServerBX

FileName                                                                   ServerAX                                                                 ServerBX
--------                                                                   ----------                                                                 ----------
rmcast.sys                                                                 6.0.6001.18000                                                             6.0.6001.18069


Many nodes, many mismatches:

PS C:\Debuggers> Test-MSCluster.ps1 Server-Clus--11 | ?{!$_.IsSame} 
Getting Nodes via WMI
Getting the drivers on: Server-Clus--10
Getting the file versions for the drivers on: Server-Clus--10
Getting the drivers on: Server-Clus--11
Getting the file versions for the drivers on: Server-Clus--11
Getting the drivers on: Server-Clus--15
Getting the file versions for the drivers on: Server-Clus--15
Getting the drivers on: Server-Clus--16
Getting the file versions for the drivers on: Server-Clus--16
Getting the drivers on: Server-Clus--13
Getting the file versions for the drivers on: Server-Clus--13
Getting the drivers on: Server-Clus--12
Getting the file versions for the drivers on: Server-Clus--12

FileName   : Dbgv.sys
Server-Clus--10 : 4.60
Server-Clus--11 : FileMissing
Server-Clus--15 : FileMissing
Server-Clus--16 : FileMissing
Server-Clus--13 : FileMissing
Server-Clus--12 : FileMissing
IsSame     : False

FileName   : HpCISSs2.sys
Server-Clus--10 : FileMissing
Server-Clus--11 : FileMissing
Server-Clus--15 : FileMissing
Server-Clus--16 : 6.8.0.64 Build 9 (x86-64)
Server-Clus--13 : 6.8.0.64 Build 9 (x86-64)
Server-Clus--12 : 6.8.0.64 Build 9 (x86-64)
IsSame     : False

FileName   : USBSTOR.SYS
Server-Clus--10 : FileMissing
Server-Clus--11 : FileMissing
Server-Clus--15 : FileMissing
Server-Clus--16 : FileMissing
Server-Clus--13 : 6.0.6001.18000
Server-Clus--12 : 6.0.6001.18000
IsSame     : False

FileName   : mrxsmb10.sys
Server-Clus--10 : 6.0.6001.18000
Server-Clus--11 : 6.0.6001.18000
Server-Clus--15 : 6.0.6001.18000
Server-Clus--16 : 6.0.6001.18068
Server-Clus--13 : 6.0.6001.18000
Server-Clus--12 : 6.0.6001.18000
IsSame     : False

FileName   : nm3.sys
Server-Clus--10 : 03.02.0764.0001
Server-Clus--11 : FileMissing
Server-Clus--15 : FileMissing
Server-Clus--16 : FileMissing
Server-Clus--13 : FileMissing
Server-Clus--12 : FileMissing
IsSame     : False

Code:
 
 
######################################################################
#Test-MSCluster.ps1
Param($ClusterNode)

# I am using this hashtable to store a unique list of file names. 
$Files = @{}
# I am using this array to store my custom objects we create later.
$FileObjects = @()

Write-Host "Getting Nodes via WMI"
$nodes = gwmi -q "Select name from MSCluster_Node" -namespace root\mscluster -computername $ClusterNode -Authentication PacketPrivacy | %{$_.Name}

# Here we process each node and get all the drivers from the node and add it to our $Files HashTable to be processed
foreach ( $node in $nodes )
{
    Write-Host "Getting the drivers on:"  $node
    # Here we are getting a list of the .sys files. Notice I am only getting the names
    $filelistFinal = get-childitem "\\$node\admin$\system32\drivers" *.sys | %{$_.name}
    
    Write-Host "Getting the file versions for the drivers on:" $node
    foreach($file in $filelistFinal)
    {
        # foreach file found we add it to the hasttable, but hashtables can only have a key once
        # so we need check if the key already exist. I do this because it is possible you could have
        # unique drivers per node.
        if(!$Files.$file)
        {
            $Files.Add($file,"added")
        }
    }
}

# Ok... now we have all our files time to process the hashtable and create our custom objects
foreach($FileName in $Files.Keys)
{
    # This is how I create an object for each file
    $myFileObj = New-Object System.Object
    
    # This is how we add a property. In this case the FileName property. For these scenarios I chose add-member
    # because you can dynamically add properties (i.e. NodeName with value of File version)
    $myFileobj | add-Member -MemberType NoteProperty -Name FileName -Value $FileName
    
    # Now we need to add properties for each node.
    foreach($node in $nodes)
    {
        # Making sure the file exist on the node
        if(Test-Path \\$node\admin$\system32\drivers\$FileName)
        {
            # Getting ProductVersion Info to use as the value for the Node Property
            $fileInfo = [system.diagnostics.fileversioninfo]::getversioninfo("\\$node\admin$\system32\drivers\$FileName")
            $myFileobj | add-Member -MemberType NoteProperty -Name $node -Value $FileInfo.ProductVersion
        }
        else
        {
            # File not found using FileMissing as the value for the Node Property
            $myFileobj | add-Member -MemberType NoteProperty -Name $node -Value "FileMissing"
        }
    }
    # Outputting Object
    $FileObjects += $myFileObj
}

foreach($result in $FileObjects)
{
    $isSame = $true
    # Getting Server Name from Properties of the custom object
    $servers = $result | Get-Member -MemberType Noteproperty | ?{$_.Name -ne "FileName"} | %{$_.Name}
    
    # Checking the value of each server vs the other servers
    foreach($server in $servers)
    {
        foreach($srv in $servers)
        {
            if($srv -ne $server)
            {
                # If the the value is different we set $isSame to $false
                if($result."$srv" -ne $result."$server"){$isSame = $false}
            }
        }
    }
    # add the isSame property to the object
    $result | add-Member -MemberType NoteProperty -Name IsSame -value $isSame
    
    # output object
    $result 
}
######################################################################

 

***Note:  This script is not fast, as it is getting the file versions for every driver (*.sys)  on each system,  I'd highly suggest not running this over the WAN...

Published Wednesday, December 03, 2008 11:25 PM by Brad Rutkowski

Comment Notification

If you would like to receive an email when updates are made to this post, please register here

Subscribe to this post's comments using RSS

Comments

# file server | Digg hot tags @ Wednesday, December 03, 2008 9:07 PM

PingBack from http://diggwow.info/tags/109/200812/file-server.html

file server | Digg hot tags

# re: Check that driver file versions match on all your cluster nodes via Powershell @ Wednesday, December 10, 2008 1:23 PM

Nice one.  Will be covering on the next PowerScripting Podcast.

Hal Rottenberg [MVP]

# re: Check that driver file versions match on all your cluster nodes via Powershell @ Tuesday, January 27, 2009 12:34 PM

I get this error on Exchange 2007 64bits cluster

[PS] D:\Scripts>.\Test-MSCluster.ps1  SCC1 | ?{!$_.IsSame}

Getting Nodes via WMI

Get-WmiObject : A parameter cannot be found that matches parameter name 'Authentication'.

At D:\Scripts\Test-MSCluster.ps1:11 char:120

+ $nodes = gwmi -q "Select name from MSCluster_Node" -namespace root\mscluster -computername $ClusterNode -Authenticati

on  <<<< PacketPrivacy | %{$_.Name}

Getting the drivers on:

Get-ChildItem : Cannot find path '\\\admin$\system32\drivers' because it does not exist.

At D:\Scripts\Test-MSCluster.ps1:18 char:35

+     $filelistFinal = get-childitem  <<<< "\\$node\admin$\system32\drivers" *.sys | %{$_.name}

Getting the file versions for the drivers on:

Exception calling "Add" with "2" argument(s): "Key cannot be null.

Parameter name: key"

At D:\Scripts\Test-MSCluster.ps1:28 char:23

+             $Files.Add( <<<< $file,"added")

eltate

# re: Check that driver file versions match on all your cluster nodes via Powershell @ Wednesday, January 28, 2009 4:54 PM

Hey eltate, you need to be running Powershell v2.

Brad Rutkowski

# re: Check that driver file versions match on all your cluster nodes via Powershell @ Wednesday, January 28, 2009 4:57 PM

Hey elate:

The -Authentication was put into v2 to help with this issue.  You cannot use get-wmiobject in POSH v1 to connect to namespaces that require packet privacy (see my earlier post on this subject).  You'd need to use [wmisearcher] or the .NET framework and then set the authentication in there.  Sorry.  It CAN be done though, just a bit more work.

Brad Rutkowski

Leave a Comment

(required) 
required 
(required) 

  
Enter Code Here: Required
Page view tracker