{"id":409,"date":"2015-05-13T07:00:43","date_gmt":"2015-05-13T05:00:43","guid":{"rendered":"http:\/\/eugene.dullaard.nl\/?p=409"},"modified":"2015-06-18T08:50:55","modified_gmt":"2015-06-18T06:50:55","slug":"password-expiration-notification","status":"publish","type":"post","link":"https:\/\/eugene.dullaard.nl\/?p=409","title":{"rendered":"Password expiration notification 1.2"},"content":{"rendered":"<p>I was talking to a friend of mine also working in IT and somewhere during the conversation the topic of Windows 7 and balloon popups appeared. As those popups tend to get missed in a lot of cases and depending on how the network is secured this means in case of password expirations the user is locked out of the network. To counter the balloon popup issue we run a script on a daily basis\u00a0that mails users that their password is about to expire. Took some time to rewrite the script we run so it is more flexible in such you can determine which OUs will be scanned and on what days before expiration a notification is being send. Enjoy.<\/p>\n<p>Version 1.1 Update:<br \/>\nTwo things are fixed which came to my attention. The first is if you only had a single OU to be scanned the script wouldn&#8217;t work. For those that know powershell it was easy to fix. Now there is a check to see if there is only a single OU entry and the script will behave correctly if there is. The second fix is to check if an account has an e-mail address attached to it, otherwise no mail can be send out. If logging is enabled an additional line will be added to the log file in case no e-mail address was found.<\/p>\n<p>Version 1.2 Update:<br \/>\nCode requires version 3 of Powershell, on version 2 .count does not work.<\/p>\n<pre class=\"brush: cpp; collapse: false; title: ; notranslate\" title=\"\">\r\n#requires -version 3\r\n\r\n&lt;#\r\nProgram  : PWExpNoticeMailer.ps1 - Password Expiration Notice Mailer\r\nAuthor   : Eugene Dullaard (https:\/\/eugene.dullaard.nl\/?p=409)\r\nDate     : 27-Aug-2013 - version 1.0\r\n           - Initial Script\r\nUpdate   : 22-Dec-2014 - version 1.1\r\n           - Check for existence of emailaddress and add none-existence to logfile if enabled\r\n           - Check for Array in case of a single line entry, script didn't work for single OU\r\nUpdate   : 13-May-2015 - version 1.2\r\n           - Changed the required version of powershell to 3.0 due to use of .count\r\n\r\nTo Do's before running this script in your environment:\r\n- This script should be scheduled on a daily basis in order to run the check once a day.\r\n- You should modify the values of $LogFile,$DaysAdvWarn,$MailServer,$MailSender to what\r\n  is required in your environment\r\n- Change and\/or add Organizational Units to be searched\r\n- Change and\/or add the above OUs into $ArrOU\r\n- Change the $Subject and $Message so they contain what you require\r\n- For testing purposes, change $_.EmailAddress to your own so you see the results\r\n#&gt;\r\n\r\nImport-Module ActiveDirectory\r\n\r\n$LogFile = &quot;.\\PWExpNoticeMailer.log&quot;       # Logfile location, use &quot;&quot; to disable logging\r\n$DaysAdvWarn = 21,14,7,4,2,1               # Days before expiration to send warning\r\n$MailServer = &quot;mailserver.domain.tld&quot;      # FQDN or IP of mailserver to be used\r\n$MailSender = &quot;itnotification@domain.tld&quot;  # Mail address of sender\r\n\r\n# Enter Organizational Units to search for user accounts in LDAP notation\r\n# Name them as you wish and use these names in ArrOU variable as per example\r\n$ou0 = &quot;OU=Abusers,OU=Beavis Corp,DC=domain,DC=tld&quot;\r\n$ou1 = &quot;OU=Loosers,OU=Butthead Inc,DC=domain,DC=tld&quot;\r\n\r\n# Build the array of Organizational Units stated above, keep them in sync if you want to use them all\r\n$ArrOU = $ou0,$ou1\r\n\r\n# Get the maximum password age and exit if not set\r\n$MaxPWAge = ((Get-ADDefaultDomainPasswordPolicy).MaxPasswordAge).Days\r\nif ($MaxPWAge -eq 0) {Throw &quot;No Domain Password Policy Present&quot;}\r\n\r\n# Loop to run through all the Organizational Units to search\r\nfor ($a=0;$a -lt ($ArrOU).count;$a++) {\r\n\r\n  #Check if Array exists and change searchbase properly in case of a single OU entry\r\n  if ($ArrOU.count -eq 1) {$SearchBase = $ArrOU} else {$SearchBase = $ArrOU&#x5B;$a]}\r\n\r\n  #Get All Users within one of the Organizational Units\r\n  #Not taking people that have disabled or non-expiring accounts\r\n  Get-ADUser -Filter {(Enabled -eq $true) -and (PasswordNeverExpires -eq $false)} -SearchBase $SearchBase `\r\n  -Properties PasswordLastSet,EmailAddress | ForEach-Object {\r\n\r\n    # Set variables\r\n    $GivenName = $_.GivenName\r\n    $Name = $_.Name\r\n\r\n    # Calculate days left before password change is required\r\n    $PWTimeLeft = (($_.PasswordLastSet - (Get-Date)).Days)+$MaxPWAge\r\n\r\n    #Check if Password Time Left equals Advance Warning Days\r\n    if ($DaysAdvWarn -contains $PWTimeLeft) {\r\n\r\n      # Add entry in logfile if enabled\r\n      if ($LogFile -ne &quot;&quot;) {Add-Content $LogFile &quot;$Name,$PWTimeLeft&quot;}\r\n\r\n      # Build up message if mailaddress is present\r\n      # You can add instructions or change the content as you see fit\r\n      if ($_.EmailAddress -ne $null) {\r\n        $Subject = &quot;IT Notification: Your password expires in $PWTimeLeft days&quot;\r\n        $Message = &quot;Dear $GivenName,\r\n\r\nYour password is about to expire in $PWTimeLeft days.\r\nPlease take the appropiate action bofore your password expires.\r\n\r\nKind Regards,\r\n\r\nYour IT Department\r\n\r\n(This message is automatically generated, please contact your support desk if you have any questions.)\r\n&quot;\r\n\r\n        # Sending Message (Hint: Change $_.EmailAddress to your own for testing purposes)\r\n        Send-MailMessage -to $_.EmailAddress -from $MailSender -Subject $Subject -body $Message `\r\n        -SmtpServer $MailServer\r\n      }\r\n      else {\r\n        if ($LogFile -ne &quot;&quot;) {Add-Content $LogFile &quot;$Name,Failure : No Mail Address&quot;}\r\n      }\r\n    }\r\n  }\r\n}\r\n<\/pre>\n<p>Q &#038; A<\/p>\n<p>Location of log-file?<\/p>\n<p>In the example above the location is set to .\\<foldername>, which means current folder. If you are running this as a scheduled task without a folder set this usually ends up in the System32 folder.<\/foldername><\/p>\n","protected":false},"excerpt":{"rendered":"<p>I was talking to a friend of mine also working in IT and somewhere during the conversation the topic of Windows 7 and balloon popups appeared. As those popups tend to get missed in a lot of cases and depending on how the network is secured this means in case of password expirations the user &hellip; <a href=\"https:\/\/eugene.dullaard.nl\/?p=409\" class=\"more-link\">Continue reading <span class=\"screen-reader-text\">Password expiration notification 1.2<\/span> <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[20],"tags":[28,27],"class_list":["post-409","post","type-post","status-publish","format-standard","hentry","category-powershell","tag-password-management","tag-powershell"],"_links":{"self":[{"href":"https:\/\/eugene.dullaard.nl\/index.php?rest_route=\/wp\/v2\/posts\/409","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/eugene.dullaard.nl\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/eugene.dullaard.nl\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/eugene.dullaard.nl\/index.php?rest_route=\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/eugene.dullaard.nl\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=409"}],"version-history":[{"count":16,"href":"https:\/\/eugene.dullaard.nl\/index.php?rest_route=\/wp\/v2\/posts\/409\/revisions"}],"predecessor-version":[{"id":715,"href":"https:\/\/eugene.dullaard.nl\/index.php?rest_route=\/wp\/v2\/posts\/409\/revisions\/715"}],"wp:attachment":[{"href":"https:\/\/eugene.dullaard.nl\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=409"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/eugene.dullaard.nl\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=409"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/eugene.dullaard.nl\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=409"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}