I need to closely track dormant accounts—those that haven't logged on in a long time—and disable them. I've written a script to handle the dirty work. For each account, the script pulls the last-logon and last-logoff date and time properties from each domain controller (DC) in the domain and uses the latest value for both properties. The script queries all the DCs because DCs don't replicate last-logon and last-logoff properties to other DCs. Sometimes, the data my script retrieves makes no sense. For example, the script might find a last-logoff time but no last-logon time (or vice versa). As another example, the last logon might be December 2002, but the last logoff is March 2001. My script is supposed to disable accounts that are out of compliance with our policies and automatically delete accounts that are excessively out of compliance, but I want to know why I'm getting these weird numbers before I start shutting down accounts. Where does Windows get these figures, and how does it store them?
Windows 2000 and Windows NT reports of the last-logon and last-logoff fields have always been weird. Most of the time, the last-logon field is correct, but it can be inexplicably blank or report a last logon that's much older than the user's actual last logon. Microsoft has never provided a solid explanation for this problem (or a fix for it). However, all is not lost, as I explain in a moment.
But first, let's discuss the last-logoff field. Knowing how Windows logons work, I don't trust this field on DCs. When you arrive at your workstation in the morning and use your domain account to log on, you aren't logging on to the domain or the DC—you're logging on to your workstation. Of course, the workstation contacts the DC to authenticate you, and that authentication is the DC's opportunity to record your last logon time. However, the DC doesn't keep track of whether you remain logged on at your workstation, nor does it know when you log off. In other words, you don't really log on to and log off of DCs—you simply authenticate to them.
In at least one place, the Microsoft Platform SDK documentation (http://msdn.microsoft.com/library/default.asp?url=/library/en-us/netmgmt/netmgmt/user_info_11_str.asp) states that Windows doesn't even use the last-logoff field (i.e., usri11_last_logoff). Any such data that you manage to obtain from Windows probably relates to when an administrator or operator interactively logged on and off at the DC's console or to when the workstation queried the DC for Group Policy information after the user logged on. Even in the Security log, you'll sometimes see a logon event (event ID 528 or event ID 540) with no corresponding logoff event (event ID 538). Given these irregularities, I recommend that you don't use the last-logoff field.
Nevertheless, identifying dormant user accounts is important for securing a domain. Often, when employees or contractors are terminated or leave an organization, their accounts remain active, letting them or other unauthorized users access the network. However, disabling accounts that haven't logged on in a long time (e.g., 90 days) isn't the best way to handle this problem because this approach targets only the accounts of former users who haven't used their accounts since leaving the organization. Thus, dormant accounts represent only "honest" former employees and contractors and tell you nothing about former users who continue to access the network.
Best practice dictates that the human resources (HR) or payroll department should notify IT when an employee departs and that you follow a similar procedure for consultants and contractors. IT should then immediately disable the associated accounts or set an appropriate expiration date. If you don't catch these accounts until much later, you leave your network open to abuse. Today's climate of layoffs and disgruntled employees increases the risk of waiting even a day after termination to disable an account. Many companies immediately escort a terminated employee from the building and revoke the employee's physical access. Why would you do less with the employee's network access, which might include remote dial-up or VPN capability?
Thus, I strongly recommend that you use the last logon only to identify accounts that have slipped through the cracks and that you rely instead on a good notification procedure from HR. If communication between HR and IT isn't reliable, you might be able to configure your HR software to automatically send a report or email message to IT when an employee is terminated. Some of my clients have even written scripts that parse the report to find the employee ID and use it to disable the user account.
One way to get additional verification that a user account is truly dormant is to compare the account's last-logon time with the Security logs on your DCs. You could easily write a script that runs nightly and scans each DC Security log for all occurrences of event ID 672 and event ID 680. Together, these two events cover every successful user authentication to the DC. The script could maintain a database of usernames and the latest occurrence of either event for each username. The script you use to identify dormant users could then compare the account's last logon with the Security log report for added confirmation that an account is truly dormant.
Windows Server 2003 takes a step in the right direction but doesn't completely fix the problem with the last-logoff field. Windows 2003 includes a new user property, Last-Logon-Timestamp, which is replicated among DCs. However, to prevent huge increases in logon-associated replication traffic, this field is accurate only to within a week.