Password Expiry Email Notification

This script will email a user in the event that their password is due to expire in X number of days. I have now moved it to GitHub -

4.6 Star
90,113 times
Add to favorites
Active Directory
E-mail Twitter Digg Facebook
  • Results in Body no Attachment
    2 Posts | Last post May 10, 2019
    • Hey Robert,
      Thanks for this helpful script. Is there a way to place the results into the body of the email that gets sent to IT, rather than an attachment. It would be easier to view on mobile devices if the results were just in the body.
      Thanks again,
    • Yes you could do something like...
              $reportSubject = "Password Expiry Report"
              $reportBody = "<html>
              foreach ($obj in $notifiedUsers)
                  $rmessage = $obj.UserMessage
                  $ruserName = $obj.UserName
                  $rname = $obj.Name
                  $rEmail = $obj.Email
                  $rPasswordSet = $obj.PasswordSet
                  $rDaysToExpire = $obj.DaystoExpire
                  $rSendMail = $obj.SendMail
                  $reportBody = $reportBody + "<tr><td>$rUsername</td><td>$rName</td><td>$rEmail</td><td>$rPasswordSet</td><td>$rDaysToExpire</td><td>$rSendMail</td><td>$rUserMessage</td></tr>"
              $reportBody = $reportBody + "</table></html>"
                  Send-Mailmessage -smtpServer $smtpServer -from $from -to $reportTo -subject $reportSubject -body $reportbody -bodyasHTML -priority High -Encoding $textEncoding -Attachments $logFile -ErrorAction Stop 
                  $errorMessage = $_.Exception.Message
                  Write-Output $errorMessage
  • Negative Values
    2 Posts | Last post May 10, 2019
    • Any way to set this up to ignore users with a negative DaysToExpire value?  It sends emails to those users with a message that just says "Your Password Will Expire" without a date or time frame.
    • Negative values have always been a pain, and im not sure i really fully understand how they come about.
      What i think they mean is that a password was set on never expire, and then a password policy was applied and never expire was removed. Which would mean, password last set + max age, is a date in the past. In theory that user should not be able to login because their password has expired.
      Or, it means we are not correctly excluding people who do have password never expire set.
      So, do you have anyone who has PasswordNeverExpires set as 'True' when you run this command, get-aduser -filter {(Enabled -eq $true) -and (PasswordNeverExpires -eq $false)}
      Alternatively to just work around the issue, you could do something like this..
      $notifyUsers = $colUsers | where { ($_.DaysToExpire -ge 0 ) -and ($_.DaysToExpire -le $expireInDays)}
  • for already expired account or 0 day
    3 Posts | Last post May 09, 2019
    • Thanks Mr. your script is really great and easy to use.
      I have question, how to add into this script for user which already has password expired or 0 day expiry?
      Would appreciate your help so much!
    • Well, in theorey they wouldn't get the notification as they wouldnt be able to log in.
    • Thank for replying sir.
      Actually I am deploying this to AD on-premise with synchronization to Office 365 account.
      User not actually login using this AD account, so we need a notification system to notice them their password is already expired.
      The expired password will not affect Office 365.
      Big help if you can advice me how to get expired password as well.
      Like adding interval 0?
  • Regarding schedulling...
    2 Posts | Last post May 06, 2019
    • First, great script, works like a charm!
      I have question about scheduling...
      Let's say I schedule it to run daily, with parameter -expireInDays 21 set, but I also add -interval 3,7,14
      If script "catches" user with expiry in 21 days, on some day and if -interval is set, will user be notified only on interval days, or will he also get an email again on the next day, when script runs in its scheduled time again?
    • Lets say on day 1 a user has 21 days left.
      You run the script daily with the settings you specify.
      Day 1, notified.
      Day 2, not notified.
      Day 3 - 7, not notified.
      Day 8, Notified - 14 days remaining.
      Day 9 - 14, not notified.
      Day 15, notified 7 days remaining.
      Day 16, 17, 18 not notified.
      Day 19, notified 3 days remaining.
      Day 19 would be the last notification.
      So i would always include 0,1 in the interval.
  • -reportto is not working
    2 Posts | Last post April 24, 2019
    • this is my script:
      c:\scripts\PasswordChangeNotification.ps1 -smtpServer -expireInDays 10 -from "IT Support <>" -reportTo -interval 1,2,3,4,5,6,8,10 -Logging -LogPath "C:\Scripts\passwordexpirelog" 
      everything is working great except for the -reportTo im not getting emails.
      i want to receive emails as CC when a user get notifications...
    • So you dont get the reports and you also want a CC to the password reminders?
      Are the reports going to junk or not received at all? is this a custom domain on gmail?
  • Scheduled Task Interval Failure
    2 Posts | Last post April 18, 2019
    • Robert,
      This is working fantastically from powershell ISE but from a scheduled task the interval parameter is failing.  Writing to the logfile, each line finishes with ,"Skipped - Interval".
      I'm running powershell.exe with the following argument:
      -file c:\scripts\scheduled\AD-User-Password-Expire-Notification\PasswordChangeNotification.ps1 -smtpServer -expireInDays 14 -from "Service Desk <>" -Logging -LogPath "c:\scripts\logfiles\Password-reset-reminder" -testing -testRecipient -interval 1,3,5,7,14
      Followed advice of an earlier poster I tried wrapping the command with "" and parameters wrapped with ''.  This actually failed to run.
      Any ideas what I maybe doing wrong?
    • lol.  silly error.  changed -file for -command.  all good.  
  • Cannot validate argument on parameter 'To'.
    6 Posts | Last post April 13, 2019
    • Hey Robert,  I have configured and tested w/o issue.  I receive my test notifications and all looks great.  When I go to run this live, I am receiving the following error when attempting to send to a user:
      Cannot validate argument on parameter 'To'. The argument is null or empty. Provide an argument that is not null or empty, and then try the command again.
      No email goes out.  I do not see a To parameter anywhere in the script however.  
      Where do I need to look?  or update?
    • -to is a parameter in Send-MailMessage, it is set to use $emailAddress.
      So, i would guess that one or more of your users does not have an emailaddress stored in Active Directory.
    • I am assuming you are referring to the 'mail' attribute in AD correct?  I show in the report that there are email addresses populated.  Here is one example:
      in 5 days.	zografoss	Sheila Zografos	9/10/2018 7:06	5	3/9/2019 7:06	Cannot validate argument on parameter 'To'. The argument is null or empty. Provide an argument that is not null or empty, and then try the command again.
      The EmailAddress column is showing the correct address for the user. 
    • Are you able to use Send-MailMessage on it's own to that recipient?
    • Yes I am able to send test messages using Send-MailMessage through the relay.
    • Hey Robert.  So I went back and sent a test email from the script w/o any modifications and was able to successfully send.  
      So started reviewing each modification from the originally edited script, and line 54 - the $testing string, I had = "Disabled".  I removed the = "Disabled" from this line and retested and was successful in sending the emails!  
      Not sure why this line would have an affect but it is working now.  Thanks for your time on this!
  • if no expiring password is found no log is written
    1 Posts | Last post April 11, 2019
    • if no user are found the script thrown this error:
      You cannot call a method on a null-valued expression.
      At c:\scripts\PasswordChangeNotification.ps1:228 char:41
      +     $samLabel = $samAccountName.PadRight <<<< ($padVal," ")
          + CategoryInfo          : InvalidOperation: (PadRight:String) [], RuntimeException
          + FullyQualifiedErrorId : InvokeMethodOnNull
      Add-Member : Cannot bind argument to parameter 'InputObject' because it is null.
      At c:\scripts\PasswordChangeNotification.ps1:266 char:31
      +             $user | Add-Member <<<<  -MemberType NoteProperty -Name SendMail -Value "OK"
          + CategoryInfo          : InvalidData: (:) [Add-Member], ParameterBindingValidationException
          + FullyQualifiedErrorId : ParameterArgumentValidationErrorNullNotAllowed,Microsoft.PowerShell.Commands.AddMemberCommand
      Creating Log File
      Log Output: .\11-4-2019-PasswordLog.csv
      Export-Csv : Cannot bind argument to parameter 'InputObject' because it is null.
      At c:\scripts\PasswordChangeNotification.ps1:296 char:32
      +     $notifiedUsers | Export-CSV <<<<  $logFile
          + CategoryInfo          : InvalidData: (:) [Export-Csv], ParameterBindingValidationException
          + FullyQualifiedErrorId : ParameterArgumentValidationErrorNullNotAllowed,Microsoft.PowerShell.Commands.ExportCsvCommand
  • Method invocation failed because [System.Int32] does not contain a method named 'split'.
    5 Posts | Last post April 11, 2019
    • Hi there,
      I have implemented this script on several servers. On 1 server I see this error in the logfile and the e-mail is not being send.
      What is missing or wrong overhere?
    • Any more info? Line number of the error, full error text? OS of the server?
    • I found the reason. The split is this line:
         if(($interval.split(",")) -Contains($daysToExpire.toString()))
      That isn't part of the script but on some servers the orginal line:
         if(($interval) -Contains($daysToExpire))
      Won't work because when using more days in the interval parameter you need the spplit. I thing its different per OS.
      That solution was posted earlier.
    • And when not using the split, it will not e-mail. It will keep saying in the log in the collum SendMail just an OK, nothing more. And the interval has got 5.
    • I think that depends how you pass the interval array into the script.
      What is the full command you use to run the script?
  • SMTP Issue while Testing
    4 Posts | Last post April 09, 2019
    • Hi there,
      Having issues getting the e-mail portion to work with g-mail. We will most likely use Office 365 smtp servers but I just wanted to get this working before I show it to my team.
      SMTP Server          :
      Expire in Days       : 21
      From                 :
      Logging              : True
      Log Path             : c:\logFiles
      Testing              : True
      Test Recipient       :
      Report Recipient     : 
      Intervals            : 
      Getting this error:
      The SMTP server requires a secure connection or the client was not authenticated. The server response was: 5.7.0 Must issue a STARTTLS command first. g1sm7204905ywf.0 - gsmtp
      I know my credentials are right, and I've followed your YT tutorial on creating the smtp.txt file as well as making it a securestring.
      Any thoughts?
      I've also added the PORT and USESSL portions to test and I'm not getting in my e-mail. Even without the port type, the error above is asking for some STARTTLS command.
      Send-Mailmessage -smtpServer $smtpServer -from $from -to $reportTo -subject $reportSubject -body $reportbody -bodyasHTML -priority High -Encoding $textEncoding -Attachments $logFile -Credential $credential Port 587 -UseSsl -ErrorAction Stop 
    • Have a look at the question on December 2nd 2018, that has the solution you need.
    • I only see questions from Dec 11 then it jumps to Nov 29. I'm missing something here. Please help.
    • Sorry don't know what happened, it was December 18th.
       [System.Net.ServicePointManager]::SecurityProtocol = 'TLS12' 
      You need to set the above prior to the sending the message, so i have added it to 'system settings'..
      # System Settings
      $textEncoding = [System.Text.Encoding]::UTF8
      $today = $start
      # Set TLS Version, used with SMTP Authentication
      [System.Net.ServicePointManager]::SecurityProtocol = [System.Net.SecurityProtocolType]::Tls12
      # End System Settings
41 - 50 of 542 Items