How to retrieve the store.exe version from all mailbox and clustered servers in one step!?

Over the last 12 months I have had various occasions where I needed to quickly check the store.exe version installed on each mailbox server within the organisation.

Seemingly there is no way to do this directly via PowerShell or Exchange cmdlets. 

Paul Flaherty has already written a great script to determine the SP and RU version of your exchange servers.  Paul uses WMI to query the registry for installed hotfixes and Roll Up’s.  I wanted to see the physical version of store.exe that was running on each server specifically, since we had a concern about how some RU’s had been applied.

On the surface this seemed like a really easy thing to do, just grab a list of Exchange servers, then grab the fileversion info from store.exe… 

Well, yes and no.  For the standalone mailbox servers this worked great, however for all of the clusters it failed, since the get-mailboxserver cmdlet returns the CMS name and under Server 2008 Clusters,  all shares are scoped to the network name, since the admin C$ share is not part of the Exchange CMS, the cluster refuses to answer the CIFS request.  However, after some digging I came up with a workaround by using the IP address.  Since the IP address is bound to the node network interface it answers the CIFS query.

So, this is the script I came up with.  Its a basic loop, that checks the file version information on the store.exe binary on each exchange server.  I used ping to get the IP address, which works quickly and seems to give me what I wanted. 

During the writing of this blog post it occurred to me that I could also use the ping reply status ($reply.status) to test if the CMS or Mailbox server was up or down, saving some time waiting for the GetVersionInfo call to timeout, but I will leave that for another day :)

$exservers = get-mailboxserver

foreach ($server in $exservers)
{

    write-host -f green "Examining Store on $server..." -nonewline

    # To get around Cluster share scoping, we need to query via IP...
    $ping = new-object System.Net.NetworkInformation.Ping
    $reply = $ping.send($server) 
    $ipaddress = $reply.address 
   

 
    if (Test-Path -path "\\$ipaddress\c$\program files\microsoft\exchange server\bin\store.exe")
    {

        $storever = [System.Diagnostics.FileVersionInfo]::GetVersionInfo("\\$ipaddress\c$\program files\microsoft\exchange server\bin\store.exe").Fileversion
        write-host -f yellow $storever
    }
    else
    {
        write-host -f red "Unable to Find Store.exe"
    }
}

The output of the script looks as follows…

[PS] C:\build\powershell>.\getstorever.ps1
Examining Store on MBXSERVER1...08.01.0336.000
Examining Store on MBXSERVER2...08.01.0336.000
Examining Store on MBXSERVER3...08.01.0336.000
Examining Store on MBXSERVER4...08.01.0336.000
Examining Store on MBXSERVER5...08.01.0336.000
Examining Store on MBXSERVER6...08.01.0336.000
Examining Store on MBXSERVER7...08.01.0240.005
Examining Store on MBXSERVER8...08.01.0336.000

Hopefully someone else out there will find this useful – its certainly saved me a couple of hours work today.  It would be nice to change the formatting and have it output this data as a HTML table, but like the ping status, I will save that for another day…

Posted by Neil Johnson , MCS UK, MCM Exchange 2007