e2010Следующий сценарий родился в процессе миграции пользователей с одного из сторонних почтовиков. Итак, у нас имеется набор почтовых ящиков, которые созданы для миграции со стороннего почтового решения. В некоторый момент времени к стандартным smtp-адресам (например, domain.com) добавляются smtp-адреса, которые находятся у пользователей во внешней почтовой системе (например, домен domain.net). Так как изначально процесс не сильно автоматизирован, то в некоторый момент времени оказывается, что не все почтовые ящики имеют smtp-адрес из домена domain.net. А час X (когда мы добавим домен domain.net в авторизованные) приближается и необходимо выяснить какие-же почтовые ящики мы не охватили. То есть необходимо найти те почтовые ящики (предположим, что мы их пока складируем в отдельных почтовых базах), которые примут пользователей при миграции, но при этом старый smtp-адрес для них не прописан.

Первым делом давайте посмотрим в каком виде у нас хранятся smtp-адреса. Все они находятся в свойстве EmailAddresses почтового ящика. Свойство это многозначное, то есть фактически представляет собой некий массив разнородных данных (помним, что кроме smtp-адресов в этом свойстве могут записываться и другие типы адресов, например, sip или X400). При обращении к нему выведется набор объектов, каждый из которых представляет определённый адрес, прописанный в свойствах ящика:

[PS] C:>(Get-Mailbox stbul).EmailAddresses

SmtpAddress        : stbul@domain.com
AddressString      : stbul@domain.com
ProxyAddressString : SMTP:stbul@domain.com
Prefix             : SMTP
IsPrimaryAddress   : True
PrefixString       : SMTP

AddressString      : C=RU;A= ;P=DOMAIN;O=DOMAIN;S=Buldakov (Test);G=Stanislav;
ProxyAddressString : X400:C=RU;A= ;P=DOMAIN;O=DOMAIN;S=Buldakov (Test);G=Stanislav;
Prefix             : X400
IsPrimaryAddress   : True
PrefixString       : X400

Очевидно, что работать мы будем не со всеми адресами, а только с smtp. Поэтому имеет смысл фильтровать по свойству ProxyAddressString, и выбирать только те объекты-адреса, у которых это свойство начинается с SMTP. Простейший вариант поиска только smtp-адресов будет выглядеть следующим образом:

$mailbox = Get-Mailbox somemailbox
for ($i=0; $i -lt $mailbox.EmailAddresses.Count; $i++){
    if ($mailbox.EmailAddresses[$i].ProxyAddressString -like "smtp:*"){
        $mailbox.EmailAddresses[$i]}
}

В нашем случае процесс усложняется тем, что перед нами стоит обратная задача. То есть надо собрать не все почтовые ящики с адресами в определённом домене, а те, у которых адресов из нужного нам домена нет. Один из вариантов решения данной проблемы – использование специального счётчика, который будет увеличиваться при нахождении в свойствах ящика нужного нам smtp-адреса. А в итоге, выводить будем те объекты, значение счётчика для которых будет равно нулю (то есть он не будет содержать нужного нам smtp-адреса). Итоговый скрипт получается примерно следующий:

$mailboxes = Get-MailboxDatabase new-db* | Get-Mailbox
foreach ($mailbox in $mailboxes){
    $i = 0
    $count = 0
    for ($i=0; $i -lt $mailbox.EmailAddresses.Count; $i++){
    if ($mailbox.EmailAddresses[$i].ProxyAddressString -like "smtp:*domain.net"){
        $count = $count + 1}
    }
    if ($count -eq 0){
        $mailbox.Name}
}

Аналогично, можно искать, например, группы распространения. В этом случае в переменную $mailboxes помещается набор нужных нам групп.