Управление списками модерации почтовых ящиков Exchange

02.12.2013

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

Примечание. У нас в компании существует порядка 30 групп рассылкок, которые структурированы по организоционной диаграмме компании: Компания - Подразделение - Город, которые вложены друг в друга по иерархии.

Так как групп оказалось очень много, чтобы делать удаление-добавление через консоль, я написал следующий скрипт Powershell.

# Разрешение исполнения неподписанных скриптов
Set-ExecutionPolicy Unrestricted

# Создание сессии к почтовому серверу
$Session = New-PSSession -ConfigurationName Microsoft.Exchange `
 -ConnectionUri http://exchangeserver.domain.com/PowerShell/ -Authentication Kerberos
Import-PSSession $Session
# Подключение модуля работы с Active Directory
Import-Module ActiveDirectory

# Функция конвертации полного имени объекта (Distinguished Name) в каноническое имя (Canonical Name)
Function Get-CanonicalName {
   Param(
       [string]$DN
   )
   Process {
       # Разделение полного имени на составляющие
       $Parts = $DN.Split(",")
       # Определение количества уровней
       $NumParts = $Parts.Count
       # Определение количества составляющих имени домена
       $FQDNPieces = ($Parts -match 'DC').Count
       # Определение количества составляющих непосредственного имени объекта
       $Middle = $NumParts - $FQDNPieces
       # Построение имени домена (части имени домена соединяются точкой)
       ForEach ($x In ($Middle+1)..($NumParts)) {
           $CN += $Parts[$x-1].SubString(3)+'.'
       }
       # Удаление лишней точки в конце имени домена
       $CN = $CN.substring(0,($CN.length)-1)
       # Достроение канонического имени, читая части полного имени с конца вперед и разделяя их слешами
       ForEach ($x in ($Middle-1)..0) {
           #$Parts[$x].substring(3)
           $CN += "/"+$Parts[$x].SubString(3)
       }
       Return $CN
   }
}

# Функция удаления пользователя из разрешенных отправителей для группы рассылки
Function Remove-DistributionGroupAcceptMessagesOnlyFrom {
   Param(
       [string]$GroupName,
       [string]$UserName)
   Process {
       # Получение текущего списка разрешенных отправителей
       Try {
           $Members = Get-DistributionGroup -Identity $GroupName | `
             Select AcceptMessagesOnlyFromSendersOrMembers
       }
       Catch {
           Write-Host "Error: The group $GroupName is not found." -ForegroundColor Red
       }
       $NewMembers = @()
       # Поиск в полученном списке указанного пользователя и перестроение списка
       ForEach ($Member in $Members.AcceptMessagesOnlyFromSendersOrMembers) {
           If (!$Member.Contains($UserName)) {
               $NewMembers += $Member
           }
       }
       # Сохранение нового списка доступа к группе
       Try {
           Set-DistributionGroup -Identity $GroupName -AcceptMessagesOnlyFromSendersOrMembers $NewMembers `
             -BypassSecurityGroupManagerCheck
       }
       Catch {
           Write-Host $Error -ForegroundColor Red
       }
   }
}

# Функция добавления пользователя в разрешенные отправители для группы рассылки
Function Add-DistributionGroupAcceptMessagesOnlyFrom {
   Param(
       [string]$GroupName,
       [string]$UserName)
   Process {
       # Поиск полного имени пользователя и конвертация найденного имени в каноническое имя
       Try {
           $UserCanonicalName = Get-CanonicalName (Get-ADUser -Filter 'Name -like `
             $UserName').DistinguishedName
       }
       Catch {
           Write-Host "Error: The user $UserName is not found." -ForegroundColor Red
       }
       # Получение текущего списка разрешенных отправителей
       Try {
           $Members = Get-DistributionGroup -Identity $GroupName | `
             Select AcceptMessagesOnlyFromSendersOrMembers
       }
       Catch {
           Write-Host "Error: The group $GroupName is not found." -ForegroundColor Red
       }
       $NewMembers = @()
       # Поиск в полученном списке указанного пользователя и перестроение списка
       ForEach ($Member in $Members.AcceptMessagesOnlyFromSendersOrMembers) {
           $NewMembers += $Member
           If ($Member.Contains($UserName)) {
               $AlreadyExists = $True
           }
       }
       # Добавление пользователя в список, если его там нет
       If (!$AlreadyExists) {
           $NewMembers += $UserCanonicalName
       }
       Else {
           Write-Host "Error: The user $UserName is already in the list." -ForegroundColor Red
       }
       # Сохранение нового списка доступа к группе
       Try {
           Set-DistributionGroup -Identity $GroupName -AcceptMessagesOnlyFromSendersOrMembers $NewMembers `
             -BypassSecurityGroupManagerCheck
       }
       Catch {
           Write-Host $Error -ForegroundColor Red
       }
   }
}

# Удаление пользователя из списка разрешенных пользователей на отправку группе рассылки
Remove-DistributionGroupAcceptMessagesOnlyFrom "Company - Nizhniny Novgorod" "Marina Ivanova"

# Добавление пользователя в список разрешенных пользователей на отправку группе рассылки
Add-DistributionGroupAcceptMessagesOnlyFrom "Company - Nizhniny Novgorod" "Irina Petrova"

Аналогичным образом можно написать функции обработки списков доступа к отправке на почтовые ящики, заменив функции Get-DistributionGroup и Set-DistributionGroup на Get-Mailbox и Set-Mailbox соотвественно. Например:

$Members = Get-Mailbox -Identity $MailboxName | Select AcceptMessagesOnlyFromSendersOrMembers