Another script that I wanted to share with the rest of the world. Please be aware that there is a bug that is preventing the replacing of dates with 1/1/1601 to Null (i.e. empty) when it creates the CSV file. If you can let me know how to fix this, then please feel free to tell me or share it in the comments section below.
'########### ORIGINAL SOURCE ########################################### ' PwdLastChanged.vbs ' ---------------------------------------------------------------------- ' Copyright (c) 2003-2010 Richard L. Mueller ' Hilltop Lab web site - http://www.rlmueller.net '########### ORIGINAL SOURCE ########################################### '########### Non-Expiring Password Audit ################################ ' This script checks for user accounts that are in active directory, ' whose accounts are disabled. It will display their name, username, ' and the date of their last logon in a CSV file. ' ' History: ' Disabled_Users.vbs v1.0 - 11/15/2012 ' '####################################################################### Option Explicit Dim strFilePath, objFSO, objFile, adoConnection, adoCommand Dim objRootDSE, strDNSDomain, strFilter, strQuery, adoRecordset Dim strDN, objShell, lngBiasKey, lngBias, strPrncName, strLstLgDt Dim objDate, k, curDate, curMonth, curDay Dim strFldr, strFile, strFldrPath 'Set up date variables curDate = Date() 'strLstMnth = DateAdd("m",-1,curDate) 'strFldr = curDate '& Right(String(2, "0") & Month(strLstMnth),2) strFldr = Year(curDate) & Right(String(2, "0") & Month(curDate),2) 'Check and see if a folder exists in the X:\mydrive\Disabled_Users\ directory 'using the YYYYMM format using the prior month's two digit number; if not, then create it, else create the 'CSV file using the current date in the European date format YYYYMMDD. Dim fileSys, crtFldr 'Change the path between the quotes if needed strFldrPath = "X:\mydrive\Disabled_Users\" & strFldr & "\" Set fileSys = CreateObject("Scripting.FileSystemObject") If Not fileSys.FolderExists(strFldrPath) Then Set crtFldr = fileSys.CreateFolder(strFldrPath) End If strFile = Year(curDate) & Right(String(2, "0") & Month(curDate),2) & Right(String(2, "0") & Day(curDate),2) strFilePath = strFldrPath & strFile & ".csv" Set objFSO = CreateObject("Scripting.FileSystemObject") ' Open the file for write access. On Error Resume Next Set objFile = objFSO.OpenTextFile(strFilePath, 2, True, 0) If (Err.Number <> 0) Then On Error GoTo 0 Wscript.Echo "File " & strFilePath & " cannot be opened" Wscript.Quit(1) End If On Error GoTo 0 ' Obtain local time zone bias from machine registry. ' This bias changes with Daylight Savings Time. Set objShell = CreateObject("Wscript.Shell") lngBiasKey = objShell.RegRead("HKLM\System\CurrentControlSet\Control\" _ & "TimeZoneInformation\ActiveTimeBias") If (UCase(TypeName(lngBiasKey)) = "LONG") Then lngBias = lngBiasKey ElseIf (UCase(TypeName(lngBiasKey)) = "VARIANT()") Then lngBias = 0 For k = 0 To UBound(lngBiasKey) lngBias = lngBias + (lngBiasKey(k) * 256^k) Next End If ' Filter to retrieve all user objects. ' NOTE: The line(s) containing (!sAMAccountName=) is used for filtering out user accounts with ' a specific set of characters, those without the * (asterisk) filters out a specific account. strFilter = "(&(objectCategory=person)(objectClass=user)(userAccountControl:1.2.840.113556.1.4.803:=2))" ' Filter to retrieve all computer objects. ' strFilter = "(objectCategory=computer)" '#################### Setup AD Connection & Create CSV File ############################################# '# The code below creatres the active directory connection and then uses the filter generated earlier. # '# From there it creates an LDAP query string and performs the actual enumeration of accounts whose # '# passwords never expire, along with their last password change date, username, etc. Once completed it # '# will write each account into a comma delimited spreadsheet (CSV) file. # '######################################################################################################## ' Use ADO to search the domain for all users. Set adoConnection = CreateObject("ADODB.Connection") Set adoCommand = CreateObject("ADODB.Command") adoConnection.Provider = "ADsDSOOBject" adoConnection.Open "Active Directory Provider" Set adoCommand.ActiveConnection = adoConnection ' Determine the DNS domain from the RootDSE object. Set objRootDSE = GetObject("LDAP://RootDSE") strDNSDomain = objRootDSE.Get("DefaultNamingContext") strQuery = "<LDAP://" & strDNSDomain & ">;" & strFilter _ & ";Name,userPrincipalName,lastLogon;subtree" adoCommand.CommandText = strQuery adoCommand.Properties("Page Size") = 100 adoCommand.Properties("Timeout") = 30 adoCommand.Properties("Cache Results") = False ' Enumerate all users. Write each user's Distinguished Name, ' when they last logon. objFile.WriteLine "Name,Username,Last Logon Date" Set adoRecordset = adoCommand.Execute Do Until adoRecordset.EOF strDN = adoRecordset.Fields("Name").Value If (TypeName(adoRecordset.Fields("lastLogon").Value) = "Object") Then Set objDate = adoRecordset.Fields("lastLogon").Value strLstLgDt = Integer8Date(objDate, lngBias) Else strLstLgDt = NULL '#1/1/1601# 'Creates Null entries for dates with 1/1/1601 End If strPrncName = adoRecordset.Fields("userPrincipalName").Value objFile.WriteLine strDN & "," & strPrncName & "," & strLstLgDt adoRecordset.MoveNext Loop adoRecordset.Close ' Clean up. objFile.Close adoConnection.Close 'Open CSV file automatically after writing to it is completed dim csvOpen set csvOpen = CreateObject("WScript.Shell") 'csvOpen.Exec(strFilePath) csvOpen.Run Chr(34) & strFilePath & Chr(34), 1, false 'Wscript.Echo "Done" Function Integer8Date(ByVal objDate, ByVal lngBias) ' Function to convert Integer8 (64-bit) value to a date, adjusted for ' local time zone bias. Dim lngAdjust, lngDate, lngHigh, lngLow lngAdjust = lngBias lngHigh = objDate.HighPart lngLow = objdate.LowPart ' Account for error in IADsLargeInteger property methods. If (lngLow < 0) Then lngHigh = lngHigh + 1 End If If (lngHigh = 0) And (lngLow = 0) Then lngAdjust = 0 End If lngDate = #1/1/1601# + (((lngHigh * (2 ^ 32)) _ + lngLow) / 600000000 - lngAdjust) / 1440 ' Trap error if lngDate is ridiculously huge. On Error Resume Next Integer8Date = CDate(lngDate) If (Err.Number <> 0) Then On Error GoTo 0 Integer8Date = #1/1/1601# End If On Error GoTo 0 End Function
No comments:
Post a Comment