MCS UK Unified Communications Blog

All things UC related from Microsoft Consulting Services UK : architecture, best practice, news for Exchange and Lync, both on-premise and cloud

Updated : Exchange version powershell script

Updated : Exchange version powershell script

  • Comments 5
  • Likes

Further to my blog post on April 30th, I have updated the powershell script to output in a more usable manner and also detect more information about your exchange servers…

ServerName TransportVer CASver StoreVer
SERVER1 08.01.0336.000 08.01.0336.000 Not Installed
SERVER2 08.01.0336.000 08.01.0336.000 Not Installed
SERVER3 08.01.0336.000 08.01.0336.002 Not Installed
SERVER4 08.01.0336.000 08.01.0336.002 Not Installed
SERVER5 08.01.0336.000 08.01.0336.002 Not Installed
SERVER6 08.01.0336.000 08.01.0336.002 Not Installed
SERVER7 08.01.0336.000 08.01.0336.000 Not Installed
SERVER8 08.01.0336.000 08.01.0336.000 Not Installed
SERVER9 08.01.0336.000 08.01.0336.002 Not Installed
SERVER10 08.01.0336.000 08.01.0336.002 Not Installed
SERVER11 08.01.0336.000 08.01.0336.002 Not Installed
SERVER12 08.01.0336.000 08.01.0336.002 Not Installed
SERVER13 Not Installed Not Installed 08.01.0336.000
SERVER14 08.01.0336.000 08.01.0336.002 Not Installed
SERVER15 08.01.0336.000 08.01.0336.002 Not Installed
SERVER16 08.01.0336.000 08.01.0336.002 Not Installed
SERVER17 08.01.0336.000 08.01.0336.002 Not Installed
SERVER18 Not Installed Not Installed 08.01.0336.000
SERVER19 08.01.0336.000 08.01.0336.002 Not Installed
SERVER20 08.01.0336.000 08.01.0336.002 Not Installed
SERVER21 08.01.0336.000 08.01.0336.002 Not Installed
SERVER22 08.01.0336.000 08.01.0336.002 Not Installed
SERVER23 08.01.0336.000 08.01.0336.000 Not Installed
SERVER24 08.01.0336.000 08.01.0336.000 Not Installed
SERVER25 08.01.0336.000 08.01.0336.000 Not Installed
SERVER26 08.01.0336.000 08.01.0336.000 Not Installed
SERVER27 08.01.0336.000 08.01.0336.000 Not Installed
SERVER28 08.01.0336.000 08.01.0336.000 Not Installed

Powershell Code…

$exservers = get-exchangeserver

function MakeData($server,$transportver,$casver,$storever) {

   
$data1 = $server
   
$data2 = $transportver
   
$data3 = $casver
   
$data4 = $storever

   
$out = new-object psobject
   
$out | add-member noteproperty ServerName $data1
   
$out | add-member noteproperty TransportVer $data2
   
$out | add-member noteproperty CASver $data3
   
$out | add-member noteproperty StoreVer $data4
   
write-output $out

}


foreach ($server in $exservers)
{

   
#
   
# We need to test for three occurrences here
   
#

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

   
if ($reply.status -ne "success")
   
{
       
#
       
# Sometimes if the server is distant the first ping fails
       
# this is just a last chance to see if its really down...
       
#
       
$reply = $ping.send("$server")
       
$reply = $ping.send("$server")
   
}
    
   
$ipaddress = $reply.address

   
if ($reply.status -eq "success")
   
{

    
       
#
       
# Check Store Version
       
#
        
       
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
       
}
       
else
       
{
           
$storever = "Not Installed"
       
}

       
#
       
# Check Transport Version
       
#
        
        
       
if (Test-Path -path "\\$ipaddress\c$\program files\microsoft\exchange server\TransportRoles\data")
       
{
        
           
$transportver = [System.Diagnostics.FileVersionInfo]::GetVersionInfo("\\$ipaddress\c$\program files\microsoft\exchange server\bin\EdgeTransport.exe").Fileversion
       
}
       
else
       
{
           
$transportver = "Not Installed"
       
}

       
#
       
# Check Client Access Version
       
#
        
        
       
if (Test-Path -path "\\$ipaddress\c$\Program Files\Microsoft\Exchange Server\ClientAccess\Owa\Bin\Microsoft.Exchange.Clients.Owa.dll")
       
{
        
           
$casver = [System.Diagnostics.FileVersionInfo]::GetVersionInfo("\\$ipaddress\c$\Program Files\Microsoft\Exchange Server\ClientAccess\Owa\Bin\Microsoft.Exchange.Clients.Owa.dll").Fileversion
       
}
       
else
       
{
           
$casver = "Not Installed"
       
}

       
MakeData $server $transportver $casver $storever
        
   
}
   
else
   
{
    
   
$transportver = "down"
   
$casver = "down"
   
$storever = "down"
    
   
MakeData $server $transportver $casver $storever

   
}
}

Posted by Neil Johnson, MCS UK, MCM Exchange 2007

