Tuesday, April 28, 2020

Email users of password expiration

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