Showing posts with label Active Directory. Show all posts
Showing posts with label Active Directory. Show all posts

Thursday, April 2, 2015

PowerShell: Password Alert & Report

This is first of three posts in regards to how admin team at current employer manage expiring password alerting and reporting.  We use 3 versions of PowerShell scripts:


  • Password Alert
  • Password Expiration based on OU Report
  • Report mailer to execute each OU Report and mail all out to admin team
This post will focus on the password alert script.

The script is composed of x number of segments.

  • Capturing max Password age from AD
  • Create function to send email users
  • Gather users not disabled with expiring passwords
  • Send email alert
First part of the script captures max password age from AD.  This is accomplished by maxpwdage from domain controller(s) then dividing it by nano seconds in a day (8.64e13 or 864000000000)

###################################
# Get the max Password age from AD 
# This Section pulls domains maximum password age from your domain controller(s)
###################################
function Get-maxPwdAge{
$root = [ADSI]"LDAP://DOMAIN.COM"
#Change DOMAIN.COM to target your domain
$filter = "(&(objectcategory=domainDNS)(distinguishedName=DC=DOMAIN,DC=COM))"
#Change Distinguished name to target your domain
$ds = New-Object system.DirectoryServices.DirectorySearcher($root,$filter)
$dc = $ds.findone()
[int64]$maxpwdage = [System.Math]::Abs( $dc.properties.item("maxPwdAge")[0])
$maxpwdage/864000000000
#Pulls maxPwdAge from domain for comparison later
}

Next part is to assemble function to email users

Key points to remember here are to update the following variables:

  • $SmtpClient.Host
    • Should be your mail server
  • $mailmessage.from
    • From email address you want messages to appear as
  • $mailmessage.Subject
    • Tweak the subject line of your message as desired
In addition you will want to update the body of the message to instruct your users on ways to reset their passwords.

###################################
# Function to send HTML email to each user
###################################

function send_email ($days_remaining, $email, $name ) 
{
 $today = Get-Date
 $today = $today.ToString("dddd (yyy-MMMM-dd)")
 $date_expire = [DateTime]::Now.AddDays($days_remaining);
 $date_expire = $date_expire.ToString("dddd (yyy-MMMM-dd)")
 $SmtpClient = new-object system.net.mail.smtpClient 
 $mailmessage = New-Object system.net.mail.mailmessage 
 $SmtpClient.Host = "ENTER YOUR MAIL SERVER HERE" 
 $mailmessage.from = "Technology <expiringpassword@donotreply.com>" 
 $mailmessage.To.add($email)
 $mailmessage.Subject = "$name, Your DOMAIN Password will expire soon."
 $mailmessage.IsBodyHtml = $true

 $mailmessage.Body = @"
<font face=Calibri (Body)>Dear $name, </font><br /><br />
<font face=Calibri (Body)>Your password will expire in <font color=red><strong>$days_remaining</strong></font> days on <strong>$date_expire</strong>.<br />
To prevent access issues ensure you change your password prior to $date_expire.<br /><br />

Your domain password is required for Computer Login, Infinite Campus, Email Access, Google Services (Drive, gMail), etc.<br /><br /><br />

You will receive this message until password is changed.<br /><br />


To change your password follow below processes:<br /><br />

<ul>
    <li type=square>Remote User
        <ul>
            <li>Must come onsite to change when connected to District network (Desktop or SaberSecure[WiFi])
        </ul>    
</ul>
<ul>
    <li type=square>PC/Windows User
        <ul>
            <li>Logon to system and press CTRL-ALT-DEL and choose Change Password.
        </ul>    
</ul>
<ul>
    <li type=square>PASSWORD REQUIREMENTS<br /><br />
        <ul>
            <li>must be 8 or more characters long and<br />
            <li>cannot be one of last 7 password used<br />
            <li>contain a mix of THREE of the following FOUR properties:<br />
                <ul>
                    <li type=disc>uppercase letters (A-Z)<br />
                    <li type=disc>lowercase letters (a-z)<br />
                    <li type=disc>numbers (0-9)<br />
                    <li type=disc>symbols (!"£$%^&*)
                </ul>
        </ul>
</ul>    
<br /><br />
Once your password has been changed you will need to update on all mobile devices (ex: cellphone / iPad / etc).  Failure to update could result in your account becoming locked repeatedly due to failed account access.
<br /><br /><br />

If you have any questions, please contact the IT Helpdesk on 
<br /><br />
 Generated on : $today

</font>
"@

 $smtpclient.Send($mailmessage) 
}


Next step is to query your domain for Non-Disabled and expiring users
###################################
# Search for Non-disabled AD users that have a Password Expiry.
###################################

$strFilter = "(&(objectCategory=User)(logonCount>=0)(!(userAccountControl:1.2.840.113556.1.4.803:=2))(!(userAccountControl:1.2.840.113556.1.4.803:=65536)))"

$objDomain = New-Object System.DirectoryServices.DirectoryEntry
$objSearcher = New-Object System.DirectoryServices.DirectorySearcher
$objSearcher.SearchRoot = $objDomain
$objSearcher.PageSize = 1000
$objSearcher.Filter = $strFilter
$colResults = $objSearcher.FindAll();

# how many days before PW expiry do we start sending reminder emails?
$max_alert = 14


# Get the maximum password lifetime
$max_pwd_life=Get-maxPwdAge

$userlist = @()
foreach ($objResult in $colResults)
   {$objItem = $objResult.Properties; 
   if ( $objItem.mail.gettype.IsInstance -eq $True) 
      {      
         $user_name = $objItem.name
         $user_email = $objItem.email
         #Transform the DateTime readable format
         $user_logon = [datetime]::FromFileTime($objItem.lastlogon[0])
         $result = $objItem.pwdlastset 
         $user_pwd_last_set = [datetime]::FromFileTime($result[0])

         #calculate the difference in Day from last time a password was set
         $diff_date = [INT]([DateTime]::Now - $user_pwd_last_set).TotalDays;

   $Subtracted = $max_pwd_life - $diff_date
         if (($Subtracted) -le $max_alert) {
            $selected_user = New-Object psobject
           # $selected_user | Add-Member NoteProperty -Name "Name" -Value $objItem.name[0]
            $selected_user | Add-Member NoteProperty -Name "Name" -Value $objItem.Item("displayname")
            $selected_user | Add-Member NoteProperty -Name "Email" -Value $objItem.mail[0]
            $selected_user | Add-Member NoteProperty -Name "LastLogon" -Value $user_logon
            $selected_user | Add-Member NoteProperty -Name "LastPwdSet" -Value $user_pwd_last_set
            $selected_user | Add-Member NoteProperty -Name "RemainingDays" -Value ($Subtracted)
            $userlist+=$selected_user
         }
      }
   }


Lastly we send the email alert to the user

We are almost ready to send out our alerts now.  In this last bit of code we pull together the email message and list of expiring users.  We then send a message to each one.  Now for testing update ENTER_ADMIN_EMAIL_HERE to direct all messages to a single account.  This allows for review and tweaking of alert message.

###################################
# Send email to each user
###################################
   foreach ($userItem in $userlist )
   {
    if ($userItem.RemainingDays -ge 0) 
       {
     #Remove Comment (#) below to perform normal process / email user
     #send_email $userItem.RemainingDays $userItem.Email $userItem.Name
     #Update and remove comment below for testing / troubleshooting.  Allows for mailing a single user all expiring user alerts
     # send_email $userItem.RemainingDays ENTER_ADMIN_EMAIL_HERE $userItem.Name
       }
   }

# END

Download the PowerShell file here:
https://drive.google.com/open?id=0B1fwreWrAZioZW5fYlRxb3BCQms&authuser=0

Wednesday, March 18, 2015

Folder Permission Nightmare (CJWDEV's NTFS Permissions Reporter)

This post focuses around a nightmare of a week I had with Technology team and file servers.

The day was Tuesday March 3rd, 2015, the day was seeming to start of slow as we were wrapping up some issues with our aging Exchange server (2007 on 2k8 platform).  We began to get calls that staff could no longer access the StaffShare folders and files.  As we began to receive the calls and research we soon discovered for whatever reason (have not had time to research more) our file server had dropped all but local admin on the staffshare.  

Some background our staffshare consists of 800 GB some 58,000 folders to be shared across 12 buildings with over 1000 users.  You would think something like this would be documented but I soon found out it was not.  For the past week we have been slowly restoring access as users request and are vetted.  We are trying to hold meetings with departments to become proactive and create groups before someone reports the issue but that process is slow.

Out of all this we have learned that NTFS permissions must be documented and audited now and then, we believe a student / teacher may have some how changed the permissions.  To complete this task we thought about using just your standard spreadsheet but realized quickly the hours to complete would a) far out way the benefit b) never be available to complete.  It was only when one of the admins asked me if only there was a software to do this for us do my somewhat mushy brain recall such a program.  This is when we rushed out and purchased CJWDEV's NTFS Permissions Reporter.
CJWDEV's NTFS Permissions Reporter - Full Version
http://cjwdev.com/Software/NtfsReports/Info.html

Installation was quick and easy.  Setting up to scan and report on a drive or even specific folder is simple.  But the greatest power lies in the export ability the reports into multiple formats.  We choose to use the NTPR format native to the program.  This allows for you to compare between either recent scan or other saved reports.  Our plan is to create baselines and audit changes quarterly via comparison.

Going forward in my career I will always purchase a copy of CJWDEV's NTFS Permissions Reporter - Full Version.  It will be the best $150-$600 dollar system software investment.

Monday, March 9, 2015

Dual Platform Woes - Password Alerts

As my current employer moves to a dual platform of Windows and Mac systems we have ran in to issues with users not being aware of password expiration.  As such the Technology team has had to look for ways to ensure both Windows and Mac users are aware of upcoming password expiration.

To accomplish this we have deployed the following:


  1. PowerShell Script
    • Password Alert
      • Runs daily at 7AM
      • Starts 14 days from expiration and continues until password reset
      • Provides links and directions on how to reset password
    • Password Expiration Report
      • Sends single email with OU Expiration reports attached
    • Use Windows Task Scheduler to execute scripts daily
    • Run on DC

  2. ADPassMon
We have just implemented both of these into our environment.  Will include complete write ups on setup of each option in the near future.



Monday, June 16, 2014

Coming back soon...

Hello everyone.

I must apologize for my failure in keeping up with my blog.  There have been several personal issues that have eaten up my time.

I have lost of content stored up and just need to make my way through it and get it posted.

Some changes I plan to add are:

  • Monthly product reviews.  I have several free apps and other software that I want to share and will get my opinions out there.
  • PowerShell scripting
  • Active Directory
  • VMware - I have finally got my server and thus my practice lab setup.
Drop me a line if you have a product you would like me to check out or any other areas you would like to hear about.