С момента своего появления в Exchange 2007 служба автообнаружения используется в Outlook по известному заранее сценарию:

  1. Outlook пытается подключиться к AD и получить список SCP для своего сайта
  2. Если п.1 не выполнен, то идёт обращение по адресу https://<SMTP-address-domain>/autodiscover/autodiscover.xml
  3. Если п.2 не выполнен, то идёт обращение по адресу https://autodiscover.<SMTP-address-domain>/autodiscover/autodiscover.xml
  4. Если п.3 не выполнен, то идёт попытка редиректа, настроенного для http://autodiscover.<SMTP-address-domain>/autodiscover/autodiscover.xml
  5. Если п.4 не выполнен, то идёт обращение к SRV-записи _autodiscover._tcp.<SMTP-address-domain>

Этот порядок поиска службы автообнаружения на клиенте можно немного подправить. Для каждого из этих шагов доступна настройка в реестре, которая позволяет этот шаг пропустить. Подробнее тут.

Все настройки выполняются в ветке реестра HKEY_CURRENT_USER\Software\Microsoft\Office\16.0\Outlook\AutoDiscover. Доступны следующие ключи:

"ExcludeScpLookup"=dword:00000001
"ExcludeHttpsRootDomain"=dword:00000001
"ExcludeHttpsAutoDiscoverDomain"=dword:00000001
"ExcludeHttpRedirect"=dword:00000001
"ExcludeSrvRecord"=dword:00000001

Полезные ссылки:
Autodiscover for Exchange
Autodiscover service
Outlook 2016 Implementation of Autodiscover
Plan to automatically configure user accounts in Outlook 2010

Active Directory предоставляет штатный механизм изменения типа группы (Distribution ↔ Security).

В случае, если у нас имеется Exchange, этого недостаточно. Необходимо так же на стороне Exchange запустить процесс обновления типа группы. В общем то это совсем не новость, так как механизм автоматической конвертации группы распространения в группу безопасности пропал в Exchange 2007 и с тех пор назад не возвращался. Поэтому, если изменение Distribution ↔ Security было выполнено на стороне Active Directory необходимо после этого запустить следующий командлет:

Set-Distributiongroup –identity <DistributionGroupId> –MemberDepartRestriction Closed

Если этого не сделать, то все операции назначения прав доступа для новоиспечённой группы безопасности на стороне Exchange будут давать сбои: нельзя будет назначать на группу права на ящики, на группы рассылок, на календари итд. итп.

Полезные ссылки:
Modify Group Type or Group Scope
How to change a UDG to a USG in Exchange 2010
Automatic converison of UDG in USG in Exchange 2007
EXCHANGE 2010 – ADD OUTLOOK CALENDAR PERMISSIONS FOR ALL MEMBERS OF A GROUP

Достаточно давно, почти сразу после появления, я делал обзор функции онлайн-архива, которая позволяла перемещать в архивный ящик письма, старше определённого возраста. С тех пор прошло достаточно много времени. Саму функциональность переименовали в In-Place Archive. Научились работать со стандартными папками Tasks и Calendar.

Недавно столкнулся с одним странным случаем. Имеется политика хранения, которая содержит DPT для архивирования, RPT для папки Tasks и несколько пользовательских тэгов. RPT для папки Tasks настроен на бессрочное хранение задач (Never Delete), DPT переносит в архив объекты старше некоторого срока (предположим, старше одного года). Согласно документации DPT применяется только к объектам, которые не помечены другими тэгами. Поэтому, вроде бы, под действие этого тэга не должны попадать задачи (помечены RPT для папки Tasks) и все папки и письма, которые помечены пользователем с помощью пользовательских тэгов.

На самом деле это не так. Задачи из папки Tasks будут попадать под действие DPT и уезжать в архив, согласно настройкам дефолтного тэга.

Кто виноват?

Предполагаю, что дело в следующем. Известно, что весь процесс работы политик хранения построен на MAPI-аттрибутах RetentionPeriod/PR_RETENTION_PERIOD, RetentionDate/PR_RETENTION_DATE, PolicyTag/PR_POLICY_TAG, ArchivePeriod/PR_ARCHIVE_PERIOD, ArchiveDate/PR_ARCHIVE_DATE и ArchiveTag/PR_ARCHIVE_TAG. Первые три связаны с настройками политик хранения (период хранения, дата истечения хранения и применённый тэг хранения), последние три с настройками архивирования (период хранения до запуска процесса архивирования, дата истечения хранения перед перемещением в архив и применённый тэг архивирования). На основании этих аттрибутов соответствующий ассистент (робот) на почтовом сервере обрабатывает объекты в почтовом ящике. Для новых объектов согласно применённым тэгам проставляются сроки хранения и время истечения сроков хранения. Для уже помеченых объектов принимается решение нужно ли с ними что-то делать, если срок хранения истёк.

С нашим странным случаем получается забавная ситуация. Ассистент видит, что существует DPT с действием MoveToArchive. Для задач из папки Tasks архивные MAPI-аттрибуты не проставлены, так как архивирование для папок Tasks и Calendar недоступно. На основании этого ассистент принимает(моё предположение) решение, что задачи попадают под действие DPT и начинает их перемещать в архив согласно настройкам DPT.

Что делать?

MS предлагает в данной ситуации один вариант – отключить для ассистента возможность обрабатывать объекты из папок Tasks/Calendar. Делается это нашим любимым способом – через пятую точкуреестр. Нужен следующий ключ на всех почтовых серверах, где хранятся базы с ящиками пользователей:

Path: HKLM\SYSTEM\CurrentControlSet\Services\MSExchangeMailboxAssistants\Parameters
Name: ELCAssistantCalendarTaskRetentionEnabled
Type: DWORD
Value: 0 (Do not process Calendar and Task folders)

Полезные ссылки:
Retention tags and retention policies in Exchange 2016
Prevent archiving of items in a default folder in Exchange 2010
Calendar and Tasks Retention Tag Support in Exchange 2010 SP2 RU4
Retention policy on Calendar and Task folders. Confused ?
DPT with move to archive action takes precedence over RPT.
Default folders that support Retention Policy Tags
Архивирование в Exchange 2010 SP1

Обновление: как доносит народная молва это поведение появилось в Exchange 2016 CU4. При отключении ящика не очищается аттрибут legacyExchangeDN. Заведён баг.

Ситуация: сотрудник переходит из одного подразделения в другое. На предыдущем месте работы он использовал линкованый ящик. На новом месте будет использовать обычный. Вроде бы штатная операция – необходимо отключить линкованый ящик (Disconnect-Mailbox) и подключить его к новой учётной записи (Connect-Mailbox). После очистки базы (Update-StoreMailboxState) получаем рабочий OWA и нерабочий Outlook. Профиль настраивается, но при запуске Outlook возвращается ошибка, что нет доступа к дереву папок. Картинка будет примерно такая:

В логе MAPI/HTTP на бэкэнде нашлась вот такая вот интересная запись:

MoMTException:2147746065 (rpc LoginFailure) -> [LoginFailureException] Unable to access AD 
(StoreError=LoginFailure) -> [StoragePermanentException] There was a problem accessing Active 
Directory. Check your network connections and try again. -> [ValueNotPresentException] 
Property 'IsSoftDeletedByRemove' is not present on object 'Some User Mailbox'.

В общем понятно, что ничего не понятно. Однако, беглый обзор аттрибутов двух учёток (новой, и старой от линкованого ящика) позволил обнаружить, что обе учётки имеют один и тот же аттрибут legacyExchangeDN. После очистки этого аттрибута на старой учётке Outlook сразу же запустился.

Аттрибут этот очень хитрый. Внутри Exchange использует именно его для маршрутизации почты. Поэтому его задвоение как миниму приводит к невозможности нормальной работы пострадавшего почтового ящика. Как оказывается он так же участвует и в процессе аутентификации.

Полезные ссылки:
Clean-MailboxDatabase in Exchange 2013
The Attribute, the Myth, the legacyExchangeDN

На текущий момент старые серверы с ролью mailbox не выполняют полезных функций: пользовательские данные перенесены в новые почтовые базы, OAB создаётся на новых серверах и клиенты используют уже её. Настало время выводить эти старые серверы из эксплуатации. Но прежде чем запускать установщик на удаление необходимо удалить со старых серверов следующее:

  • пустые базы почтовых ящиков
  • старую OAB
  • пустые базы общих папок

Удаляем пустые базы почтовых ящиков

Если базы в DAG, то необходимо предварительно удалить все копии баз за исключением последней. Последние копии баз удаляются обычным способом:

Get-MailboxDatabase -Server oldserver | Remove-MailboxDatabase

Важно помнить, что удаляемая база не должна быть связана с запросами на импорт/экспорт и восстановление, а так же не должна содержать арбитражные ящики.

Удаляем старую OAB

После миграции OAB на новые серверы ничто не мешает старую OAB удалить:

Remove-OfflineAddressBook 'Old Address Book'

Удаляем базы общих папок

Очевидный стоп-фактор процесса – наличие данных в общих папках. К этому моменту эти данные должны быть смигрированы либо в общие ящики, либо в новые общие папки (Modern Public Folders). Остатки общих папок можно переместить в выделенную базу, которую будем удалять последней:

MoveAllReplicas.ps1 -Server oldserver -NewServer newserver

Процесс переноса можно отслеживать по наличию локальных копий перемещаемых папок:

Get-PublicFolderStatistics -Server oldserver

Кроме остатков папок базы почтовых ящиков могут ссылаться на удаляемую базу общих папок. Все эти ссылки необходимо удалить. Следующий командлет работать не будет:

Set-MailboxDatabase somedatabase -PublicFolderDatabase $null

И тут нам на помощь придёт утилита ADSIEdit. Необходимо будет подключиться к разделу конфигурации и в нужных базах, расположенных тут – CN=Services > CN=Microsoft Exchange > CN=(your organization name) > CN=Administrative Groups > CN=Exchange Administrative Group (FYDIBOHF23SPDLT) > CN=Databases очистить аттрибут msExchHomePublicMDB. Подробно процесс в картинках можно посмотреть тут.

Когда не останется баз, связанных с удаляемой базой общих папок, и не останется локальных копий общих папок, можно будет удалять базу:

Get-PublicFolderDatabase -Server oldserver | Remove-PublicFolderDatabase

Удаляем последнюю базу общих папок

Перед удалением последней базы общих папок чистим её от остатков папок:

Get-PublicFolder -Server newserver "\" -Recurse | Remove-PublicFolder -Recurse
Get-PublicFolder -Server newserver "\Non_Ipm_Subtree" -Recurse | Remove-PublicFolder -Recurse

Для счастливых обладателей общих папок, существующих с версий 2003 и раньше, возникнет проблема – часть папок удалить не получится. Вот эти волшебные папки:

  • Все папки оффлайновых адресных книг, расположенные в \Non_Ipm_Subtree\OFFLINE ADDRESS BOOK\
  • Папка \Internet Newsgroups

Согласно этой ссылке это “нормальное” и ожидаемое поведение. Существует небольшой финт ушами, который позволит эту проблему обойти. Для этого мы отключаем базу общих папок, удаляем всё содержимое папки, в которой хранятся файлы базы и монтируем базу назад. В итоге мы получаем девственно чистую базу без артефактов прошлых эпох. Так как старая база никаких ценных данных не содержала, то мы при этом процессе ничего не теряем. После этого последнюю базу общих папок можно удалять:

Remove-PublicFolderDatabase -Server newserver -RemoveLastAllowed

Ключ -RemoveLastAllowed обязателен.

Удаление mailbox-сервера

После того, как удалены все базы и OAB mailbox-сервер можно удалить либо через штатный GUI в Program and Files, либо через командную строку:

Setup.com /mode:Uninstall /role:M

Полезные ссылки:
How to Remove the Default Public Folder Database for an Exchange Mailbox Database
Unable to delete the OAB system folders in Exchange 2007?

Механизм создания и распространения оффлайновой адресной книги между версиями Exchange 2010 и Exchange 2016 сильно различается. Поэтому процесс переключения на OAB, находящийся на Exchange 2016, в процессе миграции нужно будет продумывать очень внимательно.

Старый механизм (Exchange 2010) работал следующим образом:

  1. Выделенный сервер с ролью mailbox по расписанию генерировал файлы OAB
  2. После создания обновлённой OAB она скачивалась на серверы с ролью Client Access Server в веб-директории
  3. Клиент Outlook обращался в эти веб-директории (её адрес он получал от службы автообнаружения) и скачивал локально файлы OAB

Подробнее процесс описан тут.

Новый механизм (Exchange 2013/2016) работает так:

  1. Специальный робот OABGeneratorAssistant генерирует OAB на сервере, где находится активная база со специальным арбитражным ящиком. У специального арбитражного ящика должна быть включена функция OrganizationCapabilityOABGen. По умолчанию она включена в ящике SystemMailbox{bb558c35-97f1-4cb9-8ff7-d53741dc928c}
  2. Затем сгенерированная OAB выгружается в веб-директорию на этом же сервере
  3. Клиент Outlook обращается в эту веб-директории (её адрес он получает от службы автообнаружения) и скачивает локально файлы OAB

Подробно процесс описан тут.

В процессе миграции OAB есть одна тонкость – мы OAB не мигрируем. Мы клиентов переключаем на новый OAB, которая генерируется по новой схеме. Схема миграции будет выглядеть примерно следующим образом:

  • Создаём отдельный арбитражный ящик и включаем в нём функцию OrganizationCapabilityOABGen (делать это необязательно, так как у нас имеется ящик SystemMailbox{bb558c35-97f1-4cb9-8ff7-d53741dc928c}, который можно использовать для этих целей):
New-Mailbox -Arbitration -Name "OAB Mailbox" -Database db1 -UserPrincipalName oab@o365lab.pro
Set-Mailbox -Arbitration oab -OABGen $true
  • Создаём новую OAB и копируем в неё адресные списки из старой OAB:
$OAB = Get-OfflineAddressBook 'Old Address Book'
New-OfflineAddressBook -Name "New Address Book (Ex2016)" -AddressLists $OAB.AddressLists
  • Привязываем новую OAB к новому арбитражному ящику, который будет заниматься генерацией OAB:
$mbx = Get-Mailbox 'OAB Mailbox' -Arbitration
Set-OfflineAddressBook 'New Address Book (Ex2016)' -GeneratingMailbox $mbx.Identity
  • Имеет смысл включить GlobalWebDistributionEnabled и ShadowMailboxDistributionEnabled (что это такое можно посмотреть тут)
Set-OfflineAddressBook "New Address Book (Ex2016)" -VirtualDirectories $null 
-GlobalWebDistributionEnabled $true -ShadowMailboxDistributionEnabled $true
  • Запускаем обновление OAB и переназначаем её всем базам:
Update-OfflineAddressBook 'New Address Book (Ex2016)'
Get-MailboxDatabase | Set-MailboxDatabase -OfflineAddressBook 'New Address Book (Ex2016)'

На выходе мы получаем новую OAB, которая создаётся на серверах Exchange 2016 и которую используют все ящики, которые смигрировали на Exchange 2016.

Полезные ссылки:
Understanding Offline Address Books (Exchange 2010)
Offline address books in Exchange 2016
OAB Improvements in Exchange 2013 Cumulative Update 7
OAB Improvements in Exchange 2013 Cumulative Update 5
OAB in Exchange Server 2013
Managing OAB in Exchange Server 2013

Проблема: администратор Exchange в процессе установки очередного CU для Exchange 2016 пытается открыть портал ECP и в ответ получает 500 ошибку примерно такого вида:

В результате небольшой проверки становится известно, что учётная запись этого администратора не имеет почтового ящика. В этом случае процесс подключения к ECP становится не совсем тривиальным и происходит следующим образом. При получении запроса Exchange видит, что администратор не имеет почтового ящика, поэтому проксирует запрос на родной сервер арбитражного ящика SystemMailbox{bb558c35-97f1-4cb9-8ff7-d53741dc928c}.

В моём случае:

[PS] C:\>Get-Mailbox 'SystemMailbox{bb558c35-97f1-4cb9-8ff7-d53741dc928c}' -Arbitration | 
fl servername

ServerName : someserver

В тот момент, когда администратор пытался открыть ECP someserver во всю обновлялся, поэтому был не доступен. Поэтому ближайший к администратору сервер возвращал ему в ответ 500 ошибку.

Поэтому вариантов дальнейшего развития событий всего два: или мы ждём, пока ссервер обновится и всё само заработает, или мы подключаем к учётной записи администратора ящик.

Полезные ссылки:
HTTP 500 Internal Server Error when logging into Exchange 2013 Exchange Control Panel (ECP)

Очередная встреча UC² под номером 25 состоится через неделю, 25 числа, как обычно с 18-00 до 21-00. Встреча будет проходить и в ОНЛАЙН-режиме. А вот кто будет выступать:

  • Борис Лохвицкий, Microsoft

Тема: Архитектура Exchange Server 2016.

Борис будет рассказывать знаменитый доклад Росса Смита, с которым последний выступает на всех крупных мероприятиях в течение последних нескольких лет. Впервые на русском языке.

  • Олег Крылов, UC User Community Russia

Тема доклада: Управление локальными учетными записями в доменной среде

Олег расскажет про использование уже не нового, но до сих пор крайне актуального инструмента LAPS (Local Administrator Password Solution).

Регистрация на встречу как обычно тут.

Обновление. Записи доступны по ссылкам:
UC². Встреча №25. Борис Лохвицкий. Архитектура Exchange Server 2016

Стандартный запрос на перемещение завершается с ошибкой. Статистика выдаёт ошибку TooManyMissingItemsPermanentException:

[PS] C:\>Get-MoveRequestStatistics 'Some Mailbox' -IncludeReport | fl
...
BadItemLimit                             : 7
BadItemsEncountered                      : 0
...
FailureCode                              : -2146233088
FailureType                              : TooManyMissingItemsPermanentException
FailureSide                              :
Message                                  : Error: This mailbox exceeded the maximum number of 
corrupt or missing items that were specified for this request.

Видно, что ключ BadItemLimit имеет значение 7, при этом в процессе перемещение плохих объектов найдено 0. Для получения дополнительной информации о перемещении у командлета Get-MoveRequestStatistics есть ключ Diagnostic, который позволяет получить дополнительную информацию в данном случае:

[PS] C:\>Get-MoveRequest 'Some Mailbox' | Get-MoveRequestStatistics -Diagnostic | fl
...
DiagnosticInfo                           : ...
        <SkippedItems Corrupt="0" Missing="13" Large="0" Other="0"> 
                <C Kind="MissingItem" KindInt="0" Cat="Default" Num="3" /> 
                <C Kind="MissingItem" KindInt="0" Cat="OldNonContact" Num="10" /> 
        </SkippedItems> 

Видно, что в процессе перемещения попались некие MissingItems в количестве 13 штук, что превышает значение, выставленное в ключе BadItemLimit. Выставляем ключ BadItemLimit  в 15, перезапускаем запрос на перемещение ящика (Resume-MoveRequest ‘Some Mailbox’). Перемещение происходит без проблем.

Переключение https-трафика

После того как новые серверы настроены и подготовлены для приёма пользовательских почтовых ящиков наступает время, когда необходимо веб-клиентов переключить на новые серверы. Новые серверы, в случае необходимости, сами будут проксировать клиентов, находящихся на серверах Exchange 2010 на старые серверы.

Делается это достаточно просто – меняется a-запись в dns, которая является точкой подключения веб-клиентов. В нашем случае это webmail.o365lab.pro. Она должна указывать на VIP балансировщика, который отвечает за обработку веб-трафика для Exchange 2016. После изменения схема лабы будет выглядеть следующим образом:

Согласно схеме все веб-клиенты (OWA/ActiveSync/Outlook Anywhere) будут ходить на новые серверы MBX161/162, которые будут проксировать подключения клиентов на старые серверы MBX101/102. MAPI-клиенты Outlook будут продолжать ходить на старые серверы MBX101/102. Для них ничего не изменится.

Миграция почтовых ящиков

После этого можно начинать миграцию почтовых ящиков. При миграции есть несолько тонких моментов:

  • Ящики пользователей нужно мигрировать в первую очередь. Связано это с тем, что если ящик пользователя находится на сервере Exchange 2010, а ресурсный/общий почтовый ящик уже на сервере Exchange 2016, то могут наблюдаться различные проблемы с доступом к ресурсному/общему почтовому ящику
  • Необходимо настроить автоматический перезапуск следующих IIS-пулов на серверах Exchange 2016 на время миграции: MSExchangeAutodiscoverAppPool, MSExchangeRpcProxyAppPool, MSExchangeServicesAppPool. Например, на перезапуск через минуту. Связано это с тем, что после миграции ящика, информация служб автообнаружения, EWS, RPC-прокси на новых серверах обновляется не сразу, а по мере сброса кэша пулов, которые отвечают за работу этих служб. Кэш сбрасывается не сразу. Например, для службы автообнаружения на текущий момент срок жизни кэша составляет 4 часа. А это значит, кто клиент, после миграции может до 4 часов получать с серверов Exchange 2016 информацию о том, что он должен подключаться к серверам Exchange 2010. Соответственно, в течение этого времени клиент не сможет подключить свой Outlook.
  • При миграции происходит конвертация данных почтового ящика в новый формат почтовой базы, что приводит к незначительному росту размера конкретного объекта в ящике. Если таких объектов много (сотни тысяч, например), то это напрямую повлияет на финальный размер ящика на сервере Exchange 2016. И если финальный размер превысит ограничения на размер ящика, то миграция ящика завершится с ошибкой. Выхода всего два: увеличивать ограничения на размер ящика либо удалять старые данные из исходного ящика, чтобы уменьшить количество объектов в нём.

Полезные ссылки:
Outlook stays disconnected after migrating mailbox from Exchange 2010 to Exchange 2013 SP1
Миграция на Exchange 2016: настройка новых серверов
Миграция на Exchange 2016: танцы с бубном вокруг IIS
Client Connectivity in an Exchange 2016 Coexistence Environment with Exchange 2010