List Active Directory Users and Last Password Change Date
Goal: Query Active Directory for users' password last changed, password never expires, and other information
Prerequisites: Windows XP or higher
So you just enforced a password expiration policy. An excellent step in securing your network. But now you want to audit who has changed their password and who just isn't using their account anymore. After all, odds are if it's been a couple weeks and their password is expired and they haven't changed it, they most likely aren't using their account. That is where this relatively simple script comes into play. Visual Basic can be a powerful tool for accessing windows API's one of which lets us query Active Directory via an ADODB connection. Below I'll show you how to leverage this ability to pull back active directory information such as their Account Name, Full Name, Account Creation Date, Last Login Date (note that if you have multiple domain controllers this is the last login date they logged in using the queried domain controller only), Password last Change date, and whether or not their account password is set to expire. Below we'll output this information into a CSV file so that we can easily view it using excel or favorite spreadsheet manipulator.
-
The first step of this process is to create the VBScript which pulls back this data. Here is a sample code which i'll save as activeDirectoryInfo.vbs. Edit as you see fit and be sure to change the domain query.
On Error Resume Next const ADS_UF_DONT_EXPIRE_PASSWD = &H10000 Const ADS_SCOPE_SUBTREE = 2 Set objConnection = CreateObject("ADODB.Connection") Set objCommand = CreateObject("ADODB.Command") objConnection.Provider = "ADsDSOObject" objConnection.Open "Active Directory Provider" Set objCommand.ActiveConnection = objConnection objCommand.Properties("Page Size") = 1500 objCommand.Properties("Searchscope") = ADS_SCOPE_SUBTREE objCommand.CommandText = _ "SELECT * FROM 'LDAP://dc=domain,dc=com' WHERE objectCategory='user'" Set objRecordSet = objCommand.Execute objRecordSet.MoveFirst Wscript.StdOut.Write """SamAccountName"",""Full Name"",""Created"",""Last Login"",""PasswordChanged"",""Password Never Expires""" & vbCrlf Do Until objRecordSet.EOF strPath = objRecordSet.Fields("ADsPath").Value Set objUser = GetObject(strPath) IF IsEmpty(objUser.samAccountName) THEN 'Do Nothing ELSE Wscript.StdOut.Write """" & objUser.samAccountName & """," IF IsEmpty(objUser.FullName) THEN Wscript.StdOut.Write """NONE""," ELSE Wscript.StdOut.Write """" & objUser.FullName & """," END IF IF IsEmpty(objUser.whenCreated) THEN Wscript.StdOut.Write """NONE""," ELSE Wscript.StdOut.Write """" & objUser.whenCreated & """," END IF IF IsEmpty(objUser.GET("lastLogon")) THEN Wscript.StdOut.Write """1/1/1601""," Else dim intLogonTime Set objLogon = objUser.Get("lastLogon") intLogonTime = objLogon.HighPart * (2^32) + objLogon.LowPart intLogonTime = intLogonTime / (60 * 10000000) intLogonTime = intLogonTime / 1440 intLogonTime = intLogonTime + #1/1/1601# inactiveDays = intLogonTime Wscript.StdOut.Write """" & inactiveDays & """," END IF IF IsEmpty(objUser.passwordLastChanged) THEN Wscript.StdOut.Write """1/1/1900 12:00:00 AM""," Else Wscript.StdOut.Write """" & objUser.passwordLastChanged & """," END IF IF objUser.GET("userAccountControl") AND ADS_UF_DONT_EXPIRE_PASSWD THEN Wscript.StdOut.Write """" & "TRUE" & """" ELSE Wscript.StdOut.Write """" & "FALSE" & """" END IF Wscript.StdOut.WriteLine End If objRecordSet.MoveNext Loop
- Next we actually need to run this script file. In windows this can be done by opening the command prompt and using the cscript command. This in combination with sending the script output to a file will generate our csv file for us. Note: You will be querying Active Directory using the account you run the command as so make sure you are running with elevated permissions if they are required.
cscript activeDirectoryInfo.vbs > activeDirectoryInfo.csv
- Finally, open up excel an load up your csv file. Voila! A great auditing tool for those who are requiring frequent password changes.