Skip to content

Instantly share code, notes, and snippets.

@mattmcnabb
Created October 28, 2016 01:00
Show Gist options
  • Save mattmcnabb/200cd8caf040d9492e71420f3d84dd6f to your computer and use it in GitHub Desktop.
Save mattmcnabb/200cd8caf040d9492e71420f3d84dd6f to your computer and use it in GitHub Desktop.
Password Expiration Notice and Report
<#
.DESCRIPTION
Finds all users in Active Directory with passwords close to expiring
and notifies them via email. Also creates and sends a report that includes all
expired and expiring passwords.
#>
#Requires -Version 3.0
#Requires -Module ActiveDirectory
param
(
$From,
# Address of admin who will receive the report. for multiple recipients
# use a comma to separate.
$ReportTo,
# Subject of message sent to admin
$ReportSubject = 'Daily Password Expiration Report',
# Subject of message sent to users
$NotifySubject = 'Password Expiration Notice',
# Message priority for user notification - values are:
# 'Low','Medium', and 'High'
$NotifyPriority = 'High',
# Interval in days to begin user notification
$NotifyInterval = 14,
# URL of password self-service webpage
$PWResetURL,
# URL of company logo to include in user notification
$LogoURL,
# Address of server to send notifications and reports to
$SMTPServer,
# OU to use as a search base for users. Recursive
[string[]]$OUsToSearch,
$Department,
$Phone
)
# Properties of message to be sent to users with expiring passwords
$NotifyMessage = @{
SMTPServer = $SMTPServer
From = $From
Subject = $NotifySubject
BodyAsHTML = $true
Priority = $NotifyPriority
}
# Properties of message sent to admin specified by $ReportTo
$ReportMessage = @{
SMTPServer = $SMTPServer
To = $ReportTo
From = $From
Subject = $ReportSubject
BodyAsHTML = $true
}
# Common variables
$ExpiringUsers = @()
$ExpiredUsers = @()
$ExpireInHours = ((Get-ADDefaultDomainPasswordPolicy).MaxPasswordAge).totalhours
$UserParams = @{
filter = {(Passwordneverexpires -eq $false) -and (enabled -eq $true)}
Properties = 'mail','passwordlastset','passwordexpired','company','title'
}
$Now = Get-Date
# Loop through users and return any with passwords expiring or expired
$Users = foreach ($OU in $OUsToSearch)
{
$UserParams['SearchBase'] = $OU
Get-Aduser @UserParams
}
ForEach ($User in $Users)
{
If($User.passwordlastset -ne $null)
{
$PassLastSet = $User.PasswordLastSet
$PassExpirationDate = $PassLastSet.AddHours($ExpireInHours)
$HoursTilExpire = ($passexpirationdate - $now)
$DaysTilExpire = [system.math]::Floor($HoursTilExpire.totalhours / 24)
If($User.passwordexpired)
{
$DaysExpired = ($Now - $PassExpirationDate).Days
$ExpiredUsers += $User |
Select-Object Name,Mail,Title,
@{l='User Name'; e={$_.SamAccountName.tolower()}},
@{l='Days Expired'; e={$DaysExpired}},
@{l='Buildings'; e={$_.Company}}
}
Elseif($HoursTilExpire -gt "0")
{
if($DaysTilExpire -le $NotifyInterval)
{
$ExpiringUsers += $User |
Select-Object Name,Mail,Title,
@{l='User Name'; e={$_.SamAccountName.tolower()}},
@{l='Days Left Until Expiration'; e={$DaysTilExpire}},
@{l='Buildings'; e={$_.Company}}
}
}
}
}
$TableExpiring = $ExpiringUsers | Sort-Object -Property 'Days Left Until Expiration',Title | ConvertTo-Html -Fragment
$TableExpired = $ExpiredUsers | Sort-Object -property 'Days Expired',Title | ConvertTo-Html -Fragment
#region Report
# Send report of expiring and expired users to admin(s)
$ReportMessage.Body =
@"
<!DOCTYPE HTML>
<html>
<Head>
<style>
body {}
table, th, td {
font-family: calibri,arial,verdana;
border: 2px solid white;
border-collapse: collapse;
background-color: #edeedc;
}
</style>
</head>
<body>
$(if ($ExpiringUsers.count -gt 0)
{
"<b>$($ExpiringUsers.Count)</b> users have passwords expiring within $NotifyInterval days:<br><br>$TableExpiring<br><br>"
})
$(if ($ExpiredUsers.count -gt 0)
{
"<b>$($ExpiredUsers.count)</b> users' passwords have already expired:<br><br>$TableExpired<br><br>"
})
$(if (($ExpiringUsers.count -eq 0) -and ($ExpiredUsers.count -eq 0)){'No password expirations to report - It must be summer!'})
</body>
</html>
"@
Send-MailMessage @ReportMessage
#endregion Report
#region Notify
# Notify expiring users
foreach ($ExpiringUser in $ExpiringUsers)
{
$NotifyMessage.To = $ExpiringUser.Mail
$NotifyMessage.Body =
@"
<!DOCTYPE HTML>
<html>
<Head>
<style>
span.red {color:red;}
body {font:face:calibri,arial,verdana;}
</style>
</head>
<body>
<p>$($ExpiringUser.Name),
<br><br>
This is an auto-generated email to remind you that the password for the Active Directory
account <b><span class=`"red`">$(($ExpiringUser.'User Name').toUpper())</span></b> will expire in
<b> $($ExpiringUser.'Days Left Until Expiration') day(s)</b>.
<br><br>
If this password expires you will not be able to log on to company computers or
access your email.
<br><br>
You can go to the password reset website <a href="$PWResetURL">here</a> and change the password yourself,
otherwise you are welcome to contact the $Department for assistance.
<br><br>
Please do not reply to this message. This mailbox is not monitored.
<br><br>
Sincerely,<br>$Department<br>$Phone
<br><br>
<img src=`"$LogoURL`" width=`"200`" ><br>
</p>
</body>
</html>
"@
Send-MailMessage @Notifymessage
}
#endregion Notify
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment