VBScript program to output all users in the domain with the date and time each last logged onto the domain. This program can be useful to identify old unused accounts that can be disabled and eventually deleted.

Because the lastLogon attribute is not replicated in Active Directory, a different value can be stored in the copy of Active Directory on each Domain Controller. The program first uses ADO to search Active Directory for all Domain Controllers. The AdsPath of each is saved in an array. Next, ADO is used to search the copy of Active Directory on each Domain Controller for all users and retrieve the lastLogon attribute. The latest date found for each user is saved in a dictionary object. Once all Domain Controllers have been queried, the program outputs each User's Distinguished Name and the latest lastLogon date. The Distinguished Name and lastLogon date for each user is output on a separate line delimited by a semicolon. If the output is redirected to a text file, it can be easily read by a spreadsheet program like Microsoft Excel.

The lastLogon attribute is stored in Active Directory as Integer8 (8 bytes). This means it is a 64-bit number, which cannot be handled directly by VBScript. Instead, the LDAP IADsLargeInteger interface provides HighPart and LowPart methods that break the number into two 32-bit components. The resulting value represents the number of 100 nanosecond intervals since 12:00 AM January 1, 1601. The date represented by this number is in Coordinated Universal Time (UTC). It must be adjusted by the time zone bias in the local machine registry to convert to local time.

The techniques in this program can be used to handle any attribute that is not replicated. Also, the conversion formulas used apply to all Integer8 attributes that represent dates, such as "pwdLastSet", "accountExpires", "badPasswordTime", and "lockoutTime".

The program should be run at a command prompt with the cscript host. The output can be redirected to a text file. For example, you can run the program with the following command:

cscript //nologo LastLogon.vbs > output.txt

LastLogon.txt <<-- Click here to view or download the program

If your domain is at Windows Server 2003 functional level, there is a new attribute called lastLogonTimeStamp you can use. Like lastLogon, this attribute is Integer8 and represents the time when the user last logged onto the domain. Unlike lastLogon, this new attribute is replicated. However, it is only updated when the user logs on if the old value is more than 14 days in the past. That means the value can only be trusted if it is more than 14 days in the past, which is fine for finding old unused accounts. This behavior reduces the synchronization load while still giving administrators the information they need.

Actually, the 14 day value can be modified by assigning a new value to the new msDS-LogonTimeSyncInterval attribute (in days). When a user logs on, if the current value of lastLogonTimeStamp is older than the current time less msDS-LogonTimeSyncInterval, then the value of lastLogonTimeStamp is updated (and this updated value replicates).

When the domain is first raised to Windows Server 2003 functional level, the value of lastLogonTimeStamp is initially updated after 14 days minus a random percentage of 5 days. This spreads out the initial replication of lastLogonTimeStamp for all users over a 5 day period.

A VBScript program to retrieve the value of lastLogonTimeStamp for all users only needs to query one Domain Controller. An example program is linked below:

LastLogonTimeStamp.txt <<-- Click here to view or download the program