Изменение паролей для всех пользователей в OU

Продолжая разговор о полезностях powershell-а давайте рассмотрим такую задачу.
Дано:
1. Энное количество пользователей-учеников какой нибудь системы обучения
2. При изменении политики паролей вам нужно поменять все пароли на произвольные.
Как бонус нужно отослать письмо о произведенных изменениях в отдел персонала.
Реализация:
Нужное подразделение (OU) или целое дерево условно находится в
$OU = "example.com/Units/"
Имя контейнера пусть будет
Pupils
При запуске скрипта производится обход дерева заданного в переменной $OU и для пользователей всех контейнеров с именем Pupils производится следующее:
1. пользователю создается новый пароль
1..6 | ForEach { $Password = $Password + [char]$rand.next(97,122) }
97,122 – диапазон используемых символов из таблицы ASCII
2. Данные о смененном пароле записываются в файл строкой.
Add-Content -Path $file -Value "Пользователь:$(ConvertFrom-DN($DN))`t Имя для входа - $($login)`t Новый пароль - $($Password)"
3. полученные файлы отчетов переименовываются в TXT файлы и отсылаются как вложение в необходимое подразделение. Формирование адреса подразделения производится следующим образом.
1. В функции get-Name в зависимости от имени юнита в котором находится учетная запись пользователя формируем первую часть адреса.
if ($DN.Contains("Unit01")) {$file="Unit1"}
Далее в функции send-Report добавляем к полученному имени окончание
$ToAddress = $name + "HRDepartment@example.com"
Собственно сам скрипт:
# в зависимости от имени подразделения формируем часть мыла
function get-Name {
param([string]$DN=(Throw ‘$DN is required!’))
$file = ""
if ($DN.Contains("Unit01")) {$file="Unit1"}
if ($DN.Contains("Unit02")) {$file="Unit2"}
$fullPath = $reportFolder+$file
return $fullPath
}
# конвертируем DN и извлекаем из него имя пользователя
function ConvertFrom-DN {
param([string]$DN=(Throw ‘$DN is required!’))
foreach ( $item in ($DN.replace(‘\,’,‘~’).split(","))) {
switch -regex ($item.TrimStart().Substring(0,3)) {
"CN=" {$CN = ‘/’ + $item.replace("CN=","");continue}
"OU=" {$ou += ,$item.replace("OU=","");$ou += ‘/’;continue}
"DC=" {$DC += $item.replace("DC=","");$DC += ‘.’;continue}
}
}
$canoincal = $cn.ToString().replace(‘~’,‘,’)
$canoincal = $cn.ToString().replace(‘/’,»)
return $canoincal
}
# меняем расширение файла
Function Rename-FileExtension($path, $newExtension) {
Get-ChildItem -path $path |
Foreach-Object {
if($_.extension.length -gt 0) {
$baseName = $_.name.remove($_.name.length - $_.extension.length)
} else {
$baseName = $_.name }
Rename-Item -Path $_.fullname -newname ($baseName + $newExtension) -Force
}
}
# отправка итогового отчета
function send-Report {
param([string]$file=(Throw ‘$messageBody is required!’))
$name = Split-Path $file -leaf
$ToAddress = $name + "HRDepartment@example.com"
Write-Host "Sendind report to $($ToAddress)"
Rename-FileExtension -path $file -newExtension ".txt"
$File = "$($file).txt"
$date = ( get-date ).ToString(‘dd-MM-yyyy’)
$FromAddress = "password.auditor@example.com"
$MessageSubject = "Change passwords report"
$MessageBody = "Change passwords report for $date."
$SendingServer = "xxx.xxx.xxx.xxx"
$SMTPMessage = New-Object System.Net.Mail.MailMessage $FromAddress, $ToAddress, $MessageSubject, $MessageBody
$Attachment = New-Object System.Net.Mail.Attachment $File
$SMTPMessage.Attachments.Add($Attachment)
$SMTPClient = New-Object System.Net.Mail.SMTPClient $SendingServer
$SMTPClient.Send($SMTPMessage)
}
#
#
$reportFolder="D:\Reports\passwords\"
Get-ChildItem -path $reportFolder | Remove-Item
# OU для обработки
$OU = "example.com/Units/"
Get-QADUser -SizeLimit 0 -SearchRoot $OU | ForEach-Object {
$DN = $_.DN
# Если в имени OU есть Pupils то начинаем обработку пользователей которые есть внутри
if ($DN.Contains("Pupils")) {
# генерим им пароль
$Password = ""
$rand = New-Object System.Random
1..6 | ForEach { $Password = $Password + [char]$rand.next(97,122) }
1..2 | ForEach { $Password = $Password + [char]$rand.next(48,57) }
$file = get-Name($DN)
$login = $_.LogonName
Add-Content -Path $file -Value "Пользователь:$(ConvertFrom-DN($DN))`t Имя для входа – $($login)`t Новый пароль – $($Password)"
$account = [ADSI]$ldapURL
$account.InvokeSet("SetPassword", $Password)
$account.setinfo()
} else {
#Write-Host "Пропускаем и идем дальше"
}
}
# отправляем отчеты
foreach ($file in gci $reportFolder) {
$name = split-path $file.fullname -Leaf
$fullName = $reportFolder + $name
send-Report $fullName
}