Expire Password and Email Notification


Here is a script that will find users who’s password that will expire in 30 days and email them.

#Load Variables
$expUsers = @();
$cdate = Get-Date -Format MM-dd-yyyy;
$result = @();
$users =@();
$mdate = (Get-Date).AddDays(30);

#List Active Users in the Users OU with Password Never Expires attribute False
$users = Get-ADUser -Filter {enabled -eq $true} -SearchBase “OU=Users,DC=YOUR,DC=DOMAIN” -Properties “msDS-UserPasswordExpiryTimeComputed”,“Mail”,“PasswordneverExpires” | Where {($.Mail -like “YOURDOMAIN.COM”) -and ($.PasswordNeverExpires -eq $false)} | Select SamAccountName,Mail,Name,Enabled,msDS-UserPasswordExpiryTimeComputed,PasswordNeverExpires;

#Convert Expiration Date to MM/dd/YYYY format
$expUsers = $users | select -Property “SamAccountName”,“Name”,“Mail”,“Enabled”,“PasswordNeverExpires”,@{Name=“ExpirationDate”;Expression={[datetime]::FromFileTime($_.“msDS-UserPasswordExpiryTimeComputed”)}};

#Get Users whos’s expiring in 30 Days
$exp_Users = $expUsers | Where {$.ExpirationDate -lt $mdate -and $.ExpirationDate -gt $cdate}

foreach ($user in $exp_Users){

#Convert data to make it readable
$result += New-Object -TypeName psobject -Property @{

SamaccountName = @($user).SamaccountName;
Name = @($user).Name;
Mail = @($user).Mail;
Enabled = @($user).Enabled;
PasswordNeverExpires = @($user).PasswordNeverExpires;
ExpirationDate = @($user).ExpirationDate;


#Export Users with Password Never Expires
$result | Sort ExpirationDate | Export-Csv -NoTypeInformation d:\scripts\ad\ExpiringPasswords-$cdate.Csv

#Load CSV File
$ExUsers = Import-Csv D:\Scripts\AD\ExpiringPasswords-$cdate.Csv

#Get User count
$c = $ExUsers | Measure;

#Load Encoding Format
$encode = [System.Text.Encoding]::UTF8;

#Loop through users to send email for Expired Passwords
For ($i = 0; $i -lt $c.Count; $i++)
$Name = @($exUsers.Name[$i]);
$ExpDate = @($exUsers.ExpirationDate[$i]).substring(0,10);
$email = @($exusers.mail[$i]);

$Subject = “Your Account Password Will Expire on $expdate”
$Body = “Dear $Name,

Your Account Password will expire on $expdate. Please change your password.


#Send-MailMessage -from “ExpirationNotify@YOURDOMAIN.COM” -To $email -Subject $Subject -Body $Body -Priority High -Encoding $encode -SmtpServer “YOURSMTPServer.COM”;

I hope this helps someone out :slight_smile:

Alex Nicastro

Thank you!

Consider refactoring that into a function of some sort, and publishing it as a module to PowerShell Gallery. I’m sure many WILL find it useful!

Here is another doing the same thing. We need to send the message in multiple languages so there is some language specific fixing. I had some troubles with sending emails so I made double logging. This is run twice a week as a scheduled job.


    $expireindays = 14
    $from = "Automated IT "
    $logging = "Enabled" # Set to Disabled to Disable Logging
    $testRecipient = ""
    $date = Get-Date -format ddMMyyyy
    $maxDomainPasswordAge = (Get-ADDefaultDomainPasswordPolicy).MaxPasswordAge 

#Logging options
    $logFile = "\\path\$(get-date -Format yyyy-MM-dd)_passwordLog.csv" 
    $EmailLogFile = "\\path\$(get-date -Format yyyy-MM-dd)_email.csv"
    New-Item $logfile -ItemType File -Force
    Add-Content $logfile "Date,Name,EmailAddress,DaystoExpire,ExpiresOn"
    New-Item $EmailLogFile -ItemType File -Force
    Add-Content $EmailLogFile "Date,Name,EmailSent"

$users = get-aduser -filter {(PasswordNeverExpires -eq $false) -and (Enabled -eq "true")} -properties Name, PasswordNeverExpires, PasswordExpired, PasswordLastSet, EmailAddress | where { $_.passwordexpired -eq $false }

ForEach ($user in $users) {  
    $Name = $user.Name
    $emailaddress = $user.emailaddress
    $passwordSetDate = $user.PasswordLastSet
    $PasswordPol = (Get-AduserResultantPasswordPolicy $user)
    # Determine Max Password Age
    if (($PasswordPol) -ne $null) 
        $maxPasswordAge = ($PasswordPol).MaxPasswordAge
        } #End if ($PasswordPol)

        $maxPasswordAge = $maxDomainPasswordAge 
        } #End Else if (($PasswordPol) -ne $null)

    $expireson = $passwordsetdate + $maxPasswordAge

    $daystoexpire = (New-TimeSpan -Start $(get-date) -End $Expireson).Days

    $messageDays = $daystoexpire

    if (($daystoexpire -ge "0") -and ($daystoexpire -lt $expireindays))

        if (($messageDays) -ge "1")

            $messageDays = "in " + "$daystoexpire" + " days"
	        $messageDaysRU = "$daystoexpire"
	        $messageDaysFI = "$daystoexpire" + " päivän kuluttua"
	        $messageDaysSE = "om " + "$daystoexpire" + " dagar"
            } #End if (($messageDays) -ge "1")
            $messageDays = "today"
	        $messageDaysRU = "сегодня"
	        $messageDaysFI = "tänään"
	        $messageDaysSE = "i dag"
            } #End Else if (($messageDays) -ge "1")

        # Email Subject Set Here
        $subject="Your password will expire $messageDays - Срок действия пароля истекает через $messageDaysRU дн."
        # Email Body Set Here, Note You can use HTML, including Images.
        $body ="
        Dear $name,
         Your Password will expire $messageDays.
        Hyvä $name, 
        Salasanasi vanhenee $messageDaysFI.
        Hej $name, 
        Ditt lösenord kommer att löpa ut $messageDaysSE. 

        Add-Content $logfile "$date,$Name,$emailaddress,$daystoExpire,$expireson" 
        #test sending
        if ($emailaddress) {
            try {

                Send-Mailmessage -smtpServer $smtpServer -from $from -to $emailaddress -subject $subject -body $body -bodyasHTML -priority High -Encoding ([System.Text.Encoding]::UTF8) -ErrorAction stop
                "$date,$Name,Yes" | out-file $EmailLogFile -Append


            catch {
                "$date,$Name,No" | out-file $EmailLogFile -Append
            } #End If
        Else {
            "$date,$Name,No" | out-file $EmailLogFile -Append

            } #End Else
        } # End if (($daystoexpire -ge "0") -and ($daystoexpire -lt $expireindays))

} #End ForEach ($user in $users)