Friday, May 22, 2009

PowerShell Script to get Exchange Version, Build and Rollup

It's not easy to tell which version and build is installed on Exchange 2007.

I wanted to find a way to display the Exchange version, build number and which Update Rollup is installed on all servers in the organization. I found the perfect script written by Paul Faherty to do just that. I modified the script slightly to work better in Exchange 2003 / 2007 mixed environments.

Download Get-ExchangeServerVersion.ps1 here: Get-ExchangeServerVersion.zip

When you run it from the Exchange Management Shell prompt you will see output similar to the following screen:

The output displays the server name, Exchange roles installed, version (Standard or Enterprise), version number, and the Update Rollups installed and their installation dates.

For you code monkeys, here's the Powershell code:

#Get-ExchangeServerPlus.ps1
#v1.1, 05/20/2009
#Written By Paul Flaherty, blogs.flaphead.com
#Modified by Jeff Guillet, www.expta.com

#Get a list of Exchange servers in the Org excluding Edge servers
$MsxServers = Get-ExchangeServer where {$_.ServerRole -ne "Edge"} sort Name
#Loop through each Exchange server that is found
ForEach ($MsxServer in $MsxServers)
{
#Get Exchange server version
$MsxVersion = $MsxServer.ExchangeVersion
#Create "header" string for output
# Servername [Role] [Edition] Version Number
$txt1 = $MsxServer.Name + " [" + $MsxServer.ServerRole + "] [" + $MsxServer.Edition + "] " + $MsxVersion.ExchangeBuild.toString()
write-host $txt1
#Connect to the Server's remote registry and enumerate all subkeys listed under "Patches"
$Srv = $MsxServer.Name
$key = "SOFTWARE\Microsoft\Windows\CurrentVersion\Installer\UserData\S-1-5-18\Products\461C2B4266EDEF444B864AD6D9E5B613\Patches\"
$type = [Microsoft.Win32.RegistryHive]::LocalMachine
$regKey = [Microsoft.Win32.RegistryKey]::OpenRemoteBaseKey($type, $Srv)
$regKey = $regKey.OpenSubKey($key)
#Loop each of the subkeys (Patches) and gather the Installed date and Displayname of the Exchange 2007 patch
$ErrorActionPreference = "SilentlyContinue"
ForEach($sub in $regKey.GetSubKeyNames())
{
Write-Host "- " -nonewline
$SUBkey = $key + $Sub
$SUBregKey = [Microsoft.Win32.RegistryKey]::OpenRemoteBaseKey($type, $Srv)
$SUBregKey = $SUBregKey.OpenSubKey($SUBkey)
ForEach($SubX in $SUBRegkey.GetValueNames())
{
# Display Installed date and Displayname of the Exchange 2007 patch
IF ($Subx -eq "Installed") {
$d = $SUBRegkey.GetValue($SubX)
$d = $d.substring(4,2) + "/" + $d.substring(4,2) + "/" + $d.substring(0,4)
write-Host $d -NoNewLine
}
IF ($Subx -eq "DisplayName") {write-Host ": "$SUBRegkey.GetValue($SubX)}
}
}
write-host ""
}

11 comments:

Shay Levy said...

How about one line of code :-)

PS > Get-ExchangeServer | Format-List Name,ServerRole,Edition,ExchangeVersion

Jeff said...

Thanks, Shay, but that only gives you the Exchange version number.

The code above tells you the Exchange version number, build number, which Update Rollup versions are installed and when they were installed. This is the only way I've found to determine which UR is installed.

Shay Levy said...

Thanks for a great script. I didn't notice the RU info. I ran the script on a VM with no RUs applied.

Anonymous said...

There is a bug in the installed date string.. should be
$d = $d.substring(4,2) + "/" + $d.substring(6,2) + "/" + $d.substring(0,4)

(originally there were 2 references to substring(4,2)

Jeff said...

Good catch, thanks!

Anonymous said...

Why do I get this error?

The term 'Get-ExchangeServer' is not recognized as a cmdlet, function, operable
program, or script file. Verify the term and try again.
At C:\Get-ExchangeServerVersion.ps1:8 char:33

Jeff said...

Anonymous: Chances are you're running the script from a PowerShell prompt, instead of the Exchange Management Shell. Run the script from EMS and it should work.

Anonymous said...

Ok. Just one question.. I don't have any Exchange 2007 in my env. Will the 'Microsoft Exchange Server 2007 Management Tools (32-Bit)' work in my Exch 2003 env?

Jeff said...

Hmmm. It should, but I haven't tried it. If you do, let me know how it goes.

Shahid said...

The script works gr8 but how to get the output in CSV file.

Anonymous said...

To get the script to output to a txt file just add | out-file -filepath c:\FILENAME.txt

Post a Comment

Thank you for your comment! It is my hope that you find the information here useful. Let others know if this post helped you out, or if you have a comment or further information.