Конкурс хаков: пишем на PowerShell скрипт, который уведомляет о днях рождения пользователей Active Directory

Евгений Петкевич, 22.09.2017
В компаниях часто встречается задача уведомлять сотрудников о приближающихся днях рождения их коллег. Где-то этим занимается секретариат, а где-то автоматизированные системы (корпоративный сайт, SharePoint и подобное). В этой статье я расскажу о простеньком скрипте на PowerShell, который работает с AD и рассылает уведомления по почте.

Поздравляем участника конкурса

Этот текст был прислан на конкурс авторов, который мы запустили весной. Мы разобрались с большим количеством пришедших материалов, подвели итоги и наградили победителей. Автор этой заметки получил приз — трехмесячную подписку на «Хакер». Поздравляем!

Итак, сценарий работы скрипта такой.

  1. Берем из AD всех пользователей.
  2. У каждого пользователя смотрим Extended attributes 10, в котором записана дата рождения сотрудника в формате дд.мм.гггг.
  3. Если дата следующего дня совпадает с датой в Extended attributes 10 сотрудника, делаем рассылку с напоминанием о предстоящем дне рождения этого сотрудника.

Дальше сам скрипт с комментариями.

# Фильтр по типу объекта и по OU
$UserFilter = "(objectCategory=User)"
$ObjSearch = New-Object System.DirectoryServices.DirectorySearcher
$ObjSearch.PageSize = 10000
$ObjSearch.Filter = $UserFilter
$ObjSearch.SearchRoot = "LDAP://OU=Company_Users,dc=company,dc=ru"

# Коллекция всех пользователей в OU
$AllUser = $ObjSearch. FindAll()

# Получаем завтрашний день в формате строки день.месяц и день.месяц.год
$NextDay = (get-date).AddDays(1).ToString("dd.MM")
$NextDayFormat = (get-date).AddDays(1).ToString("dd.MM.yyyy")

# Параметры для отправки почты
$EmailFrom = "notice@company.ru"
$SmtpServer = "192.168.0.25"
$EmailTo="all@company.ru"
$Msg = New-Object Net.Mail.MailMessage
$Encoding = [System.Text.Encoding ]::UTF8

# Авторизация для сервера Exchange
# При первом запуске скрипта сохраним в текстовый файл зашифрованный пароль от пользователя, под которым будем авторизовываться на почтовом сервере
$GetCred = Get-Credential
$GetCred.Password | ConvertFrom-SecureString | Set-Content C:Temppassex.txt
# После первого запуска две строки сверху можно закомментить

$Pass = Get-Content C:Temppassex.txt | ConvertTo-SecureString
$Cred = New-Object System.Management.Automation.PsCredential ("notice@company.ru", $Pass)

# Перебор всех элементов коллекции
foreach ($User in $AllUser) {

# Получаем все атрибуты пользователя
$UserInf = $User. GetDirectoryEntry()

# Если extensionattribute10 непустой, то есть там есть какая-то дата
if ($UserInf.extensionattribute10 -ne "") {

# Получаем эту дату из 10-го атрибута
[string] $DayOfBirth = $UserInf.extensionattribute10

# Берем из строки первые пять символов (пример 01.10)
$DayOfBirth = $DayOfBirth. substring(0, 5)

# Если дата из атрибута 10 = дате завтрашнего дня
if ($DayOfBirth -eq $NextDay) {

# Формируем сообщение в формате HTML
$Msg.IsBodyHtml = $true
$Msg.Subject = "Напоминание: $NextDayFormat г. день рождения у сотрудника " + $UserInf. displayname
$Msg.Body = "
ДЕНЬ РОЖДЕНИЯ!

Завтра ( $NextDayFormat г.), " + $UserInf.displayname + " празднует день рождения!

"
send-MailMessage -SmtpServer $SmtpServer -To $EmailTo -From $EmailFrom -Credential $Cred -Subject $Msg.Subject -Body $Msg.Body -BodyAsHtml -Encoding $Encoding
}
}
}

Конечно, код скрипта не оптимален, зато, скорее всего, будет понятен всем.

Конкурс продолжается

Мы решили продлить конкурс и превратить его в постоянную акцию. Прислав нам описание хака, полезный совет или описание клевой неизвестной проги, ты по-прежнему можешь получить подписку на месяц, три месяца или, если постараешься, на год. Следуй рекомендациям и присылай свой текст!