<# Script Name: Find_Old_Timers.ps1 Version: 1.0 Author: Dean Bunn Last Edited: 03/08/2013 Description: Finds Old AD Accounts (in specific OUs) Older than Four Years Old with Passwords that have Never been Changed or are Older than Four Years Old #> #Create DateTime Object for Four Years Ago $dt4YrsAgo = (Get-Date).AddYears(-4); #Var for Converted File Time Used for Password Last Set Filter $ftPLS = $dt4YrsAgo.ToFileTime().ToString(); #Constructing When Created Filter(Should Look Like 20130302000000.0Z) $wcYear = $dt4YrsAgo.Year.ToString(); $wcMonth = "{0:D2}" -f $dt4YrsAgo.Month; $wcDay = "{0:D2}" -f $dt4YrsAgo.Day; $sWC = $wcYear + $wcMonth + $wcDay + "000000.0Z"; #Reporting Array $report = @(); #Var for Showing Progress $x = 0; #Array of OUs to Check Against $arrOUs = @("LDAP://OU=External,DC=MyCollege,DC=edu", "LDAP://OU=Students,DC=MyCollege,DC=edu", "LDAP://OU=Staff,DC=MyCollege,DC=edu"); foreach($ouADsPath in $arrOUs) { #Directory Entry for OU to Search $deOU = [adsi]$ouADsPath; #Search OU for All User Accounts Meeting the Search Criteria $dsSearch = New-Object DirectoryServices.DirectorySearcher($deOU); $dsSearch.filter = "(&(objectClass=user)(sAMAccountName=*)(whenCreated<=$sWC)(|(pwdlastset<=$ftPLS)(pwdlastset=0)(pwdlastset=9223372036854775807)))"; $dsSearch.PageSize = 900; $dsSearch.SearchScope = "SubTree"; $srResults = $dsSearch.Findall(); #Loop Through All Search Results foreach($srResult in $srResults) { $x++; Write-Output $x.ToString(); #Retrieve DirectoryEntry for the User Account $deADUser = $srResult.GetDirectoryEntry(); #Null Check on the DirectoryEntry Object if($deADUser) { #Create Custom Object for Reporting $cstPCUser = New-Object PSObject; $cstPCUser | Add-Member -MemberType NoteProperty -Name "UserID" -Value ""; $cstPCUser | Add-Member -MemberType NoteProperty -Name "UPN" -Value ""; $cstPCUser | Add-Member -MemberType NoteProperty -Name "CN" -Value ""; $cstPCUser | Add-Member -MemberType NoteProperty -Name "UAC" -Value "" $cstPCUser | Add-Member -MemberType NoteProperty -Name "PasswordChanged" -Value ""; $cstPCUser | Add-Member -MemberType NoteProperty -Name "LastLoginTimeStamp" -Value ""; #Pull Basic Account Information $cstPCUser.UserID = $deADUser.sAMAccountName.ToString().ToLower(); $cstPCUser.UPN = $deADUser.userPrincipalName.ToString().ToLower(); $cstPCUser.CN = $deADUser.cn.ToString(); #Check Last Password Change if($srResult.Properties["pwdlastset"][0].ToString() -ne "9223372036854775807" -and $srResult.Properties["pwdlastset"][0].ToString() -ne "0") { $cstPCUser.PasswordChanged = ([System.DateTime]::FromFileTime($srResult.properties["pwdlastset"][0])).ToString(); } else { $cstPCUser.PasswordChanged = "Not Set"; } #Account Status Check if($deADUser.userAccountControl) { switch([int]($deADUser.userAccountControl.ToString())) { 512 {$cstPCUser.UAC = "Enabled"} 514 {$cstPCUser.UAC = "Disabled"} 520 {$cstPCUser.UAC = "Enabled"} 522 {$cstPCUser.UAC = "Disabled"} 544 {$cstPCUser.UAC = "Enabled"} 546 {$cstPCUser.UAC = "Disabled"} 66048 {$cstPCUser.UAC = "Enabled"} 66050 {$cstPCUser.UAC = "Disabled"} 66080 {$cstPCUser.UAC = "Enabled"} 66082 {$cstPCUser.UAC = "Disabled"} 8388608 {$cstPCUser.UAC = "Password Expired"} default {$cstPCUser.UAC = "unknown"} } } #Convert Last Logon Timestamp (If Exists) if($srResult.Properties["lastlogontimestamp"]) { $cstPCUser.LastLoginTimeStamp = ([System.DateTime]::FromFileTime($srResult.Properties["lastlogontimestamp"][0])).ToShortDateString(); } #Add Custom Object to Report Collection $report += $cstPCUser; }#End of $deADUser Null Check }#End of $srResults Foreach }#End of $arrOUs Foreach #Get Current Short Date $rptFileDate = Get-Date -Format d; #Var for CSV File Name $fileName = "Old_Timers_Password_Change_Report_" + $rptFileDate.ToString().Replace("/","-") + ".csv"; #Export CSV Report $report | Sort-Object UserID | Export-CSV $fileName -NoTypeInformation ; ###### End of Script ###################
Friday, March 8, 2013
PowerShell: Find Old Accounts and Passwords
Yesterday, I got tasked with helping find all users accounts in an Active Directory domain that are older than four years and haven't changed their password or have passwords older than four years. The domain in question had only starting using password complexity four years ago and wanted an audit of which accounts might be non-compliant. I spent some time figuring out the proper syntax to the search filter but at least I know it now. Below is the script. Enjoy.
Subscribe to:
Post Comments (Atom)
No comments:
Post a Comment