Comments
  • Hey, I am trying to adapt your original code to check for a specified file on a network share. So, far, i cannot get it to set the property correctly for the host, therefore, it always comes back else, mind taking a look at it?(See Below)

    PS:after the function is succesful, can i pipe $storever to Out-File?

    #Attempts to get a list of computer names to test

    $exservers = gc pclist.txt

    #Beginning of the function loop

    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

    #I think this is the problem, it does not resolve this path correctly

       if (Test-Path "\\$ipaddress\c$\Program Files\Microsoft Office\Office12\WINWORD.EXE)"

       {

           $storever = Get-FileVersionInfo("\\$ipaddress\c$\Program Files\Microsoft Office\Office12\WINWORD.EXE").Fileversion

           write-host -f yellow $storever

       }

       else

       {

           write-host -f red "Unable to Find Store.exe"

       }

    }

  • Looks like the parenthesis are in the wrong place, try this...

    if (Test-Path "\\$ipaddress\c$\Program Files\Microsoft Office\Office12\WINWORD.EXE")

    Neil.

  • I have to admit, you sure went all out on this script!  It seems to me that it was an awful lot of work though, without a lot of gain.  One can gain all relevant build information using a one-liner.  Here is the output one can get (per exchange server) from a simple line of code:

    Name                : XYZSVEHT12

    ServerRole          : HubTransport

    Edition             : Enterprise

    AdminDisplayVersion : Version 8.1 (Build 240.6)

    ExchangeVersion     : 0.1 (8.0.535.0)

    Note the edition is Enterprise, validated by the Exchange Version field-8.0.535.0. That was Exch 2007 Enterprise RTM.  The admin display version informs you that you have SP1 applied, hence 8.1., as well as the specific build.  SP2 is version 8.2., and so forth...

    Make sure you have adequate permissions, and run the following line of PowerShell code from an admin workstation.  If you have a cluster, as I do, it will report on the active nodes. It will then cycle through all Exchange Servers in your organization, if your permission level allows it:

    Get-ExchangeServer | fl name,serverrole,edition,admindisplayversion,exchangeversion

    You can also run the code below to get a count of all your Exchange boxes.

    (get-exchangeserver).count

    So, save yourself trouble by running as little code as possible!  That's my motto and I'm stickin' to it.

    gb

    Austin TX, USA

  • I suspect you missed the point of the script, but its nice to see you learning and enjoying Exchange Powershell!.

    The script was put together to determine exactly which build of each component was running on each server.  What you will find is that although a servicepack will iterate the AdminDisplayVersion an RU, IU or QFE patch will not.  More importantly sometimes an IU will only update one component such as OWA or STORE.  So if you were deploying an RU or IU to a large global environment it becomes a challenge to quickly validate which servers have it succesfully installed and which dont.  Most organisations have a form of deployment tracking, however I liked the ability to be able to validate the patch deployments throughout an Exchange organisation totally independently of any other system.

    Its a great example of how flexible powershell is though, if all you need to know is which major version and SP your servers are running get-exchangeserver does a great job.  Is just a shame it doesent return RU update details as well...

    Neil.

  • I think I did miss the point, and for that I apologize.  If one is looking for output that has detailed RU info like:

    XYZSVECA01 [ClientAccess] [Enterprise] 8.0.535.0

    - 04/04/2008:  Update Rollup 1 for Exchange Server 2007 Service Pack 1 (KB945684) 8.1.263.1

    - 08/08/2009:  Update Rollup 9 for Exchange Server 2007 Service Pack 1 (KB970162) 8.1.393.1

    - 05/05/2009:  Update Rollup 7 for Exchange Server 2007 Service Pack 1 (KB960384) 8.1.359.2

    - 05/05/2008:  Update Rollup 2 for Exchange Server 2007 Service Pack 1 (KB948016) 8.1.278.2

    XYZSVECA02 [ClientAccess] [Enterprise] 8.0.535.0

    - 04/04/2008:  Update Rollup 1 for Exchange Server 2007 Service Pack 1 (KB945684) 8.1.263.1

    - 05/05/2009:  Update Rollup 7 for Exchange Server 2007 Service Pack 1 (KB960384) 8.1.359.2

    - 05/05/2008:  Update Rollup 2 for Exchange Server 2007 Service Pack 1 (KB948016) 8.1.278.2

    ...then I believe this is the detail you were looking for. Notice you get the server name, role, build number, date RU applied, RU version and KB number. I have to give credit to Paul Flaherty at blogs.flaphead.com and Jeff Guillet at www.expta.com for compiling the script...

    It works flawlessly in my organization. It is called get-exchangeserverplus.ps1.  I will post it here with your permission.

    Neil, I do commend you for a fantastically brilliant script. As with any script, there are 100 ways to do things.  So do not think I think badly of your efforts.  Quite the contrary sir!

    For the novice who reads this, I was never able to script well in VB.  I just didn't ever have the time to invest in learning it. PowerShell however is easy to learn, and playing with it has proven to be fun. I consider myself a newbie to PowerShell, and simply using the cmdlets has been cool, as each one gives you results.  Writing an actual script was a huge event for me!!

    Keep up the good work and I look forward to more software packages becoming PowerShell ready, especially SharePoint and Citrix.

    gb

    Austin, TX USA

Your comment has been posted.   Close
Thank you, your comment requires moderation so it may take a while to appear.   Close
Leave a Comment