Задача узнать, какие накопительные обновления (Rollup Updates) установлены на ваших серверах, может оказаться сложнее, чем просто взглянуть версию в оснастке Exchange 😉
При выполнении командлета Get-ExchangeServer у нас есть два поля, давайте посмотрим на них:
Get-ExchangeServer mail01 | select *version
AdminDisplayVersion ExchangeVersion
——————- —————
Version 14.2 (Build 247.5) 0.1 (8.0.535.0)
Ну вроде все супер? Ан нет – значение параметра AdminDisplayVersion изменяется только при установке сервис пака. Поле ExchangeVersion для меня еще загадочней.
Поиск на просторах интернета выдал ссылку на постоянно пополняющуюся базу сборок Exchange 2007/2010. Вручную можно посмотреть версию сервера, зайдя в свойства файла любой службы Exchange.
Внезапно на просторах интернета мне попался скрипт на Powershell, делающие это для Exchange 2007/2010. Дело оставалось за малым: объединить их в один и чуть-чуть оптимизировать вывод.
В начале скрипта указываются актуальные версии сервис паков и накопительных обновлений для Exchange 2007/2010, в конце приводится статистика. Скрипт не инвентаризирует Edge-сервера.
$RU10="Rollup 2"
$RU07="Rollup 7"
$SP10="SP2"
$SP07="SP3"
$exservers = Get-ExchangeServer | ? {$_.ServerRole -notlike "edge"}
$i=0
$count=$exservers.count
$Servers=1..$exservers.count | %{
$RU=" "
$Version="Exchange "
if($exservers[$i].admindisplayversion.major -eq 14)
{$version+="2010 SP"
$regKey = "SOFTWARE\Microsoft\Windows\CurrentVersion\Installer\UserData\S-1-5-18\Products\AE1D439464EB1B8488741FFA028E291C\Patches\"
}
else
{$version+="2007 SP"
$regKey = "SOFTWARE\Microsoft\Windows\CurrentVersion\Installer\UserData\S-1-5-18\Products\461C2B4266EDEF444B864AD6D9E5B613\Patches\"
}
$version+=$exservers[$i].admindisplayversion.minor
$baseKey = [Microsoft.Win32.RegistryKey]::OpenRemoteBaseKey(’LocalMachine’, $exservers[$i])
$baseKey = $baseKey.OpenSubKey($regKey)
$Updates = $baseKey.GetSubKeyNames()
$arr_upd= New-Object -comObject System.Collections.ArrayList
ForEach($Update in $Updates)
{$fullPath= $regKey + $Update
$UpdateKey = [Microsoft.Win32.RegistryKey]::OpenRemoteBaseKey(’LocalMachine’, $exservers[$i])
$UpdateKey = $UpdateKey.OpenSubKey($fullPath)
$values = $UpdateKey.GetValueNames()
ForEach($value in $values)
{if ($value -eq "DisplayName")
{[void]$arr_upd.Add($UpdateKey.GetValue($value))}
}
}
$RU=$arr_upd | sort desc | select -first 1
$RU= ($RU).substring(7,9)
$obj = New-Object psobject
$obj | Add-Member -type noteproperty -name Name -Value $exservers[$i].Name
$obj | Add-Member -type noteproperty -name Roles -Value $exservers[$i].Serverrole
$obj | Add-Member -type noteproperty -name Edition -Value $exservers[$i].Edition
$obj | Add-Member -type noteproperty -name Version -Value $version
$obj | Add-Member -type noteproperty -name Rollup -Value $RU
$obj
$i=$i+1
}
$Servers | sort name | ft -autosize
$final="Всего - $count"+" серверов, из них не обновлено"
$old07=0
$old10=0
$servers | %{
if(($_.version -match "2010")-and(!($_.rollup -eq $RU10)-or(!($_.version -like "*$SP10")))){$old10+=1}
if(($_.version -match "2007")-and(!($_.rollup -eq $RU07)-or(!($_.version -like "*$SP07")))){$old07+=1}
}
$final+=" $old10 серверов с Exchange 2010 и "+"$old07 серверов с Exchange 2007"
$final
Вывод скрипта выглядит примерно так:
Name Roles Edition Version Rollup
---- ----- ------- ------- ------
Mail01 Mailbox Enterprise Exchange 2007 SP3 Rollup 5
Hub01 ClientAccess, HubTransport Enterprise Exchange 2007 SP3 Rollup 5
Hub02 ClientAccess, HubTransport Enterprise Exchange 2007 SP3 Rollup 5
Mail02 Mailbox Enterprise Exchange 2010 SP2
Mail03 Mailbox Enterprise Exchange 2010 SP2
Hub03 ClientAccess, HubTransport Standard Exchange 2010 SP2
Всего – 6 серверов, из них не обновлено 3 cерверов с Exchange 2010 и 3 серверов с Exchange 2007.
P.S. CCR-кластер с Exchange 2007 будет видеться как один сервер.
P.P.S. Пока гуглил, нашел еще один вариант скрипта для смешанной инфраструктуры.
Опытным путем выяснено, что скрипт не всегда адекватно отрабатывает, поэтому определение переменной $RU необходимо указывать в следующем виде:
$RU=$arr_upd | sort desc | select -first 1
$RU= ($RU).substring(7,9)
Текущий листинг скрипта я уже поправил.