Tag Archives: Send-MailMessage

Sending custom “password is about to expire” notifications with PowerShell

Sending out reminders to your users about changing their password before it expires could really take some load of the Helpdesk, and there are a few scripts available that does just that. What I found was that most of these scripts were assuming that everyone in the organization should get the same e-mail, which is not always true.

Therefore I wrote a new one where you could specify how the e-mail should look depending on where in your organization the user works. In our case, we needed to have different languages for different countries, the instructions were different aswell (some users needed to use a password change portal to change their passwords, others are using the classic “CTRL + ALT + DELETE”-method). We also have different contact information for the helpdesk in those countries and departments.

I will do a walk-through of this script to help you customize it to fit your organisation.

The first thing you need to do, is to decide when the users should receive a notification. This is done with these variables:

# Set when users should get a warning...

# First time
$FirstPasswordWarningDays = 14

# Second time
$SecondPasswordWarningDays = 7

# Last time
$LastPasswordWarningDays = 3

Users will then receive a warning 14 days, 7 days and finally 3 days before the password expires. Depending on how the number of days are rounded in the e-mail, it may differ a day from what you specify here.

You then need to set what smtp-server to use:

# Set SMTP-server
$SMTPServer = "MySMTP.Contoso.Com"

There is no need to change the next part of the code, it basically is just calculating when passwords will expire based on your domain policy and what you set in the variables above. It looks like this:

# Get the password expires policy
$PasswordExpiresLength = (Get-ADDefaultDomainPasswordPolicy).MaxPasswordAge

# Calculating when passwords would have been set if they expire today
$CurrentPWChangeDateLimit = (Get-Date).AddDays(-$PasswordExpiresLength.Days)

# Calculating all dates
$FirstPasswordDateLimit = $CurrentPWChangeDateLimit.AddDays($FirstPasswordWarningDays)
$SecondPasswordDateLimit = $CurrentPWChangeDateLimit.AddDays($SecondPasswordWarningDays)
$LastPasswordDateLimit = $CurrentPWChangeDateLimit.AddDays($LastPasswordWarningDays)

We are now ready to load the users, you might want to adjust the filter a bit depending on how your Active Directory design is. Just edit the first part of the filter (Mail -like ‘*@*’) to do this.

# Load the users
$MailUsers = Get-ADUser -Filter "(Mail -like '*@*') -AND `
(PasswordLastSet -le '$FirstPasswordDateLimit' -AND PasswordLastSet -gt '$($FirstPasswordDateLimit.AddDays(-1))' -OR `
PasswordLastSet -le '$SecondPasswordDateLimit' -AND PasswordLastSet -gt '$($SecondPasswordDateLimit.AddDays(-1))' -OR `
PasswordLastSet -le '$LastPasswordDateLimit' -AND PasswordLastSet -gt '$($LastPasswordDateLimit.AddDays(-1))') -AND `
(PasswordNeverExpires -eq '$false' -AND Enabled -eq '$true')" -Properties PasswordLastSet, DisplayName, PasswordNeverExpires, mail

We now got all the users, we just need to loop through them and send out the e-mails. This is where we need to specify which users should get which e-mail.

The comments should give you the information you need to customize it for your environment. Make sure you check out lines 13 and 19 below and change “MyOU1” and “MyOU2” to match your Organizational Units in Active Directory.

# Loop through them
foreach ($MailUser in $MailUsers) {

# Count how many days are left before the password expires and round that number
$PasswordExpiresInDays = [System.Math]::Round((New-TimeSpan -Start $CurrentPWChangeDateLimit -End ($MailUser.PasswordLastSet)).TotalDays)

# Write some status...
Write-Output "$($MailUser.DisplayName) needs to change password in $PasswordExpiresInDays days."

# Build the body depending on where in the organisation the user is

# Change MyOU1 to match your the OU you want your users are in.
if ($MailUser.DistinguishedName -like "*MyOU1*") {
$Subject = "Your password is expiring in $PasswordExpiresInDays days"
$Body = "Hi $($MailUser.DisplayName),

Your password is expiring in $PasswordExpiresInDays days. Please change it now!

Don't forget to change it in your mobile devices if you are using mailsync.

Helpdesk 1"
$EmailFrom = "Helpdesk 1 <[email protected]>"
}
# Change MyOU2 to match your environment
elseif ($MailUser.DistinguishedName -like "*MyOU2*") {
$Subject = "Your password is expiring in $PasswordExpiresInDays days"
$Body = "Hi $($MailUser.DisplayName),

Your password is expiring in $PasswordExpiresInDays days. Please change it now!

Don't forget to change it in your mobile devices if you are using mailsync.

Helpdesk 2"
$EmailFrom = "Helpdesk 2 <[email protected]>"
}
# This is the default e-mail
else {
$Subject = "Your password is expiring in $PasswordExpiresInDays days"
$Body = "Hi $($MailUser.DisplayName),

Your password is expiring in $PasswordExpiresInDays days. Please change it now!

Don't forget to change it in your mobile devices if you are using mailsync.

Helpdesk 3"
$EmailFrom = "Helpdesk 3 <[email protected]>"
}

# Time to send the e-mail

# The line below might need changing depending on what SMTP you are using (authentication or not)
Send-MailMessage -Body $Body -From $EmailFrom -SmtpServer $SMTPServer -Subject $Subject -Encoding UTF8 -BodyAsHtml -To $MailUser.mail

# E-mail is sent!
}

You also need to change the body/subject/mailfrom variables to match what you want to send out. Just add more “elseif”-clauses if you want to send out more versions, or remove them if you don’t need them.

And make sure you configure the “Send-MailMessage”-cmdlet correctly to use your smtp-server if you use authentication or a different port.

All you need to do after that is to schedule the script to run at the same time every day and you are done! (And some testing of course… 🙂 )

Leave a comment if you have any questions!

The complete and uncut code is available here.