Email Users If Their Active Directory Password is set to Expire Soon

Email Users If Their Active Directory Password is set to Expire Soon

In this article I will show you how PowerShell can automatically send an e-mail notification to end users when their Active Directory password is set to expire soon. I looked over several other similar scripts on TechNet but ended up writing one from scratch to incorporate several features I needed, as well as improve on the overall script flow.

Some of the requirements I needed to meet were as follows:

  1. Get users email addresses from the Email Address value in Active Directory, if it’s empty look at the default address in the proxyaddresses attribute
  2. Send E-mail to users with passwords that were expiring in 7 days or less
  3. Include directions users can follow to reset their Active Directory password
  4. Send E-mail with high priority
  5. Get E-mail notification if sent or failed
  6. Store the credential in a Cred object so it’s secure
  7. Advanced logging on the script for troubleshooting
  8. Send E-mail from Office 365
  9. Set up the script as a scheduled task

User E-Mail Address

One of the key pieces I wanted was to check the users proxyaddresses attribute for a default e-mail address if the E-mail entry in the users Active Directory properties was empty. Many scripts I found online only looked at the E-mail value, so if there was nothing there it would just fail instead of looking at other places. In a lot of environments I have seen that not all users had the E-mail value filled out, but had their default e-mail address and aliases in the proxyaddresses attribute. For Office 365, if you sync your Active Directory this is where it will get the default e-mail address, and any other proxy addresses for Exchange. The script will find the default value by looking at what’s in the proxyaddresses attribute and looking for the value with a capital “SMTP”.

E-Mail Format

In my e-mail I wanted to first greet the user by their Name. This isn’t hard as all we have to do is pass something like their DisplayName value to a variable and add that to the body. Second, I wanted to send the e-mail with high importance, this will show a red exclamation mark next to the e-mail. The subject of the email would tell the user how many days until their password is expired and lastly, if the user wanted to reach to our IT team it would have our contact information followed by our signature.

An e-mail notification would be sent back to the sending address on any failure or any success. This would include the actual e-mail that was sent to the user in an attachment, and the subject of the e-mail. If you have a password portal, on-premise exchange or Office 365 password write-back you could also include a link in the e-mail where users can click and reset their passwords.

SMTP

Since my mail server is Office 365 I want to send mail authenticated, and use SSL. The user I am using to authenticate against the SMTP server must also either be the sending user, or have Send-As rights on the sending user. When the script runs it will search for its credential object, if the credential object is not there it will prompt you for credentials (its best to run this manually first to input and have it store the credentials before setting it up as a scheduled task). As we see in the Get-Credential message it reminds you that this account must be the sender, or have proper permissions.

Sending E-Mail

There are two ways you can go about sending mail with PowerShell. You can use the System.Net.Mail Namespace or use the Send-MailMessage cmdlet. If you want to set this up as a scheduled task I recommend using the System.Net.Mail Namespace (which I use in the script), as you will run into issues trying to use Send-MailMessage unattended.

In the scriptblock below I am calling the Namespace, setting the From, SMTP Host, SSL, Credentials, To, Subject, Delivery Notifications, Priority and Body.

Logging

Using Write-Host and Try/Catch blocks I can log every step of the script and any running errors. The log will be saved at the same $DirPath location which I set at C:\Automation\PasswordExpiry.  In this folder it will store the log as well as the credential object. Here is my log file:

If you run the script manually the shell will also display its progress to you.

 

Credential

The script will store your Office 365 / authentication credentials by using the Export-CLIXML cmdlet. This allows us to store away the entire System.Management.Automation.PSCredential Object as an XML file. the Export-CliXml cmdlet encrypts credential objects using the Windows standard Data Protection API. It’s always best to store credentials of a user with no administrative roles in your Office 365 / Mail environment.

 

The Script

 

 

My name is Bradley Wyatt; I am currently a Technology Specialist at Porcaro Stolarek Mete Partners which is headquartered in Chicago, Illinois. At PSM we provide solutions which are custom designed around the specific needs of each client.

7 thoughts on “Email Users If Their Active Directory Password is set to Expire Soon

  1. Just found your blog through Reddit. This is something I would like to have in place. Will this work if I am using a local installation of office pro 2016 and A local exchange server?

    Thanks
    Ciarán

    1. The installation of Office doesn’t matter. This will work with local Exchange. You just need to modify the SMTP info to not go to Office 365. (ports, authentication, etc)
      let me know if you’re needing assistance.

  2. Hello brad thanks for great script!
    But i have an error to sending email I a time out message
    Exception calling “Send” with “1” argument(s): “The operation has timed out.”
    At line:150 char:4
    + $smtpclient.Send($mailmessage)
    + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo : NotSpecified: (:) [], MethodInvocationException
    + FullyQualifiedErrorId : SmtpException

    do you have any idea?
    thanks

  3. Brad!

    AWESOME Script nice work!!

    Do you have any tips on how to automate this, I have tried using scheduler but it throws this…

    Exception calling “Send” with “1” argument(s): “The SMTP server requires a secure connection or
    the client was not authenticated. The server response was: 5.7.57 SMTP; Client was not
    authenticated to send anonymous mail during MAIL FROM [AM5PR0402CA0022.eurprd04.prod.outlook.com]”
    At C:\passwordreminder.ps1:173 char:4
    + $smtpclient.Send($mailmessage)
    + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo : NotSpecified: (:) [], MethodInvocationException
    + FullyQualifiedErrorId : SmtpException

    I think its because the SMTP needs auth but can get it when run from Scheduler.

    Any ideas?

    Darren

Leave a Reply

Your email address will not be published. Required fields are marked *