Powershell: Users and passwords about to expire

So, it’s that time of year; people heading back and forth on vacation and meanwhile their Active Directory password expires. People tend to miss the default notification popping up in Windows and have done so since forever.

So how about getting an annoying email every day, 7 days prior to the actual expiration? The main goal here is to avoid having users ending up with expired password, and thus causing troubles for the user and generating calls to helpdesk.

Here’s how I do using Powershell: (Some of the body text is in danish because lazy, and my syntax highlighter is on vacation too. Just copy/paste the code directly into your PS ISE, save the script and schedule it to run through Task Scheduler and you’re set. 🙂

<#
.DESCRIPTION
    Loops through all AD users in specified OUs, and check for password expiry date. If is about to expire (7 days) send the user an email about the password is about to expire

.AUTHOR
    Martin Bengtsson - imab.dk
#>

try {
    Import-Module ActiveDirectory -ErrorAction Stop
} 
catch {
    Write-Error "Active Directory module failed to Import. Terminating the script."
    exit(1)
}

#Email SMTP variables
$AnonUsername = "anonymous"
$AnonPassword = ConvertTo-SecureString -String "anonymous" -AsPlainText -Force
$AnonCredentials = New-Object System.Management.Automation.PSCredential($AnonUsername,$AnonPassword)
$SMTPServer = "smtp.yoursmtp.com”
$From = "Helpdesk <hlp@yourdomain.com>"
$Subject = "Password will expire soon!"

#What OUs to look for users
$OUs = "CN=Schema,CN=Configuration,DC=EUROPE,DC=TEST,DC=CONTOSO,DC=COMe"

#Get todays date and format as string dd/MM/yyyy
$Today = (Get-Date).ToString("dd/MM/yyyy")

#Find all the users and select the objects we need
$Users = ForEach ($OU in $OUs) {Get-ADUser -SearchBase $OU -Filter {Enabled -eq $True -and PasswordNeverExpires -eq $False} –Properties "DisplayName", "Mail", "msDS-UserPasswordExpiryTimeComputed" | Select-Object -Property "Displayname","mail",@{Name="ExpiryDate";Expression={[datetime]::FromFileTime($_."msDS-UserPasswordExpiryTimeComputed")}} | % {

#Store selected objects into variables
$Name = $_.Displayname
$To = $_.Mail
$ExpiryDate = $_.ExpiryDate

#Format the date to same format as used in $Today
$ExpiryDate = $ExpiryDate.ToString("dd/MM/yyyy")

#Count the days intil expiration
$DateDiff = New-TimeSpan -Start $Today -End $ExpiryDate

#If less than or equal to 7 days until expiration, create and send HTML email
If ($DateDiff.Days -le 7 -and $DateDiff.Days -ge 0){

    $Body = "
    <html>
    <head>
    <style type='text/css'>
    h1 {
    color: #f07f13;
    font-family: verdana;
    font-size: 20px;
    }

    h2 {
    color: ##002933;
    font-family: verdana;
    font-size: 15px;
    }

    body {
    color: #002933;
    font-family: verdana;
    font-size: 13px;
    }
    </style>
    </head>
    <h1>Dit kodeord udløber snart!</h1>
    <body>
    Kære $Name<br/><br/>
    Dit kodeord udløber om <b>$($DateDiff.Days)</b> dage og har derfor endeligt udløb <b>$ExpiryDate</b>.<br/><br/>
    Husk at skifte kodeord ved CTRL+ALT+DEL, og vælg 'Change a Password'.<br/><br/>
    Skifter du ikke kodeord i tide, så vil du opleve at din iPhone ikke kan modtage/sende e-mails, og at applikationer ikke virker som tiltænkt.<br/><br/>
    Mvh Helpdesk
    </body>
    </html>
    "
    #Override to for testing purposes
    $To = "mab@imab.dk"
    
    #Send the mail message
    Send-MailMessage -To $To -Bcc mab@kromannreumert.com -From $From -Subject $Subject -Body $Body -SmtpServer $SMTPServer -BodyAsHtml -Credential $AnonCredentials -Encoding Unicode
    
    Write-Host -ForegroundColor Cyan "$Name --- $To --- $ExpiryDate"
    #Pause for testing purposes
    Pause
    }
}
}

Preview of the email being sent. Also in danish because lazy.

Leave a Comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.