«Проявление» удаленных почтовых ящиков


Редко приходится восстанавливать удаленные почтовые ящики, поэтому всё время забываю, как их «проявить» в Exchange Server 2013.

Exchange чрезвычайно экономно работает с почтовыми базами и базой Active Directory. Причем настолько экономно, что порой «забывает» изменять второстепенные атрибуты: например, при удалении почтового ящика признак SoftDeleted можно ждать очень долго, а без него трудоёмко найти фактически уже удаленный почтовый ящик.

В Exchange 2010 «проявить» все удаленные почтовые ящики можно было командой:

Get-MailboxDatabase | Clean-mailboxdatabase

Более экономно для одной почтовой базы:

Get-MailboxDatabase "mbdatabase"| Clean-mailboxdatabase

В версии Exchange 2013 командлета Clean-mailboxdatabase нет!

Тем не менее «проявление» удаленных почтовых ящиков можно сделать так:

Get-MailboxDatabase | foreach{Get-MailboxStatistics -Database $_.identity} | ForEach { Update-StoreMailboxState -Database $_.Database -Identity $_.MailboxGuid -Confirm:$false }

(Также можно указать конкретную почтовую базу Get-MailboxDatabase «mbdatabase»| …)

Как видите, стремление к экономии породило новый командлет Update-StoreMailboxState, который в отличие от Clean-mailboxdatabase работает только для одного почтового ящика: поэтому приходится перетряхивать всё содержимое почтовой базы командлетом Get-MailboxStatistics.

Только после этого можно получить список удаленных (отсоединенных) почтовых ящиков:

Get-MailboxDatabase | Get-MailboxStatistics | Where {($_.DisconnectDate -ne $null)}

Полезные ссылки:

  1. Connect-Mailbox
  2. Update-StoreMailboxState
  3. Connect a disabled mailbox

Один нюанс при миграции почтовых групп Exchange


При миграции учётных записей и почтовых ящиков из одного леса в другой чаще всего есть период времени, когда две организации Exchange должны сосуществовать и тесно взаимодействовать. Описанные в документации стандартные процедуры миграции содержат лишь достаточный минимум. При этом существует множество мелких полезных нюансов. Например, можно настроить надёжную передачу сообщений (Exchange – надежная доставка сообщений между лесами) задействовав Shadow Redundancy.

Ещё одна хитрость касается групп рассылки (distribution groups). При миграции почтовых групп (mail groups) пользователи и группы могут оказаться в разных лесах. При этом де-юре два наших леса это одно целое, но технически это не так. Когда пользователь из одного леса попробует отправить сообщение в группу рассылки другого леса, то получит отказ, т.к. по умолчанию отправлять в группы рассылки могут только пользователи прошедшие аутентификацию, а пользователь другого леса по умолчанию будет анонимным. Как быть?

Можно на время миграции включить на всех группах разрешение отправки для анонимных пользователей. Это может быть неудобно по той причине, что возможно на части групп это разрешение уже включено, и придётся вести учёт таких групп. Но есть достаточно простой и красивый обходной путь.

Как определяется, что пользователь прошёл аутентификацию? В рамках одного леса сервер, к которому происходит первичное подключение пользователя производит его аутентификацию и выставляет соответствующий флаг. Когда письмо передаётся на другой сервер, то аутентификация пользователя уже не производится: письмо просто передаётся с флагом, и принимающий сервер доверяет этой информации. Ключ здесь – «доверяет». Все Exchange серверы в одном лесу доверяют друг другу: передают и получают служебную информацию и доверяют ей, в том числе сведениям об аутентификации. Вопрос в том, как настроить доверие между Exchange серверами разных лесов. Возможно ли это? Да, это возможно. Exchange серверы взаимодействуют друг с другом через коннекторы, и именно свойства этих коннекторов определяют механизмы аутентификации и уровень безопасности (доверия) между серверами. Так коннектор принимающий почту из Интернета не доверяет внешним серверам и не принимает от них никакой служебной информации, а коннектор между Exchange серверами одного леса полностью доверяет служебной информации от соседних серверов его почтовой организации. Регулируется это выставлением прав (permissions) на коннекторах.

Фактически для решения нашей задачи в каждом лесу нужно создать внутренний (Internal) принимающий коннектор и указать в нем группы прав Exchange Servers и LegacyExchange Servers, а также аутентификацию External Secured. Безусловно нужно защититься указав адрес передающего сервера/серверов другого леса. Аналогично поступаем для передающего коннектора. Всё! Теперь пользователи наших лесов смогут отправлять сообщения в группы рассылки.

Полезные ссылки:

  1. How to Create a receive connector to authorize Cross forest emails in Exchange 2013
  2. Receive connector permissions
  3. Allowing application servers to relay off Exchange Server 2007

Интеграция OWA и Lync


OWA может как и Outlook распознавать контакты Lync и отображать состояние присутствия клиента. И не только отображать состояние, но и предоставить доступ к некоторым функциям Lync. Для этого нужно выполнить процедуру интеграции как описано в статье Integrating Microsoft Lync Server 2013 and Microsoft Outlook Web App 2013.

Важно помнить, что при установке очередного кумулятивного обновления исправления внесённые в web.config файл будут потеряны и нужно снова выполнить шаг настройки интеграции и добавить две свои строки в этот файл:

<add key=»IMCertificateThumbprint» value=»EA5A332496CC05DA69B75B66111C0F78A110D22d»/>

<add key=»IMServerName» value=»atl-cs-001.litwareinc.com»/>

Если серверов много, то поможет специальный скрипт Configure-IMIntegration.ps1 описанный тут.

Exchange – надежная доставка сообщений между лесами


Теневая избыточность (Shadow redundancy) обеспечивает высокую надежность доставки сообщений на уровне транспортных служб. Работает она в рамках одной организации Exchange. Но бывают ситуации, когда в компании несколько лесов и несколько организаций Exchange, либо когда есть необходимость обеспечить надежную доставку компаниям-партнерам. Возникает вопрос: можно ли настроить Shadow redundancy так, чтобы этот механизм работал между серверами в разных лесах?

Ответ положительный. Нужно всего лишь выставить для учётных записей серверов (MS Exchange\Externally Secured Servers) право ms-Exch-SMTP-Accept-XSHADOW на коннекторах, которые связывают серверы разных лесов друг с другом, а также выставить доверие (SmartHostAuthMechanism ExternalAuthoritative). В зависимости от ситуации это можно сделать как на существующих коннекторах, так и создать новые.

Два примера (первый и второй). Копия второго:

New-SendConnector ToForest2 -AddressSpaces SMTP:domain.com -SmartHosts mail.domain.com -ProtocolLoggingLevel verbose -DNSRoutingEnabled $False -SmartHostAuthMechanism ExternalAuthoritative
Get-SendConnector ToForest2 | Add-ADPermission -user "MS Exchange\Externally Secured Servers" -ExtendedRights ms-Exch-SMTP-Send-XShadow

New-ReceiveConnector FromForest1  -Bindings 0.0.0.0:25 -RemoteIPRanges 192.168.1.1 -ProtocolLoggingLevel verbose -Banner "220 Forest2 XShadow SMTP Server" -AuthMechanism ExternalAuthoritative
Get-ReceiveConnector FromForest1 | Add-ADPermission -user "MS Exchange\Externally Secured Servers" -ExtendedRights ms-Exch-SMTP-Accept-XShadow


Powershell – вычисляем размер поддиректорий


Update: сделан командлет и опубликован в Gallery Measure-SubDirSize — measure sizes of subdirectories

При анализе индексации файловых шар (Sharepoint — мусор на файловой шаре) возникла частная задача: есть папки на диске или шары подразделений; для каждого подразделения требуется оценить количество файлов заданного типа и их общий размер.

Фактически нужно взять путь в ресурсу и для каждой поддиректории вычислить число и размер файлов заданных маской. При этом нам не нужна информация о поддиректориях ниже первого уровня. Иначе говоря, простая рекурсия не подходит. Современные версии Powershell (выше 3.0) позволяют решить задачу в команду при использовании pipeline variable.

С учётом предыдущего опыта по оптимизации скриптов на Powershell (Powershell – средства оптимизации скрипта) получился такой скрипт решающий нашу задачу:


$res=dir -Directory \\server\share  -pv pvDir |
    % {dir -Recurse -Path ($_.FullName) -Filter "*.xls"  | Measure-Object -Property Length -Sum } |
    % { [pscustomobject] @{ Name=$pvDir.Name; Count = $_.Count ; Sum = $_.Sum } }

Sharepoint — мусор на файловой шаре


На днях настраивал в Sharepoint индексацию файловых шар. При изучении ошибок индексации обнаружил попытки Sharepoint проиндексировать файлы вида ~*.* – временные файлы, которые создают приложения Microsoft Office. Эти временные файлы удаляются автоматически при закрытии рабочего файла в приложении Office, но если рабочий файл не закрыли нормальным способом (потеря сети, крах системы, крах приложения и т.п.), то временные файлы могут оставаться на диске и образовывать мусор. Со временем на большом файловом сервере могут скопиться тысячи таких файлов занимающих гигабайты дискового пространства.

В Sharepoint пришлось создать правило индексации исключающее файлы вида ~*.* Это уменьшило число ошибок индексации и заметно уменьшило время индексации: если такой временный файл новый и используется, то он как правило заблокирован для доступа, и процесс индексации начинает его «долбить», растрачивая ресурсы и замедляя индексацию. Это был позитивный результат. Но сам мусор остался на дисках.

Чтобы его удалить, пришлось искать подходящий инструмент. Проблема заключалась в том, что пользователи создают папки очень большой длинны и большой вложенности. Когда имя файла превышает 260 символов (что жёстко задано в Windows File Explorer), то происходит ошибка и процесс очистки останавливается. Поэтому требовался инструмент, который бы использовал низкоуровневый API Win32 и был лишен этого ограничения. Таким инструментом оказалась давно известная утилита robocopy.

Получилась такая команда:

robocopy "E:\Data" null  ~*.* /s /mov

Учтите, что при выполнении robocopy вполне способна полностью занять одно ядро CPU и серьезно нагрузить систему ввода-вывода, поэтому чистку больших томов лучше запускать в часы наименьшей нагрузки.

Полезные ссылки:

1. Long Paths in .NET, Part 1 of 3 [Kim Hamilton]
2. Long Paths in .NET, Part 2 of 3 [Kim Hamilton]
3. Long Paths in .NET, Part 3 of 3 [Kim Hamilton]

Sharepoint Server 2013 – удаление RBS


После экспериментов по установке и настройке RBS (Remote Blob storage) на Sharepoint возник закономерный вопрос о том, как откатиться: полностью деактивировать и деинсталлировать RBS.

Последствия установки RBS в том, что часть информации оказывается вне SQL-базы в виде файлов на файловой системе. Поэтому просто взять и удалить RBS из списка установленных программ это значит разрушить базу, что категорически неприемлемо. Читать далее