Taking a Bite Out of Password Expiry Helpdesk Calls
By call volume, the top problem that most Helpdesks face is expired or forgotten passwords. In this story we'll try to make a dent in the first one - expired passwords.
It's simply human nature to leave things to the last minute, especially if you don't get nagged (aka "reminded") about it. Active Directory passwords are especially bad for this, as they tend to just leap out at you with "your password is expired, it's time to change it NOW".
This leaves your people at a disadvantage. Not only can't they remember what the policy is or what we talked about during that part of their security awareness training, but they can't get to their notes because they CAN'T. LOG. ON.
This script tries to take care of this for you. it'll send them a daily reminder for the 7 days (or whatever you set) before their expiry date, with links to the policy and a reminder of what not to use in their password, and why.
OK, let's get to the code.
Before we start, we'll need today's date in a variable:
$now - get-date |
Next, collect all the user accounts in AD, note that neat "Expression" block where we compute the password expiry date for each
$b = Get-ADUser -filter {Enabled -eq $True -and PasswordNeverExpires -eq $False} –Properties SAMAccountName,"DisplayName", "msDS-UserPasswordExpiryTimeComputed","emailaddress",mobilephone, officephone, telephoneNumber | Select-Object -Property SamAccountName,"Displayname",@{Name="ExpiryDate";Expression={[datetime]::FromFileTime($_."msDS-UserPasswordExpiryTimeComputed")}},"emailaddress", mobilephone, officephone, telephoneNumber |
Note that "ExpiryDate" computed field.
So who will be expiring in the next 7 days?
$expirydays = 7 |
We collected the phone numbers because we're also interested in the helpdesk phone folks who have expired and maybe don't know it yet. So who has expired in the last 30 days?
$ExpiredPeople = $b | where-object {($_.expirydate -$now).days -lt 0} | where-object {($_.expirydate -$now).days -ge -30} | sort-object -property expirydate |
How do we let folks know that they're expiring soon? We'll use email, because that's what corporate runs on (and it's easier than slack or teams or whatever cool chat / collab thing you are using). We'll send using the send-mailmessage command. This covers everyone, if they leave things until they expire, you'll be able to tell them we TOLD YOU, 7 times (or however many days you choose), and you'll have the emails to back you up.
Note that the send-mailmessage command is SMTP only, so it's clear-text. You'll want to send this to an internal relay host that will in turn forward it to the affected folks in a more secure way.
Microsoft doesn't have a secure alternative to this in Powershell, but I'll cover off a few alternatives (one actually from Microsoft) in my next story.
Anyway, the command looks like this:
send-mailmessage -smtpserver $mailserver -subject $subj -from $from -to $p.emailaddress -Body $emailtext -BodyAsHtml |
The "$emailtext" variable has to be a string (a simple text file will not fly, that would be too easy), the -BodyasHtml parameter has that string being interpreted as HTML.
Putting it all together ..
$now = get-date # Collect all users with their respective password expiry dates # who has expired in the last 30 days? (note that $recent is negative) # who will be expiring within the next week? # Define mail parameters # send the note to each person in turn # send the two lists of people (expired and soon to expire) to the helpdesk
|
So, what does a typical email look like? The one that my skeleton creates looks like this:
What else can you use this for? Sending expiring passwords of service accounts to the helpdesk (or whoever owns those accounts) is another common thing I've seen.
If you find this code useful, you can find it on my github: https://github.com/robvandenbrink
If you see a better way to code any of this, or have another use for this bit of code, by all means let us know in the comment section!
===============
Rob VandenBrink
rob@coherentsecurity.com
Comments
Vincent T
Apr 20th 2023
1 year ago
But in AD we still see lots of things that don't play nicely with MFA - starting with every corporate app that uses LDAP for authentication, and hasn't even stepped up to LDAPS yet, let alone MFA. Service accounts too, no MFA in most automated processes.
Anything with that uses RADIUS with an AD back-end you can usually wrangle to use MFA somehow though.
You definitely can do Windows Hello for AD these days (also some other MFA solutions), but it's a new enough thing, and a large enough project that most orgs haven't gone there yet.
Which in the best case sadly still leaves us with AD passwords that need to be managed in most shops....
Rob VandenBrink
Apr 20th 2023
1 year ago
Vincent T
Apr 20th 2023
1 year ago