There is a great PowerShell Script out there to email folks 10 days prior to password expiration…
Set-ExecutionPolicy UnRestricted
cls
#############################################################################
Created by Levente Veres (bergermanus)
Contact: http://my.bergersoft.net
Description: The current script send Alert for users before they password
expires. You can set some values to configure this script.
############################################################################
###############################################################################
Get The max Password age from AD
###############################################################################
function Get-maxPwdAge{
$root = [ADSI]“LDAP://chch.loc”
$filter = “(&(objectcategory=domainDNS)(distinguishedName=DC=codespring,DC=local))”
$ds = New-Object system.DirectoryServices.DirectorySearcher($root,$filter)
$dc = $ds.findone()
$dc.Properties | fl
[int64]$mpa = ($dc.Properties[‘maxpwdage’][0]).ToString().Trim(“-”)
#$mpa*(.000000100)/86400
}
###############################################################################
Function to send email to each user
###############################################################################
function send_email_user ($remaining_day, $email, $name )
{
$today = Get-Date
$date_expire = [DateTime]::Now.AddDays($remaining_day) ;
$SmtpClient = new-object system.net.mail.smtpClient
$mailmessage = New-Object system.net.mail.mailmessage
$SmtpClient.Host = “astaro.chch.loc”
$mailmessage.from = “helpdesk@chch.org”
$mailmessage.To.add($email)
$mailmessage.Bcc.add(“teach@chch.org”)
$mailmessage.Subject = “$name, Your Domain & E-Mail Password Expires ”
$mailmessage.IsBodyHtml = $true
$mailmessage.Body = “<h3>Dear $name </h3>”
$mailmessage.Body +=“<h4> Your login password for account <font color=red>$email</font> on use of the CH-CH computers, Wi-Fi and Email will be expire in <font color=red>$remaining_day</font> days on $date_expire</h4>”
$mailmessage.Body +=“Please login to a CH-CH lab computer or a Faculty/Staff Laptop connected with a Network Cable. You then can change your password. Changing your password can be done by hitting CTRL-ALT-DEL and selecting change password. Failing to do so could result in getting locked out of the system then requiring a password reset by the help desk!<br /><br />”
$mailmessage.Body += " Generated on : $today<br /><br />"
$mailmessage.Body += “================================== <br />”
$mailmessage.Body += “CH-CH Technology Help Desk <br />”
$mailmessage.Body += “HelpDesk@chch.org <br />”
$smtpclient.Send($mailmessage)
}
###############################################################################
Send REPORT for Admins
###############################################################################
function sendmail($body)
{
$today = Get-Date
$SmtpClient = new-object system.net.mail.smtpClient
$mailmessage = New-Object system.net.mail.mailmessage
$SmtpClient.Host = “astaro.chch.loc”
$mailmessage.from = “helpdesk@chch.org”
$mailmessage.To.add(“helpdesk@chch.org”)
$mailmessage.Subject = “[Report] chch.loc password expires”
$mailmessage.IsBodyHtml = $true
$mailmessage.Body = “<h4>Generated on : $today n</h4>" + $body $mailmessage.Body += "n” + $body1
$smtpclient.Send($mailmessage)
}
###############################################################################
Search for the active directory users with following conditions
1. Is in USER category
2. Is loged in more that 1 times - for eliminate the system accounts
3. Eliminate the Disbaled Accounts
###############################################################################
$strFilter = “(&(objectCategory=User)(logonCount>=1)(!userAccountControl:1.2.840.113556.1.4.803:=2))”
$objDomain = New-Object System.DirectoryServices.DirectoryEntry
$objSearcher = New-Object System.DirectoryServices.DirectorySearcher
$objSearcher.SearchRoot = $objDomain
$objSearcher.PageSize = 1000
$objSearcher.Filter = $strFilter
$colResults = $objSearcher.FindAll();
#SET the max day before expiration alert
$max_alert = 10
###############################################################################
#SET the max password lifetime
In the future i rewrite to ask teh GP for the group.
###############################################################################
$max_pwd_life= get-maxPwdAge;
$userlist = @()
foreach ($objResult in $colResults)
{$objItem = $objResult.Properties;
if ( $objItem.mail.gettype.IsInstance -eq $True)
{
$user_name = $objItem.name
$user_email = $objItem.email
#Transform the DateTime readable
$user_logon = [datetime]::FromFileTime($objItem.lastlogon[0])
$result = $objItem.pwdlastset
$user_pwd_last_set = [datetime]::FromFileTime($result[0])
#calculate the difference in Day
$diff_date = [INT]([DateTime]::Now - $user_pwd_last_set).TotalDays;
if (($max_pwd_life - $diff_date) -le $max_alert) {
$selected_user = New-Object psobject
$selected_user | Add-Member NoteProperty -Name "Name" -Value $objItem.name[0]
$selected_user | Add-Member NoteProperty -Name "Email" -Value $objItem.mail[0]
$selected_user | Add-Member NoteProperty -Name "LastLogon" -Value $user_logon
$selected_user | Add-Member NoteProperty -Name "LastPwdSet" -Value $user_pwd_last_set
$selected_user | Add-Member NoteProperty -Name "EllapsedDay" -Value $diff_date
$selected_user | Add-Member NoteProperty -Name "RemainingDay" -Value ($max_pwd_life-$diff_date)
$userlist+=$selected_user
}
}
}
###############################################################################
Send email for each user
###############################################################################
foreach ($userItem in $userlist )
{
send_email_user $userItem.RemainingDay $userItem.Email $userItem.Name
}
###############################################################################
Sedn email for Admins in reporting format
###############################################################################
$bodyme = $userlist| Sort-Object “RemainingDay” | ConvertTo-Html -Title “AD password Status” -Body "<H2>Ad password expiration Status</H2> " -head “<style>td{font-size:smaller;padding:0 0 0 5px;border: 1px solid #003366;}table{border: 1px solid #003366;margin:0;padding:0}tr{margin:0;padding:0;}h2{color:red};th{font-size:smaller;text-align:left;border: 1px solid #003366;background-color:#aaa;}</style>” | foreach {$_ -replace “<table>”, “<table cellspacing=0>”}
sendmail $bodyme
###############################################################################
END
###############################################################################
However, I ran into a couple of small problems:
- Everyone in the Organization got an email rather than just a few people, who’s passwords will expire soon.
- Remaining Days for Password expiration is a negative number. ie: your password will expire in -200 days.
Your login password for account DOT@chch.org on use of the CH-CH computers, Wi-Fi and Email will be expire in -682 days on 01/31/2012 09:45:35 - Program listed an exception when it ran:
Cannot index into a null array.
At passwordexpiration.ps1:21 char:1
[int64]$mpa = ($dc.Properties[‘maxpwdage’][0]).ToString().Trim(“-”)
+ CategoryInfo : InvalidOperation: (:) [], RuntimeException
+ FullyQualifiedErrorId : NullArray
However, I am not sure how to fix this problem. I emailed Levente, but have not heard back. Any ideas?