Автоматическое наполнение группы AD через PowerShell

Обновлено 27.09.2023

Group Active directory logo

Добрый день! Уважаемые читатели и подписчики блога Pyatilistnik.org. В предыдущей статье я вас научил отключать встроенный антивирус в браузере Chrome, который дико нагружал своим процессом Software Reporter Tool.exe процессор, местами под 100%. Сегодня я хочу с вами поделиться скриптом PowerShell, который будит автоматически наполнять группу Active Directory по определенным критериям. Думаю, это будет полезно для многих системных администраторов.

Постановка задачи

У меня есть терминальная RDS ферма на базе Windows Server 2019, на ней работают свыше 1100 человек каждый день. Профили у пользователей перемещаемые, поэтому от их размера очень сильно зависит скорость их загрузки на RDSH хост и его обратная синхронизация при выходе. К сожалению нельзя выбрать, что будет частью перемещаемого профиля, а что нет и это плохо. В итоге у многих из них разбухает папка "Загрузки", как ее автоматически чистить я рассказывал, с помощью скрипта, который распространяется через групповые политики.

Как ограничить размер профилей, через дисковые квоты пользователей через NTFS

Данная политика и скрипт по очистке папки загрузка, выполняется только для определенной группы. Нам нужно автоматически туда и накидать людей. Что делает нижеописанный скрипт:

  • Необходимо оповестить пользователя 4 раза, о том, что его папка загрузки будет очищена и ему необходимо перенести его данные в облако
  • Создать папку с почтами сотрудника и сколько раз ему ушло уведомление
  • Вести подробный лог, о добавлении сотрудника в нужную группу и ошибки
  • Разбить добавление сотрудников на группы по 50 человек и добавить их в нужную группу

Содержание скрипта по автоматическому наполнению группы AD

function Date {Get-Date -Format "yyyy.MM.dd HH:mm:ss"}

# папка для хранения лог файлов с именем скрипта
$log_dir = "$PSScriptRoot\Logs\" + $($MyInvocation.MyCommand.Name -replace (".ps1", ""))
if (! (Test-Path $log_dir -PathType Container -ErrorAction SilentlyContinue))
{
New-Item $log_dir -ItemType D -Force | Out-Null
}

$log = "$log_dir\" + (Get-Date -Format "yyyy_MM_dd_HH_mm_ss") + ".log"

### Подключение к Active Directory

"$(Date) Start Processing" | Tee-Object $log -Append

$DC = (Get-ADDomain).ReplicaDirectoryServers | select -First 1
$GC = "$DC`:3268"

"$(Date) Will use $DC as DC and GC" | Tee-Object $log -Append

# Исходная группа откуда будут копироваться люди, тут может быть и пользователи домена и любая другая, у меня для нее дается доступ на RDS ферму
$group = "Farm-RDPusers-l"

# В какую группу мы будим добавлять пользователей
$group_target = "Farm-Folder-Downloads-cleanup-l"

# Количество уведомлений которое получит пользователь на почту перед добавлением в группу
$notification_number = 4

# Количество группирования
$max_users_to_process = 50

# Папка куда будет складываться лог с почтой сотрудника и количеством уведомлений отправленных ему
$user_folder = "$log_dir\Users"

if (! (Test-Path $user_folder -PathType Container -ErrorAction SilentlyContinue))
{
New-Item $user_folder -ItemType D -Force | Out-Null
}

"$(Date) Going to process group `"$group`" members" | Tee-Object $log -Append

$members = Get-ADGroup -Identity $group -Properties Members | Select-Object -ExpandProperty Members # | Get-ADObject -Server nw # -Server nw
$max_users_to_process_current = 0
foreach ($member in $members) # | Measure-Object # | select -First 25
{
"$(Date) Trying to process user `"$member`"" | Tee-Object $log -Append

$user = $mail = $current_notifications = $null
$user = Get-ADUser $member -Properties mail -Server $GC
$user_file = "$user_folder\$($user.mail).txt"

$mail = $user.mail

if ($mail -eq $null -or $user.Enabled -ne $true)
{
"$(Date) Skip user processing because mail attribute is null or he is disabled (mail is `"$mail`", Enabled is `"$($user.Enabled)`")" | Tee-Object $log -Append
Continue
}

if (Test-Path $user_file -PathType Leaf -ErrorAction SilentlyContinue)
{
[int]$current_notifications = Get-Content $user_file

if ($current_notifications -ge $notification_number)
{
"$(Date) Going to add user `"$mail`" to group `"$group_target`"" | Tee-Object $log -Append

try {
Add-ADGroupMember -Identity $group_target -Members $user -ErrorAction Stop
}
catch {
"$(Date) $($_.exception.message)" | Tee-Object $log -Append
}

"$(Date) Skip user processing because max_notification count is reached" | Tee-Object $log -Append
Continue
}
}
else
{
$max_users_to_process_current++
$current_notifications = 0
# "$(Date) Trying to process user `"$member`"" | Tee-Object $log -Append

if ($max_users_to_process_current -gt $max_users_to_process)
{
"$(Date) Skip user processing because max_users_to_process count is reached" | Tee-Object $log -Append
Continue
}
}

###

"$(Date) Going to send notification to `"$mail`", current notificaion count is `"$current_notifications`"" | Tee-Object $log -Append
# ".
$body = @"
<p>$($user.GivenName),</p>
<p>Через 4 дня Ваша папка "Загрузки" на терминале будет очищаться каждый раз при выходе из терминальной сессии.</p>
<p>Во избежание потери данных просим вас перенести все необходимое на личный гугл-диск через веб-интерфейс <a href = "https://drive.google.com">https://drive.google.com</a>.</p>
<p>Напоминаем Вам, что терминал не предназначен для длительного хранения объемных данных, это оказывает негативное влияние на работу всей системы. Вам доступны безлимитные личные гугл-диски.</p>

<p><i>Это письмо сформировано автоматически, отвечать на него не нужно.</i></p>
<p>Отдел технической поддержки

"@

# Настройка почтового сервера и отправки письма
$from = "support@pyatilistnik.org"
$to = $mail # "ivan@pyatilistnik.org #
$Subject = "Очистка папки `"Загрузки`" на терминале"
$smtpserver = "smtp.pyatilistnik.org"
$secure = $true
$port = 587 # TLS, for SSL use 465
$username = "support"
$password = "P@ssw0rd"

$message = New-Object System.Net.Mail.MailMessage
$message.From = $from
$message.To.Add($to)

$message.Subject = $Subject
$message.Body = $body
$message.IsBodyHtml = $true

$smtp = New-Object Net.Mail.SmtpClient($smtpserver)

try {
$smtp.Send($message)
}
catch {
"$(Date) $($_.exception.message)" | Tee-Object $log -Append
# Break
}

$current_notifications++
$current_notifications | Out-File $user_file
}

###

"$(Date) End Processing" | Tee-Object $log -Append

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

текст письма рассылки

В папке логов будут вот такие объекты, в виде текстовых файлов по датам и папка User.

Содержимое файла логов

В папке User будут так же созданы текстовые файлы с почтами сотрудников, в их содержании будет количество отправленных уведомлений.

Содержимое файла логов

Вот такой интересный скрипт по наполнению пользователей Active Directory. Скачать скрипт можно по ссылке. С вами был Иван Сёмин, автор и создатель IT портала Pyatilistnik.org.

Автор - Сёмин Иван

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *