Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save meoso/de56bdc68eced50a65d38e99e306ee42 to your computer and use it in GitHub Desktop.
Save meoso/de56bdc68eced50a65d38e99e306ee42 to your computer and use it in GitHub Desktop.
#################################################################################################################
#
# Version 1.4 February 2016
# Robert Pearman (WSSMB MVP)
# TitleRequired.com
# Script to Automated Email Reminders when Users Passwords due to Expire.
#
# Requires: Windows PowerShell Module for Active Directory
#
# For assistance and ideas, visit the TechNet Gallery Q&A Page. http://gallery.technet.microsoft.com/Password-Expiry-Email-177c3e27/view/Discussions#content
# Or Checkout my Youtube Channel - https://www.youtube.com/user/robtitlerequired
#
##################################################################################################################
# Please Configure the following variables....
$smtpServer="mail.server.com"
$expireindays = 21
$from = "Company Administrator <support@mycompany.com>"
$logging = "Enabled" # Set to Disabled to Disable Logging
$logFile = "<log file path>" # ie. c:\mylog.csv
$testing = "Enabled" # Set to Disabled to Email Users
$testRecipient = "testuser@company.com"
#
###################################################################################################################
# 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,Notified"
}
} # End Logging Check
# System Settings
$textEncoding = [System.Text.Encoding]::UTF8
$date = Get-Date -format ddMMyyyy
# End System Settings
# 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)
$sent = "" # Reset Sent Flag
# 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) -gt "1")
{
$messageDays = "in " + "$daystoexpire" + " days."
}
else
{
$messageDays = "today."
}
# Email Subject Set Here
$subject="Your 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 on a PC press CTRL ALT Delete and choose Change Password <br>
<p>Thanks, <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))
{
$sent = "Yes"
# If Logging is Enabled Log Details
if (($logging) -eq "Enabled")
{
Add-Content $logfile "$date,$Name,$emailaddress,$daystoExpire,$expireson,$sent"
}
# Send Email Message
Send-Mailmessage -smtpServer $smtpServer -from $from -to $emailaddress -subject $subject -body $body -bodyasHTML -priority High -Encoding $textEncoding
} # End Send Message
else # Log Non Expiring Password
{
$sent = "No"
# If Logging is Enabled Log Details
if (($logging) -eq "Enabled")
{
Add-Content $logfile "$date,$Name,$emailaddress,$daystoExpire,$expireson,$sent"
}
}
} # End User Processing
# End
@meoso
Copy link
Author

meoso commented Feb 28, 2023

Hi, How can I modify this code to send out notification to a security group?

maybe useful: https://activedirectoryfaq.com/2021/02/sending-e-mail-to-members-of-an-ad-group/

@Odakolo
Copy link

Odakolo commented Feb 28, 2023

Hi, How can I modify this code to send out notification to a security group?

maybe useful: https://activedirectoryfaq.com/2021/02/sending-e-mail-to-members-of-an-ad-group/

Thanks meoso, I know I have to edit this part of the code
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 }

But I am not sure of how to.
I have tried other things like "Get-ADGroupMember".
I want the new code to look in a particular security group and email the users in that security at the times I want them to be notified.

@meoso
Copy link
Author

meoso commented Feb 28, 2023

Hi, How can I modify this code to send out notification to a security group?

maybe useful: activedirectoryfaq.com/2021/02/sending-e-mail-to-members-of-an-ad-group

Thanks meoso, I know I have to edit this part of the code 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 }

But I am not sure of how to. I have tried other things like "Get-ADGroupMember". I want the new code to look in a particular security group and email the users in that security at the times I want them to be notified.

Try some variation of (Get-ADGroup -Identity $GroupName -properties members).Members | Get-ADUser,
where this format of (Get-ADGroup -Identity $GroupName -properties members).Members is a workaround for a 5000 user-count limitation existing in Get-ADGroupMember -Identity $GroupName

@Odakolo
Copy link

Odakolo commented Feb 28, 2023

**Try some variation of [...]

I tried it but it didnt work.

@meoso
Copy link
Author

meoso commented Feb 28, 2023

I tried it but it didnt work.

so

$users = (Get-ADGroup -Identity $GroupName -properties members).Members | get-aduser -filter * -properties Name, PasswordNeverExpires, PasswordExpired, PasswordLastSet, EmailAddress |where {$_.Enabled -eq "True"} | where { $_.PasswordNeverExpires -eq $false } | where { $_.passwordexpired -eq $false }

where $GroupName is set for your group, still fails?

EDIT: do not use -filter *

@Odakolo
Copy link

Odakolo commented Feb 28, 2023

$users = (Get-ADGroup -Identity $GroupName -properties members).Members | get-aduser -filter * -properties Name, PasswordNeverExpires, PasswordExpired, PasswordLastSet, EmailAddress |where {$_.Enabled -eq "True"} | where { $_.PasswordNeverExpires -eq $false } | where { $_.passwordexpired -eq $false }

Thanks, my bad. I missed something. After fixing it, it runs but it gets notification for everyone not the people in the specific security group I specified.

@meoso
Copy link
Author

meoso commented Mar 1, 2023

[...]] it runs but it gets notification for everyone not the people in the specific security group I specified.

try without the -filter *. This is an interesting use-case. maybe i should do some coding/testing myself.

@Odakolo
Copy link

Odakolo commented Mar 1, 2023

try without the -filter *. This is an interesting use-case. maybe i should do some coding/testing myself.

Thanks! I will try that and let you know.

@meoso
Copy link
Author

meoso commented Mar 1, 2023

@Odakolo , i just tested without -filter *; It works.

$users = (Get-ADGroup -Identity $GroupName -properties members).Members | get-aduser -properties Name, PasswordNeverExpires, PasswordExpired, PasswordLastSet, EmailAddress |where {$_.Enabled -eq "True"} | where { $_.PasswordNeverExpires -eq $false } | where { $_.passwordexpired -eq $false }

image

where my group had 4 users. 1 of which with a soon to expire password.

seems like there would be a way to simplify this as well, rather than piping, but i'm happy enough with that line.

@Odakolo
Copy link

Odakolo commented Mar 2, 2023

@Odakolo , i just tested without -filter *; It works.

THANKS! it works!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment