A Guide to Active Directory User Logon Metadata

A Guide to Active Directory User Logon Metadata

This blog post is the first in a series about Active Directory attributes with values or behaviors that can be easily and inadvertently misinterpreted and misused. This series will provide information about these attributes, including both their limitations and their valid usages with respect to the administration of Active Directory.

Active Directory user objects possess a number of logon metadata attributes that are often leveraged in Active Directory audit reporting and administration. One of their most common uses is to identify user accounts that have been inactive for a significant period, generally referred to as “stale” user accounts.

However, each of these logo metadata attributes have some unique behaviors that need to be understood. Failing that, the use of these attributes can result in reporting that is confusing at best and inaccurate or otherwise misleading at worst.

This blog post explains the behaviors of each of the Active Directory user object logon metadata attributes and points out the potential uses and misuses of each.

Last-Logon Attribute

The Last-Logon attribute contains a Windows FileTime representation of the last time a domain controller successfully authenticated the user. It is the granddaddy of user logon metadata, and has been around since the first version Active Directory.

The Last-Logon attribute is updated every time a domain controller successfully processes a logon request. While this makes Last-Logon appear to be the perfect way to accurately identify stale user accounts, there’s a big caveat that needs to be taken into account.

Last-Logon is not a replicated attribute; every domain controller maintains its own version of the attribute for any specific user. This behavior is both intentional – the increase in replication traffic necessary to keep this attribute in sync across a network’s domain controllers would have been overwhelming; especially at its time of introduction twenty years ago – and the reason that it is necessary to be careful when using this attribute to report on stale user accounts.

Because the Last-Logon attribute is not replicated, its value can only be interpreted in the context of the domain controller that is being queried. The attribute’s value is not necessarily the last time the user logged in, but rather the last time the user logged in through a specific domain controller. Similarly, the attribute having a value is zero does not necessarily mean that the user has never logged in; it may mean that the domain controller that returned the value has never processed a login request from that user (though you’d have to check the rest of the domain’s domain controllers to be sure).

While the Last-Logon attribute can be used for login-related auditing, accurate reporting will require querying every domain controller capable of processing login requests to identify its most recently-updated value for any specific user account. That is to say, we should probably keep looking for a better option.

Last-Logon-Timestamp Attribute

The Last-Logon-Timestamp contains a Windows FileTime representation of a recent time the user logged on to a domain. The attribute was introduced with Windows Server 2003. Unlike the Last-Logon attribute, the Last-Logon-Timestamp attribute is a replicated attribute; its value for any specific user is synced to every domain controller. This is a big improvement over the Last-Logon attribute, which means that the best way to identify stale user accounts is to use the Last-Logon-Timestamp, right? Well, using this attribute comes with its own warning.

The “gotcha” with the Last-Logon-Timestamp attribute is that it is not always updated when a domain controller successfully processes a logon request. Instead, the attribute has a dynamic update frequency that is limited by the value of the ms-DS-Logon-Time-Sync-Interval attribute, which defaults to NOT SET and is treated as 14 days. It’s not common for this attribute to have been changed, but if you’re curious you can easily identify its actual value using PowerShell:

$lastLogonReplicationInterval = (Get-ADDomain).LastLogonReplicationInterval

if( $lastLogonReplicationInterval ) 
{
    Write-Host "ms-DS-Logon-Time-Sync-Interval is set to $($lastLogonReplicationInterval) days"
}
else {
    Write-Host "ms-DS-Logon-Time-Sync-Interval is not set and will be treated as 14 days"
}

In a domain with a default 14-day maximum update boundary, the Last-Logon-Timestamp is only updated when a domain controller successfully processes a logon request and the period since the attribute’s last update is greater than somewhere between 9 and 14 days. The variation in that period is the result of a random percentage that is included in the logic that controls the update frequency. This behavior reflects a compromise made to limit the replication traffic necessary to keep this attribute in sync across a network’s domain controllers, with the inherent randomization serving to further limit the likelihood of having to replicate a significant number of users who had their Last-Logon-Timestamp updated at around the same time.

Here’s a simplified example of the logic that controls the update frequency of the Last-Logon-Timestamp attribute:

(Current Datetime – Last-Logon-Timestamp) ≥ (ms-DS-Logon-Time-Sync-Interval – (Random % * 5 days))

