Notifications of expiration password in Active Directory with PowerShell
the Backstory
Started the whole story of what came next IT audit. Came serious uncles from Price Waterhouse Coopers, gave us a lot of guidance and a couple of scripts that had to run on the domain controller to then send them the logs. After reviewing the texts of the scripts (a little is that there safety is paramount) logs were provided to them. And then it began.
Requirements PWC in most cases, related security policies. One of them was to enter the password complexity policy and pasword lifetime. To do this, of course, was pretty easy, but soon we are faced with the following problem: Windows does not notify user about expiration of their password if the connection is via VPN from external network. The problem was quite serious because simply update the password and unlock the account of this user was no longer sufficient. You had to take your laptop in the home, office network. Given the fact that some users "live" in eternal mission — the problem was very serious. Manually tracking them is a pain, and not on alminski somehow. There appeared the idea to organize a mailing list for automatic notifications. After a short time spent on searches, was fair scriptwho remotely tried to perform the desired actions. I had to modify it.
Since it was my first experience writing a script under PowerShell, the time was spent a lot (nearly full time).
Script
And that's what I got:
the
Import-Module ActiveDirectory
#System globalization
#$ci = New-Object System.Globalization.CultureInfo("EN-us")
#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 = "notification@domain.com"
$msg.To.Clear()
$msg.To.Add($to)
$msg.Subject = "Password expiration notice"
$msg.Body =</pre><code> "<html><body><font face='Arial'>This is an automatically generated message from Exchange service.<br><br><b>Please note that the password for your account <i><u>Domain\$upn</u></i> will expire on $expiryDate.</b><br><br>Please change your password immediately or at least before this date as you will be unable to access the service without contacting your administrator.</font></body></html>"</code><pre>
}
EmailStructureReport Function($to)
{
$msgr.IsBodyHtml = $true
$msgr.From = "notification@domain.com"
$msgr.To.Add($to)
$msgr.Subject = "Script running report"
$msgr.Body = </pre><code>"<html><body><font face='Arial'><b>This is a daily report.<br><br>Script has successfully completed its work.<br>$NotificationCounter users have recieved notifications:<br><br>$ListOfAccounts<br><br></b></font></body></html>"</code><pre>
}
#Set the target OU that will be amazing 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
}
}
}
}
Write-Host "SENDING REPORT TO IT DEPARTMENT"
EmailStructureReport("itdepartment@domain.com")
$smtp.Send($msgr)
Saved it as a text file with the extension .ps1.
start Command
Next, create a file with the extension .cmd and write in it the option of running the script. I have, it looks like this:
powershell D:\ExchangeTools\pwde.ps1
Both files I have are on the mail server. You can try your own version.
create a schedule
Next, put in the schedule daily .the cmd file. I have it running every day at 11 am.
Start > All programs > Accesories > System tools > Task scheduler.
Click Action > Create new task.
On the General tab, click "Change user" select the user on whose behalf all of this will work. The user must have permission to read parameters needed for the script from AD. Set "Run whether user logged on or not" (to run regardless of logged in user or not). When you save the task, the system will ask you to enter the user's password.
Further, the Triggers tab. Everything is simple — set the start time as you need.
Tab Actions, click "New", select "Start a program" and specify the path to our .the cmd file. The last two tabs can not touch, but if necessary — make changes as you see fit.
Notifications are sent for 15, 7 and 3 days or less.
warning
Exchange server you need to specify your own address as a relay if you plan on sending to addresses outside of the domain (the duplication for the personal address, for example).
Some will probably ask — "why take the address of ExtensionAttribute if there is a standard field containing the user's e-mail?". The answer is simple — a copy of each notification slesa also in the IT department, the user can have more than one address and some system accounts do not have mailboxes in principle, but the notices they need to make life easier directly to the administrators. To enter addresses in ExtensionAttribute15 you will be able going to the Active Directory tree on the domain controller with administrator rights. In account properties tab "Attribute Editor". If the addresses field is a few — to share their should be a comma.
Комментарии
Отправить комментарий