Уведомления об истечении срока действия пароля в Active Directory средствами PowerShell

1805
Уведомления об истечении срока действия пароля в Active Directory средствами PowerShell
Уведомления об истечении срока действия пароля в Active Directory средствами PowerShell

Import-Module ActiveDirectory

#System globalization
#$ci = New-Object System.Globalization.CultureInfo("ru-RU")

#SMTP server name
$smtpServer = "mail.domain.local"

#Creating a Mail object
$msg = new-object Net.Mail.MailMessage
#Creating a Mail object for report
$msgr = new-object Net.Mail.MailMessage

#Creating SMTP server object
$smtp = new-object Net.Mail.SmtpClient($smtpServer)


#E-mail structure
Function EmailStructure($to,$expiryDate,$upn)
{
    $msg.IsBodyHtml = $true
    $msg.From = "[email protected]"
    $msg.To.Clear()
    $msg.To.Add($to)
    $msg.Subject = "Password expiration notice"
    $msg.Body =</pre><code> "&lthtml&gt&ltbody&gt&ltfont face='Arial'&gtThis is an automatically generated message from Exchange service.&ltbr&gt&ltbr&gt&ltb&gtPlease note that the password for your account &lti&gt&ltu&gtDomain\$upn&lt/u&gt&lt/i&gt will expire on $expiryDate.&lt/b&gt&ltbr&gt&ltbr&gtPlease change your password immediately or at least before this date as you will be unable to access the service without contacting your administrator.&lt/font&gt&lt/body&gt&lt/html&gt"</code><pre>
}

Function EmailStructureReport($to)
{
    $msgr.IsBodyHtml = $true
    $msgr.From = "[email protected]"
    $msgr.To.Add($to)
    $msgr.Subject = "Script running report"
    $msgr.Body = </pre><code>"&lthtml&gt&ltbody&gt&ltfont face='Arial'&gt&ltb&gtThis is a daily report.&ltbr&gt&ltbr&gtScript has successfully completed its work.&ltbr&gt$NotificationCounter users have recieved notifications:&ltbr&gt&ltbr&gt$ListOfAccounts&ltbr&gt&ltbr&gt&lt/b&gt&lt/font&gt&lt/body&gt&lt/html&gt"</code><pre>
}

#Set the target OU that will be searched for user accounts
$OU = "OU=Organisation,DC=domain,DC=local"

</pre><code>$ADAccounts = Get-ADUser -LDAPFilter "(objectClass=user)" -searchbase $OU -properties PasswordExpired, extensionAttribute15, PasswordNeverExpires, PasswordLastSet, Mail, Enabled | Where-object {$_.Enabled -eq $true -and $_.PasswordNeverExpires -eq $false}</code><pre>
$NotificationCounter = 0
$ListOfAccounts = ""

Foreach ($ADAccount in $ADAccounts)
{
 $accountFGPP = Get-ADUserResultantPasswordPolicy $ADAccount
                if ($accountFGPP -ne $null)
        {
                 $maxPasswordAgeTimeSpan = $accountFGPP.MaxPasswordAge
        }
        else
        {
                 $maxPasswordAgeTimeSpan</pre><code> = (Get-ADDefaultDomainPasswordPolicy).MaxPasswordAge</code><pre>
                }

#Fill in the user variables
    $samAccountName = $ADAccount.samAccountName
    $userEmailAddress = $ADAccount.ExtensionAttribute15
    $userPrincipalName = $ADAccount.UserPrincipalName

    if ($ADAccount.PasswordExpired)
    {
     Write-host "The password for account $samAccountName has expired!"
    }
    else
    {
     $ExpiryDate = $ADAccount.PasswordLastSet + $maxPasswordAgeTimeSpan
     $TodaysDate = Get-Date
     $DaysToExpire = $ExpiryDate - $TodaysDate
#Calculating DaysToExpireDD to DD format (w/o fractional part and dot)
     $DaysToExpireDD = $DaysToExpire.ToString() -Split ("\S{17}$")
     Write-host </pre><code>"The password for account $samAccountName expires on: $ExpiryDate. Days left: $DaysToExpireDD"</code><pre>
        if (($DaysToExpire.Days -eq 15) -or </pre><code>($DaysToExpire.Days -eq 7) -or ($DaysToExpire.Days -le 3))</code><pre>
        {
         $expiryDate = $expiryDate.ToString("d",$ci)
#Generate e-mail structure and send message
            if ($userEmailAddress)
            {
     		 EmailStructure $userEmailAddress $expiryDate $samAccountName
     		 $smtp.Send($msg)
    			 Write-Host </pre><code>"NOTIFICATION - $samAccountName :: e-mail was sent to $userEmailAddress"</code><pre>
   			 $NotificationCounter = $NotificationCounter + 1
    			 $ListOfAccounts = </pre><code>$ListOfAccounts + $samAccountName + " - $DaysToExpireDD days  left. Sent to $userEmailAddress&ltbr&gt"</code><pre>
            }
   		}
    }
}
Write-Host "SENDING REPORT TO IT DEPARTMENT"
EmailStructureReport("[email protected]")
$smtp.Send($msgr)
  1. Необходимо сохранить скрипт как текст в файл с расширением .ps1.
  2. Необходимо создать файл с расширением .cmd
  3. В файл с расширением .cmd пишем powershell D:\ExchangeTools\pwde.ps1

График выполнения скрипта Active Directory

Ставлю в расписание ежедневный запуск .cmd файла в 11 утра (вы можете выбрать свое время)

Системный администратор

Start > All programs > Accesories > System tools > Task scheduler.
Жмем Action > Create new task.

На вкладке General жмем кнопку «Change user» выбираем пользователя, от имени которого всё это будет работать. У пользователя должны быть права на считывание параметров, необходимых для скрипта из AD. Ставим «Run whether user logged on or not» (запускать независимо от того, залогинен пользователь или нет). При сохранении задачи система попросит вас ввести пароль пользователя.

Далее вкладка Triggers. Тут всё просто — настраиваете время запуска как вам нужно.

Вкладка Actions, жмем «New», выбираем «Start a program» и указываем путь к нашему .cmd файлу. Последние две вкладки можно не трогать, но если есть необходимость — внесите изменения как считаете нужным.

Уведомления посылаются за 15, 7 и 3 и менее дней.

ВНИМАНИЕ
Exchange серверу нужно указать собственный адрес в качестве релея если планируется отправка на адреса, находящиеся вне домена (дублирование на личный адрес, например).

Некоторые, вероятно, спросят — «зачем же брать адрес из ExtensionAttribute если есть стандартное поле содержащее e-mail пользователя?». Ответ прост — копия каждого уведомления шлется также в IT department, у пользователя может быть не один адрес и некоторые системные аккаунты не имеют почтовых ящиков в принципе, но уведомления о них нужны для облегчения жизни уже непосредственно администраторам. Вписать адреса в ExtensionAttribute15 вы сможете зайдя в дерево Active Directory на контроллере домена с правами администратора. В свойствах аккаунта будет вкладка «Attribute Editor». Если адресов в поле будет несколько — разделять их следует запятой.