Search This Blog

Wednesday, July 05, 2006

lastLogonTimestamp

So yet another question about how to find out the last logon time for users.... Ok, here is how it works in Windows 2003.

One of the new attributes in Windows 2003 is lastLogonTimestamp which can be used to retrieve the last logon time for users, good so we have a new attribute to use! Sounds easy, right?

But this is not as trivial as you might think! The lastLogonTimestamp is not always showing the truth since it is only replicated every 14 days... Then take into account that when you read the value for the attribute it is stored as a 64-bit integer calculated from 1601 January 1st in 100-nano secs interval. (No, it was not MS fault. It was the darn Cobol programmers!!)

And another funny thing is that VBScript can't handle 64-bit integers!!!!! So you need to break it down into two 32-bit integers with IADsLargeInteger, which has two properties:

highpart = store the high 32-bits
lowpart = store the low 32-bits

…then you add them to get a single value.

So how would a script that does this look like you might wonder.

I will not just put the code here but rather I will walk you through how to “think” to solve it. (If you really need the code and don’t know how to write it, send me an e-mail).

  1. Use “Get” to retrieve the attribute (lastLogonTimestamp)

  2. Store the value in an IADsLargeInteger object

  3. Combine the highpart and lowpart values into one value by taking the highpart * (2^32) and add the lowpart.

Ok, step 3 which is one line of code will give us the last logon for a user. But it will give us the time in a format of how many 100-nano secs intervals occurred since  Jan 1, 1601 and the user’s last logon.

The value might look like this: 2.5643571264596E+16

This, at least to me, looks kind of hard to read. And I bet the one asked for the report will not be happy if you give him/her this….. So now we need to do something about it, but first a little bit on nanosecs:

1 second = 1,000,000,000 nanosecs = 10,000,000 nanosec intervals per second (10,000,000 * 100 = 1,000,000,000). This means that there are 600,000,000 100-nano secs intervals per minute.

  1. To find out how many minutes elapsed since Jan 1, 1601 and last logon we can take the last logon time and divide it by (60*10000000).

  2. If we want to find out the number of days that have elapsed we dived the last logon time with 1440 (which is the number of minutes per 24 hrs).

The above steps (5 and 6) can be done in one step if you want…..

  1. Now we know how many days elapsed since Jan 1, 1601 so we take that and add it to Jan 1, 1601 (“last logon time” + #1/1/1601#) and we get the result in an easy to read format!


But I assume it is W2K3 otherwise you need to use the lastLogon which is not replicated at all, which means you have to retrieve it from all DCs and then compare the values, sounds boring but can be solved with some code...