Powershell for Password Expiration notices

Wednesday 30 of May, 2012

We have a group of folks who only ever remote into our environment and because of that often don't receive password expiration notices from Windows. As luck would have it, often their passwords expire over the weekend and they're locked out until Monday morning. We devised this script to send email notifications in advance of expiration.

First I went spelunking because I'm lazy and I know I'm not the first to need to do this. I found an excellent module in the TechNet Script Repository called Search-ADUserWithExpiringPasswords (cache). It's contributed by Steve Blossom and I thank him for doing the heavy lifting for this project!

The script has one shortcoming. It doesn't allow you to restrict which OUs to search. I've posted a script modification in the Q&A for Steve's upload.

The next step was to wrap some code around the module to do what we needed it to do.

The script starts by setting a few constants and including the Search-ADUserWithExpiringPasswords module.

$smtpserver = "mail.myco.com" 
  $emailFrom = "HelpDesk@myco.com" 
  $HelpDeskTo = "HelpDesk@myco.com"
  $DaysToNotify = "7"
  $SendEmpEmail = $True
. C:\NetAdmin\Notify-PasswordExpiration\Search-ADUSerWithExpiringPwd.ps1
Function CPwdLastSet ($pls)

Next, we reset some counters and do the actual search

$logtxt = ""
$count = 0
Search-ADUserWithExpiringPasswords -searchbase "ou=home_employee,ou=user accounts, `
ou=ourOffice,dc=myco,dc=com" -TimeSpan $DaysToNotify `
-Properties mail,PwdLastSet,givenName,sn|`

This command from Steve's module searches the OU specified for passwords expiring in $DaysToNotify (in this case 7) and returns the necessary attributes. Notice that the search command is not terminated but is the beginning of a pipeline to the remainder of the script. The next part of that pipeline processes each returned user object and sends email.

ForEach-Object {
  $today = Get-Date 
  $logdate = Get-Date -format yyyyMMdd 
  $samaccountname = $_.samAccountName 
  $FName = $_.givenName
  $Lname = $_.sn
  $count += 1
  $emailTo = $_.mail  
  $passwordLast = cPwdLastSet($_.pwdLastSet) #this is a date now
	$maxAge = (new-object System.TimeSpan((Get-ADObject (Get-ADRootDSE).defaultNamingContext -properties maxPwdAge).maxPwdAge))
	$passwordexpirydate =  $passwordLast.subtract($maxAge)
  $daystoexpiry = ($passwordexpirydate - $today).Days
  $expirationDate = $passwordexpirydate.ToString("D")

This part of the foreach loop calculates the number of days to password expiration, and the expiration date so we can use them in the email message.

$subject = "Your network password will expire soon."     
  $body = "$FName $LName, `n`n" 
  $body += " Your password will expire in $daysToExpiry day(s) on $ExpirationDate.  Please change your password before it expires to ensure you can continue to work. `n`n" 
  $body += "For instruction on how to change your password please refer to this document on the Employee Zone: http://OurSharepoint/SiteDirectory/ee_Info/Shared%20Documents/NetAdmin/HomeworkerPwChange.doc"
  $body += " `n`nIf you are unable to change your password, please contact us at 215 734-2253 `n`n" 
  $body += "Thank you! `n`nYour SysOps Team"
   #Employee notification
   if ($SendEmpEmail) {
	#Send-MailMessage -To $emailTo -From $emailFrom -cc "gmartin@myco.com" -Subject $subject -Body $body  -SmtpServer $smtpserver 
	Send-MailMessage -To $emailTo -From $emailFrom -Subject $subject -Body $body  -SmtpServer $smtpserver 

   $logtxt += $today.ToString("d")
   $logtxt +=" Email was sent to $samAccountName for password expiring on $passwordexpirydate`n" 

The next section of the foreach, generates the text for the mail message and sends it using Send_MalMessage.

Finally, we generate a summary message for the helpdesk.

$logtxt += @"
   $count employee(s) notified.
   This message is sent from a scheduled task called Notify-PasswordExpiration running on ADMON.  The task queries Active Directory 
   for homeworker accounts whose password are expiring in the next 7 days and emails the employee.  It also notifies Help Desk with a summary. 
   No action is generally necessary except by the notified employees.  Please see the Windows Engineering team if you need assistance.

Task home:

Last update:
May 2012
	#system notification
  #Send-MailMessage -To $emailFrom -From $emailFrom -Subject "Password Expiration notices" -Body $logtxt  -SmtpServer $smtpserver 
  Send-MailMessage -To $HelpDeskTo -From $emailFrom -cc "gmartin@myco.com" -Subject "Password Expiration notices" -Body $logtxt  -SmtpServer $smtpserver

A coupe other notes:

Leave a comment if you have questions

Permalink: https://tiki.gmartin.org/tiki-view_blog_post.php?postId=170