Инвентаризация ВСЕХ серверов Exchange в организации

Я ранее уже рассказывал об инвентаризации серверов 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"

4 thoughts on “Инвентаризация ВСЕХ серверов Exchange в организации”

  1. Ой, извините, поспешил с комментарием и написал глупость =)
    На мой взгляд такой “Exchange Service Pack String Mapping” пример хренового кода. Проще регулярным выражением исправить одиночные цифры…

  2. Насчет хренового кода согласен.
    Просто задач 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)”
    Если поможешь, с радостью укажу тебя в соавторах 🙂

  3. Ну на вскидку я б сделал расшифровку версии отдельной функцией.
    Типа такого:
    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)”}

    Тогда при неопознанных версиях инфа все-равно будет показана…

Leave a Reply

Your email address will not be published. Required fields are marked *