In practice, the Last-Logon-Timestamp attribute will simplify login-related auditing and reporting. The only significant potential issue involves inactive user reporting. When used to identify inactive users, the threshold for “staleness” needs to exceed the domain’s ms-DS-Logon-Time-Sync-Interval value by enough time to ensure that replication has been able to propagate any meaningful updates.

LastLogonDate (PowerShell)

Those familiar with PowerShell may recognize LastLogonDate, but you won’t be able to find it anywhere in the Active Directory schema. This is because LastLogonDate is actually a locally-calculated value that will display the replicated value of the Last-Logon-Timestamp attribute in a “friendly” format. Unsurprisingly, LastLogonDate has all of the benefits and all but one of the drawbacks (requiring conversion from Windows DateTime) of the Last-Logon-Timestamp attribute, making this the best option for most user login-related audit reporting.

ms-DS-Last-Successful-Interactive-Logon-Time

The ms-DS-Last-Successful-Interactive-Logon-Time attribute was introduced in Windows Server 2008, but many people are unfamiliar with it because it’s disabled by default. The ms-DS-Last-Successful-Interactive-Logon-Time attribute (when enabled) contains the date and time of a user’s last successful interactive logon. While this seems like an incredibly useful thing to enable, you’re probably going to have trouble finding a domain that has done so.

There are some compelling reasons that tend to result in its remaining disabled, which I’ll get to in a moment. If you have a lab environment and want to play around with the ms-DS-Last-Successful-Interactive-Logon-Time attribute, just enable the Computer Configuration → Policies → Administrative Templates → Windows Components → Windows Logon Options → Display information about previous logons during user logon GPO setting and force some Group Policy updates. Do not enable this setting in a production domain for fun. You’ll have a bad time.

The first issue with the ms-DS-Last-Successful-Interactive-Logon-Time attribute is that its value is only updated when an interactive logon is authenticated (think “Ctrl-Alt-Del” logons). This means important authentication activities like Network Share logins and LDAP authentications will not trigger an update. If you attempt to use the ms-DS-Last-Successful-Interactive-Logon-Time attribute to generate logon-related audit reports, you’re likely to get some potentially unpleasant results. For example, reports identifying inactive user accounts are likely to inaccurately include domain service accounts, which are generally very active in non-interactive ways.

The second issue with the ms-DS-Last-Successful-Interactive-Logon-Time attribute is alluded to in the name of the GPO setting that enables the behavior: “Display information about previous logons during user logon”. When this setting is enabled, whenever a user logs on in an interactive session (i.e., every time they log on to a domain-joined computer) they will be presented with a message that contains the date and time of their last successful logon, the date and time of their last unsuccessful logon, and the number of unsuccessful logons that have occurred since their last successful logon. This message cannot be suppressed and must be acknowledged before the user’s desktop will appear. I can’t imagine that causing any issues beyond the possibility of hordes of end-users endlessly complaining about this being a most egregious inconvenience which has significantly and negatively impacted their overall productivity and is probably also the reason they can’t print to the shared printer on the second floor near Karen’s desk anymore.

Enabling this setting makes stale user reporting really simple and reliable, but only for user accounts that are used for interactive sessions. Additionally, the costs associated with this login-auditing “easy button” are significant increases in both Active Directory replication traffic and, more importantly, complaints from end-users who are annoyed by the new click-through that’s been added to their login process. What I’m saying is, if this setting is not currently enabled in your domain, don’t enable it.

Summary

If you need to generate Active Directory login audit reports, the best approach is probably to aggregate your domain controller event logs and process them. While event logs are incredibly noisy, they’re also incredibly reliable and provide historical information that Active Directory cannot.

If that’s not feasible, use LastLogonDate. Or, even better, use the Search-ADAccount cmdlet baked into the ActiveDirectory PowerShell module:

Search-ADAccount -AccountInactive -DateTime ((Get-Date).AddDays(-30)) -UsersOnly 

The Search-ADAccount cmdlet actually leverages LastLogonDate behind the scenes. Its inactivity period defaults to 15 days, which should be fine in most environments. The example above includes the syntax necessary to override the inactivity period with a value of 30 days.

Leave a Reply

Your email address will not be published. Required fields are marked *

*

This site uses Akismet to reduce spam. Learn how your comment data is processed.

Start a Free StealthAUDIT® Trial!

No risk. No obligation.

Privacy Preference Center

      Necessary

      Advertising

      Analytics

      Other