Я ранее уже рассказывал об инвентаризации серверов Exchange в организации. Данный скрипт отображал список серверов Exchange с установленными на них Rollup Update.
Один из моих коллег нашел прекрасный скрипт, делающий аудит инфраструктуры Exchange и отображающий просто МОРЕ информации:
- список серверов с апдейтами, ролями, версиями ОС и сервиспаками (причем скрипт работает от Exch2003 до Exch2013);
- Список названий внутренних/внешних имен для CAS и CAS Arrays;
- Список баз с количеством ящиков, средним размером, занятым местом и количеством свободного места в %.
Мы настроили этот скрипт на ежедневный запуск, сделали вывод результатов на корпоративный веб-сервер и долго наслаждались.
Однако затем пришел ОН — Exchange 2013 и наступила тишина…
Новых серверов в отчете не было.
Немного поразбиравшись с текстом скрипта, я нашел несколько «косяков», которые доработал и предлагаю на суд общественности.
1) Отсутствие в отчете серверов и других объектов Exchange 2013 объяснялось просто — скрипт запускался с Exchange 2010. Соответственно, запускаем скрипт с самой новой версии Exchange.
2) В теле скрипта зашита проверка того, запускается он из обычного PowerSHell или EMS (Exchange Management Shell).
# 1.1 Check Exchange Management Shell, attempt to load
if (!(Get-Command Get-ExchangeServer -ErrorAction SilentlyContinue))
{
if (Test-Path "C:\Program Files\Microsoft\Exchange Server\V14\bin\RemoteExchange.ps1")
{
. 'C:\Program Files\Microsoft\Exchange Server\V14\bin\RemoteExchange.ps1'
Connect-ExchangeServer -auto
} elseif (Test-Path "C:\Program Files\Microsoft\Exchange Server\bin\Exchange.ps1") {
Add-PSSnapIn Microsoft.Exchange.Management.PowerShell.Admin
.'C:\Program Files\Microsoft\Exchange Server\bin\Exchange.ps1'
} else {
throw "Exchange Management Shell cannot be loaded"
}
}
Если скрипт запускать из EMS, он отлично отрабатывает. Если из PowerShell на системе с Exchange 2013 — фиг. Поэтому я добавил еще один elseif-оператор, проверяющий Exch2k13.
# 1.1 Check Exchange Management Shell, attempt to load
if (!(Get-Command Get-ExchangeServer -ErrorAction SilentlyContinue))
{
if (Test-Path "C:\Program Files\Microsoft\Exchange Server\V14\bin\RemoteExchange.ps1")
{
. 'C:\Program Files\Microsoft\Exchange Server\V14\bin\RemoteExchange.ps1'
Connect-ExchangeServer -auto
} elseif (Test-Path "C:\Program Files\Microsoft\Exchange Server\bin\Exchange.ps1") {
Add-PSSnapIn Microsoft.Exchange.Management.PowerShell.Admin
.'C:\Program Files\Microsoft\Exchange Server\bin\Exchange.ps1'
} elseif (Test-Path "C:\Program Files\Microsoft\Exchange Server\V15\bin\RemoteExchange.ps1") {
Add-PSSnapin Microsoft.Exchange.Management.PowerShell.SnapIn
} else {
throw "Exchange Management Shell cannot be loaded"
}
}
3) После этого все почти работает, но в отчете слова «Exchange 2013 так и не появляется. Это связано с тем, что заполнение версии Exchange осуществляется путем сравнения версии SP/CU/UR с таблицей
# 1.5.8 Exchange Service Pack String Mapping
$ExSPLevelStrings = @{"0" = "RTM"
"1" = "SP1"
"2" = "SP2"
"3" = "SP3"
"4" = "SP4"
"CU1" = "CU1"
"CU2" = "CU2"
"CU3" = "CU3"
"CU4" = "CU4"
"CU5" = "CU5"
"SP1" = "SP1"
"SP2" = "SP2"}
Как нетрудно догадаться, сейчас есть Exchange 2013 CU7, которого в таблице нет. Исправляем таблицу, предположив, что для Exchange 2013 не будет выпущено больше CU10:
# 1.5.8 Exchange Service Pack String Mapping
$ExSPLevelStrings = @{"0" = "RTM"
"1" = "SP1"
"2" = "SP2"
"3" = "SP3"
"4" = "SP4"
"CU1" = "CU1"
"CU2" = "CU2"
"CU3" = "CU3"
"CU4" = "CU4"
"CU5" = "CU5"
"CU6" = "CU6"
"CU7" = "CU7"
"CU8" = "CU8"
"CU9" = "CU9"
"CU10" = "CU10"
"SP1" = "SP1"
"SP2" = "SP2"}
4) Вот и все. Теперь скрипт можно запустить в качестве задания, выполнив следующую строку:
powershell "c:\scripts\Get-ExchangeEnvironmentReport.ps1 -HTMLreport \\Server\Report\Exchange_BD\EXReport.html"
Андрей, пофиксено автором скрипта почти год назад:
«Update 2nd February — V1.5.8 – Exchange 2013 CU and SP support, HTTPS and CAS array names shown, initial Office 365 Hybrid support»
http://www.stevieg.org/2014/02/exchange-environment-report-v1-5-8-now-available/
Ой, извините, поспешил с комментарием и написал глупость =)
На мой взгляд такой «Exchange Service Pack String Mapping» пример хренового кода. Проще регулярным выражением исправить одиночные цифры…
Насчет хренового кода согласен.
Просто задач 100500 и учиться работе с регулярными выражениями было некогда. Да и это было бы гораздо сложнее, учитывая дальнейшую конструкцию автора по заковыриванию и выковыриванию версии Exchange :))
# 1.5.9 Populate Full Mapping using above info
$ExVersionStrings = @{}
foreach ($Major in $ExMajorVersionStrings.GetEnumerator())
{
foreach ($Minor in $ExSPLevelStrings.GetEnumerator())
{
$ExVersionStrings.Add(«$($Major.Key).$($Minor.Key)»,@{Long=»$($Major.Value.Long) $($Minor.Value)»;Short=»$($Major.Value.Short)$($Minor.Value)»})
}
}
—
$Output+=»$($ExVersionStrings[«$($Server.ExchangeMajorVersion).$($Server.ExchangeSPLevel)»].Long)»
Если поможешь, с радостью укажу тебя в соавторах 🙂
Ну на вскидку я б сделал расшифровку версии отдельной функцией.
Типа такого:
function _GetVersion
{
param($Version,$type)
$ExMajorVersionStrings = @{«6.0» = @{Long=»Exchange 2000 «;Short=»E2000»}
«6.5» = @{Long=»Exchange 2003 «;Short=»E2003»}
«8» = @{Long=»Exchange 2007 «;Short=»E2007»}
«14» = @{Long=»Exchange 2010 «;Short=»E2010»}
«15» = @{Long=»Exchange 2013 «;Short=»E2013»}
«16» = @{Long=»Exchange 2013 «;Short=»E2013»}}
if ($Version -match ‘^(.+)\.(\w+)$’)
{
$Res = $ExMajorVersionStrings[$Matches[1]].$type
switch -regex ($Matches[2])
{
«^0$» {$Res+=$(«RTM»)}
«^[1-9]$» {$Res+=»SP»+$Matches[0]}
default {$Res+=$Matches[2]}
}
$Res
}
else
{
$Version
}
}
Выкинул нафиг куски 1.5.7 — 1.5.9
Ну и в коде в районе 640 строки:
$Output+=»$(_GetVersion «$($Server.ExchangeMajorVersion).$($Server.ExchangeSPLevel)» Long)»
и в районе 1025:
# Show Column Headings based on the Exchange versions we have
$ExchangeEnvironment.TotalMailboxesByVersion.GetEnumerator()|Sort Name| %{$Output+=»$(_GetVersion $_.Key Short)»}
$ExchangeEnvironment.TotalMailboxesByVersion.GetEnumerator()|Sort Name| %{$Output+=»$(_GetVersion $_.Key Short)»}
Тогда при неопознанных версиях инфа все-равно будет показана…