I've run into many situations where we've needed to email end users of their pending password expiration. Sometimes it's remote users who don't see the password change alerts, sometimes it's just a way to show that the end user was notified their password was expiring. Here's the script I've cobbled together from various sources. It emails their password once it's 7 days out. I usually schedule the script to run daily at noon.
# Please Configure the following variables....
$smtpServer="smtp.domain.com"
$expireindays = 7
$from = "noreply@domain.com"
$logging = "Enabled" # Set to Disabled to Disable Logging
$logFile = "c:\logs\pwdemaillog.csv" # ie. c:\logs\pwdemaillog.csv
#$testing = "Enabled" # Set to Disabled to Email Users
$testRecipient = "adminuser@domain.com"
$date = Get-Date -format ddMMyyyy
#
###################################################################################################################
# Check Logging Settings
if (($logging) -eq "Enabled")
{
# Test Log File Path
$logfilePath = (Test-Path $logFile)
if (($logFilePath) -ne "True")
{
# Create CSV File and Headers
New-Item $logfile -ItemType File
Add-Content $logfile "Date,Name,EmailAddress,DaystoExpire,ExpiresOn"
}
} # End Logging Check
# Get Users From AD who are Enabled, Passwords Expire and are Not Currently Expired
Import-Module ActiveDirectory
$users = get-aduser -filter * -properties Name, PasswordNeverExpires, PasswordExpired, PasswordLastSet, EmailAddress |where {$_.Enabled -eq "True"} | where { $_.PasswordNeverExpires -eq $false } | where { $_.passwordexpired -eq $false }
$DefaultmaxPasswordAge = (Get-ADDefaultDomainPasswordPolicy).MaxPasswordAge
# Process Each User for Password Expiry
foreach ($user in $users)
{
$Name = $user.Name
$emailaddress = $user.emailaddress
$passwordSetDate = $user.PasswordLastSet
$PasswordPol = (Get-AduserResultantPasswordPolicy $user)
# Check for Fine Grained Password
if (($PasswordPol) -ne $null)
{
$maxPasswordAge = ($PasswordPol).MaxPasswordAge
}
else
{
# No FGP set to Domain Default
$maxPasswordAge = $DefaultmaxPasswordAge
}
$expireson = $passwordsetdate + $maxPasswordAge
$today = (get-date)
$daystoexpire = (New-TimeSpan -Start $today -End $Expireson).Days
# Set Greeting based on Number of Days to Expiry.
# Check Number of Days to Expiry
$messageDays = $daystoexpire
if (($messageDays) -ge "1")
{
$messageDays = "in " + "$daystoexpire" + " days."
}
else
{
$messageDays = "today."
}
# Email Subject Set Here
$subject="This is a friendly reminder that your network password will expire $messageDays"
# Email Body Set Here, Note You can use HTML, including Images.
$body ="
Dear $name,
<p> Your Password will expire $messageDays<br>
To change your password, press CTRL+ALT+DEL and select change password.<br>
<p>Thank you, <br>
<p>Company IT Team <br>
<p>it@domain.com<br>
</P>"
# If Testing Is Enabled - Email Administrator
if (($testing) -eq "Enabled")
{
$emailaddress = $testRecipient
} # End Testing
# If a user has no email address listed
if (($emailaddress) -eq $null)
{
$emailaddress = $testRecipient
}# End No Valid Email
# Send Email Message
if (($daystoexpire -ge "0") -and ($daystoexpire -lt $expireindays))
{
# If Logging is Enabled Log Details
if (($logging) -eq "Enabled")
{
Add-Content $logfile "$date,$Name,$emailaddress,$daystoExpire,$expireson"
}
# Send Email Message
Send-Mailmessage -smtpServer $smtpServer -from $from -to $emailaddress -bcc "adminuser@domain.com" -subject $subject -body $body -bodyasHTML -priority High
} # End Send Message
} # End User Processing
# End