Created
November 29, 2016 20:11
-
-
Save tostka/18b1b5ce1965b522ab62fab5bb9d567b to your computer and use it in GitHub Desktop.
Tweaked variant of Bhargav Shukla's script that polls all Exchange 2007/2010/2013 boxes in the org, and reports on current Exch patch revision
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Get-ExchangeUpdateRollups.ps1 - Gets the Exchange Server 2007, Exchange 2010 and Exchange 2013 Update Rollups | |
<# | |
.SYNOPSIS | |
Get-ExchangeUpdateRollups.ps1 - Gets the Exchange Server 2007, Exchange 2010 and Exchange 2013 Update Rollups | |
.NOTES | |
Written By: Bhargav Shukla | |
Website: http://www.bhargavs.com | |
Revised By: Todd Kadrie | |
Website: http://tinstoys.blogspot.com | |
Twitter: http://twitter.com/tostka | |
Change Log | |
* 8:55 AM 11/29/2016 TSK: add name sort (make them output into a rational order) | |
* 8:54 AM 11/29/2016 TSK: fixed typo in $ofile gen | |
* 8:52 AM 11/29/2016 TSK: added Ex Org, progress verbose outputs | |
* 8:23 AM 11/29/2016 TSK: added/reformated comments into pshelp, | |
ren chg rpt file results.csv => $ofile (scriptname-report-timestamped.csv) | |
added $ofile invoke item, reformated to OTB, | |
* Posted version:"UPDATED: Feb 26, 2014, updated script to accommodate Exchange 2013 | |
The script was not written to accommodate Exchange 2013 as it doesnÆt use RU. | |
It uses different servicing model. I have updated script to work with 2013 but | |
it wonÆt report CU, it will provide build numbers that can be matched to CUs | |
published on TechNet. Links are included in the script." | |
.DESCRIPTION | |
Get-ExchangeUpdateRollups.ps1 | |
# Gets the Exchange Server 2007, Exchange 2010 and Exchange 2013 Update Rollups | |
# installed writes output to CSV file in same folder where script is called from | |
# | |
# Exchange 2013 CU Build Numbers - http://social.technet.microsoft.com/wiki/contents/articles/15776.exchange-server-2013-and-cumulative-updates-cus-build-numbers.aspx | |
# Exchange Server Update Rollups and Build Numbers - http://social.technet.microsoft.com/wiki/contents/articles/240.exchange-server-and-update-rollups-build-numbers.aspx | |
# | |
# This script won't report RUs for Exchange Server 2013 since it uses Cummulative Updates (CU). | |
# More details on Exchange Team Blog: Servicing Exchange 2013 | |
# http://blogs.technet.com/b/exchange/archive/2013/02/08/servicing-exchange-2013.aspx | |
DISCLAIMER | |
# ========== | |
# THIS CODE IS MADE AVAILABLE AS IS, WITHOUT WARRANTY OF ANY KIND. THE ENTIRE | |
# RISK OF THE USE OR THE RESULTS FROM THE USE OF THIS CODE REMAINS WITH THE USER. | |
.INPUTS | |
None. Does not accepted piped input. | |
.OUTPUTS | |
Outputs a csv file in the scripts subdir of the | |
.EXAMPLE | |
.\get-ExchangeUpdateRollups.ps1 | |
Default run against all Ex07|10|13 servers in the Org | |
.LINK | |
http://www.bhargavs.com/index.php/2009/12/14/how-do-i-check-update-rollup-version-on-exchange-20xx-server/ | |
#> | |
# 8:32 AM 11/29/2016 add simple code for report based on scriptname | |
$ScriptDir=(Split-Path -parent $MyInvocation.MyCommand.Definition) + "\" ; | |
$ScriptNameNoExt = [system.io.path]::GetFilenameWithoutExtension($MyInvocation.InvocationName) ; | |
$ofile = (join-path -path $ScriptDir -childpath "logs") ; | |
if(!(test-path -path $ofile)){write-verbose -verbose:$true "$((get-date).ToString("HH:mm:ss")):Creating missing logs dir $($ofile)" ; mkdir -path $ofile -force ; } ; | |
$ofile+="\$($ScriptNameNoExt)-$(get-date -uformat "%Y%m%d-%H%M")-Report.csv" ; | |
write-verbose -verbose:$true "$((get-date).ToString("HH:mm:ss")):`ofile:$($ofile)" ; | |
# Store header in variable | |
$headerLine = | |
@" | |
Exchange 2013 CU Build Numbers - http://social.technet.microsoft.com/wiki/contents/articles/15776.exchange-server-2013-and-cumulative-updates-cus-build-numbers.aspx | |
Exchange Server Update Rollups and Build Numbers - http://social.technet.microsoft.com/wiki/contents/articles/240.exchange-server-and-update-rollups-build-numbers.aspx | |
Server Name,Rollup Update Description,Installed Date,ExSetup File Version | |
"@ | |
# Write header to file | |
#$headerLine | Out-File .\results.csv -Encoding ASCII -Append | |
# 9:06 AM 11/29/2016 update to $ofile | |
$headerLine | Out-File -filepath $ofile -Encoding ASCII -Append ; | |
#*------v Function getRU v------ | |
function getRU([string]$Server) { | |
# Set server to connect to | |
$Server = $Server.ToUpper() | |
# Check if server is running Exchange 2007 or Exchange 2010 | |
$ExchVer = (Get-ExchangeServer $Server | ForEach {$_.AdminDisplayVersion}) | |
$sMsg=$Server ; | |
# Set appropriate base path to read Registry | |
# Exit function if server is not running Exchange 2007 or Exchange 2010 | |
# 8:49 AM 11/29/2016 added version echo - this runs awhile with no progress/status updates | |
if ($ExchVer -match "Version 15") { | |
$sMsg+="(Exch2013)" ; | |
$REG_KEY = "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\S-1-5-18\\Products\\AE1D439464EB1B8488741FFA028E291C\\Patches" | |
$Reg_ExSetup = "SOFTWARE\\Microsoft\\ExchangeServer\\v15\\Setup" | |
} elseif ($ExchVer -match "Version 14") { | |
$sMsg+="(Exch2010)" ; | |
$REG_KEY = "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\S-1-5-18\\Products\\AE1D439464EB1B8488741FFA028E291C\\Patches" | |
$Reg_ExSetup = "SOFTWARE\\Microsoft\\ExchangeServer\\v14\\Setup" | |
} elseif ($ExchVer -match "Version 8") { | |
$sMsg+="(Exch2007)" ; | |
$REG_KEY = "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\S-1-5-18\\Products\\461C2B4266EDEF444B864AD6D9E5B613\\Patches" | |
$Reg_ExSetup = "SOFTWARE\\Microsoft\\Exchange\\Setup" | |
} else { | |
return | |
} | |
# 8:48 AM 11/29/2016 add progress echo | |
write-verbose -verbose:$true "$((get-date).ToString("HH:mm:ss")):Processing Server $($sMsg)..." ; | |
# Read Rollup Update information from servers | |
# Set Registry constants | |
$VALUE1 = "DisplayName" | |
$VALUE2 = "Installed" | |
$VALUE3 = "MsiInstallPath" | |
# Open remote registry | |
$reg = [Microsoft.Win32.RegistryKey]::OpenRemoteBaseKey('LocalMachine', $Server) | |
# Set regKey for MsiInstallPath | |
$regKey= $reg.OpenSubKey($REG_ExSetup) | |
# Get Install Path from Registry and replace : with $ | |
$installPath = ($regkey.getvalue($VALUE3) | foreach {$_ -replace (":","`$")}) | |
# Set ExSetup.exe path | |
$binFile = "Bin\ExSetup.exe" | |
# Get ExSetup.exe file version | |
$exSetupVer = ((Get-Command "\\$Server\$installPath$binFile").FileVersionInfo | ForEach {$_.FileVersion}) | |
# Create an array of patch subkeys | |
$regKey= $reg.OpenSubKey($REG_KEY).GetSubKeyNames() | ForEach {"$Reg_Key\\$_"} | |
# Walk through patch subkeys and store Rollup Update Description and Installed Date in array variables | |
$dispName = [array] ($regkey | %{$reg.OpenSubKey($_).getvalue($VALUE1)}) | |
$instDate = [array] ($regkey | %{$reg.OpenSubKey($_).getvalue($VALUE2)}) | |
# Loop Through array variables and output to a file | |
$countmembers = 0 | |
if ($regkey -ne $null) { | |
while ($countmembers -lt $dispName.Count){ | |
#$server+","+$dispName[$countmembers]+","+$instDate[$countmembers].substring(0,4)+"/"+$instDate[$countmembers].substring(4,2)+"/"+$instDate[$countmembers].substring(6,2)+","+$exsetupver | | |
# Out-File .\results.csv -Encoding ASCII -Append | |
# 8:40 AM 11/29/2016 shift to report from scriptname | |
$server+","+$dispName[$countmembers]+","+$instDate[$countmembers].substring(0,4)+"/"+$instDate[$countmembers].substring(4,2)+"/"+$instDate[$countmembers].substring(6,2)+","+$exsetupver | | |
Out-File -filepath $ofile -Encoding ASCII -Append | |
$countmembers++ | |
} ; | |
} else { | |
#$server+",No Rollup Updates are installed,,"+$exsetupver | Out-File .\results.csv -Encoding ASCII -Append | |
# 8:40 AM 11/29/2016 shift to report from scriptname | |
$server+",No Rollup Updates are installed,,"+$exsetupver | Out-File -filepath $ofile -Encoding ASCII -Append | |
} | |
} #*------^ END Function getRU ^------ | |
# Get Exchange 2007/2010 servers and write Rollup Updates to results file | |
# 8:51 AM 11/29/2016 add org Name | |
$exOrg=(get-organizationconfig).Name ; | |
write-verbose -verbose:$true "$((get-date).ToString("HH:mm:ss")):Collecting Exchange Servers in Org:$($exOrg)..." ; | |
#$Servers = (Get-ExchangeServer | Where-Object {($_.AdminDisplayVersion -match "Version 8" -OR $_.AdminDisplayVersion -match "Version 14" -OR $_.AdminDisplayVersion -match "Version 15") -AND $_.ServerRole -ne "ProvisionedServer" -and $_.ServerRole -ne "Edge"} | ForEach {$_.Name}) | |
# 8:55 AM 11/29/2016 add name sort (make them output into a rational order) | |
$Servers = (Get-ExchangeServer | Where-Object {($_.AdminDisplayVersion -match "Version 8" -OR $_.AdminDisplayVersion -match "Version 14" -OR $_.AdminDisplayVersion -match "Version 15") -AND $_.ServerRole -ne "ProvisionedServer" -and $_.ServerRole -ne "Edge"} | | |
sort Name | ForEach {$_.Name}) | |
$Servers | ForEach {getRU $_} ; | |
#Write-Output "Results are stored in $(Get-Location)\results.csv" | |
# 8:40 AM 11/29/2016 shift to report from scriptname & invoke-item it | |
Write-Output "Results are stored in $($ofile)" ; | |
if(get-childitem -path $ofile){Invoke-Item -path $ofile ;} ; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment