Подчищаем хвосты за Microsoft Exchange Server 2016 используя Powershell

в 12:11, , рубрики: active directory, exchange, powershell, автоматизация, системное администрирование

image

Работая в течении полугода с Microsoft Exchange Server 2016 в компании, где более 500 сотрудников использует корпоративную почту, я столкнулся с проблемой полноценного удаления информации о пользователях, отключенных в Active Directory.

Задачи, которые мы хотим автоматизировать, после отключения учетки пользователя в AD:

  • Экспорт всех писем из основого и архивного ящика в .pst файл;
  • Полная блокировка почтового ящика после экспорта писем;
  • Очистка всех списков рассылки от «мертвых пользователей» (автоматически не очищается);
  • Обновление Global Address List и Offline Address Book, чтобы активные пользователи не видели отключенных.

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

Подготовка:

Подключаем библиотеку Exchange Management PowerShell:

Add-PSSnapin Microsoft.Exchange.Management.PowerShell.SnapIn;

Получаем список всех отключенных в Active Directory пользователей и исключаем некоторые служебные записи:

$DisableUsers = get-user -Filter {(UserAccountControl -eq 'AccountDisabled, NormalAccount') -and (RecipientType -eq 'UserMailbox')} | ? {($_.SamAccountName -ne 'krbtgt') -and ($_.SamAccountName -ne 'SM_2013a5b0c2bd4ca2a') -and ($_.SamAccountName -ne 'testvc')}

Объявляем переменные:

# Объявляем переменную для объединения нескольких запросов на экспорт.
$BatchName = 'MassRequest'
# Создаем пути для экспорта
$CMounth = (Get-Date).month 
$CYear = (Get-Date).year 
$CurrentDate = "$CYear.$CMounth" # Получаем будущее имя папки вида Год.Месяц
$MainDir = "\%Ваш путь%"
$ExportPath = $MainDir + $CurrentDate + ""

Обработка:

Чтобы было удобнее найти .pst архив уволенного пользователя, было принято решение создавать папку вида Год.Месяц. Так, все уволенные пользователи в апреле 2017 года попадут в папку 2017.4, уволенные в мае в папку 2017.5 и тд.

# Проверяем, есть ли уже папка Год.Месяц, если нет, то создаем.
if ((Test-Path $ExportPath -PathType Container) -eq $false){
    New-Item -Path $MainDir -Name $CurrentDate -ItemType "directory"
} 

В цикле по отключенным пользователям выгружаем их почту в .pst файл из основного и архивного почтовых ящиков и сохраняем в папку Год.Месяц.

С помощью параметра -BatchName объединяем запросы под одним именем, для возможности отслеживать статус всей выгрузки сразу, а не каждый запрос отдельно.

foreach($User in $DisableUsers){
$PrimaryPath = $ExportPath + $User.SamAccountName + ".pst"
$ArhivePath = $ExportPath + $User.SamAccountName + "_Archive.pst"

New-MailboxExportRequest -Mailbox $User.SamAccountName -BatchName $BatchName -FilePath $PrimaryPath
New-MailboxExportRequest -Mailbox $User.SamAccountName -BatchName $BatchName -FilePath $ArhivePath -IsArchive     
} 

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

# Ждем, пока скрипт закончит работу
$i=1;
while ((Get-MailboxExportRequest -BatchName $BatchName | Where {($_.Status -eq “Queued”) -or ($_.Status -eq “InProgress”)})) {
    sleep 60
    Write-Host "Скрипт работает $i минут. Ожидаем завершения.."
    $i=$i+1
}

После завершения экспорта удаляем все запросы, которые получили статус Completed

# После завершения экспорта удаляем все запросы
Get-MailboxExportRequest -Status Completed | Remove-MailboxExportRequest -Confirm:$false 

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

# Начинаем чистить списки рассылок. Сначала получаем их полный список. 
$DistribList = Get-DistributionGroup

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

# В цикле удаляем отключенных пользователей из всех списков
foreach($List in $DistribList){
    foreach($User in $DisableUsers){        
        Remove-DistributionGroupMember -Identity $List -Member $User -Confirm:$false -ErrorAction Ignore  
    }
} 

Предпоследний этап: отключение почтовых ящиков. Из учетки пользователя в AD пропадает E-mail, а сам почтовый ящик удаляется. Теперь его только в течении некоторого времени можно восстановить стандартными средствами Exchange.

# Начинаем отключать почтовые ящики, после чего они пропадут из адресной книги
foreach($User in $DisableUsers){
    Disable-Mailbox -Identity $User.SamAccountName -Archive -Confirm:$false 
    Disable-Mailbox -Identity $User.SamAccountName -Confirm:$false       
}

Обновляем GAL и OAB, чтобы пользователи увидели изменения как можно быстрее.

# Обновляем Global Adress List, чтобы клиенты увидели изменения в адресной книге
Get-GlobalAddressList | Update-GlobalAddressList
Get-OfflineAddressBook | Update-OfflineAddressBook
Get-AddressList | Update-AddressList

Небольшой комментарий:

В своей фирме мы прицепили эту обработку к кастомной кнопке в 1С. Отдел кадров в профиле сотрудника выставляет ему статус «Уволен» и скрипт начинает работать.

Тем самым отключенных пользователей в адресной книге практически невозможно увидеть, а уволенный сотрудник сразу теряет доступ к почте. (Если только выключить учетку в Active Directory, то зайти в почту сотрудник все равно может, что по нашей корпоративной политике недопустимо).

Надеюсь кому-то скрипт будет полезен. Спасибо!

Автор: kotorr

Источник

* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js