chessexpert said:
Yes, but that still does not explain why I have multiple DCs showing the
exact same date/time in the GUI for a specific user. Since this does not
get
replicated, how is it that so many (but not all) DCs have the exact Last
Logon date/time for a particular user (i.e. how can that user get
authenticated on many DCs at the same time?)Perhaps one DC was used as a
template during a restore or build process, and that captured the Last
Logon
info on all DCs that copied the AD database? And why is it that the GUI
does
not always match the AD query? It is as if the AD query is not going to
the
DC that I specify in the LDAP path, but perhaps rather whichever responds
first? Basically I need a way to determine tha actual last long date on
each
DC. But sometime the Gui matches the VBScript Get method, and other times
it
matches the GetEx method.
If you are retrieving the value of lastLogon for a user from several DC's,
you are right that they should not be the same (except for the value 0,
which means never). Values of lastLogonTimeStamp should be the same. If you
specify the DNS name of the DC in the binding string, only that DC should
respond. To specify a particular DC I use code similar to:
Set objUser = GetObject("LDAP://MyServer.MyDomain.com/cn=Jim
Smith,ou=West,dc=MyDomain,dc=com")
If the DC is not available an error should be raised. I've never heard of
using the GetEx method. I thought it was only for multi-valued attributes. I
use code simiilar to (using the IADsLargeInteger interface):
Set objDate = objUser.Get("lastLogon")
Wscript.Echo objDate.HighPart & ", " & objDate.LowPart
However I experimented with GetEx and found it retrieves lastLogon as a
Variant() array with one element, which is an object, although you cannot
use the Set keyword. I used this code:
objDate = objUser.GetEx("lastLogon")
Wscript.Echo objDate(0).HighPart & ", " & objDate(0).LowPart
This gave me the exact same result for both high and low 32-bit parts of the
64-bit value. Note that the standard formula for calculating the 64-bit
value (in VB and VBScript) using the IADsLargeInteger interface is:
=========
Set objDate = objUser.Get("lastLogon")
lngHigh = objDate.HighPart
lngLow = objDate.LowPart
lngDate = #1/1/1601# + (((lngHigh * (2 ^ 32)) _
+ lngLow) / 600000000 - lngAdjust) / 1440
dtmDate = CDate(lngDate)
=========
However there is a problem in the IADsLargeInteger interface, which only
reveals itself half the time and gives answers only off by 7 minutes 9.5
seconds. The fix is as follows:
=========
Set objDate = objUser.Get("lastLogon")
lngHigh = objDate.HighPart
lngLow = objDate.LowPart
' Account for error in IADsLargeInteger property methods.
If (lngLow < 0) Then
lngHigh = lngHigh + 1
End If
lngDate = #1/1/1601# + (((lngHigh * (2 ^ 32)) _
+ lngLow) / 600000000 - lngAdjust) / 1440
dtmDate = CDate(lngDate)
=======
Also, the resulting date is in UTC, so you must correct by the time zone
bias to convert to local time. I mention this in case this accounts for
differences between what you calculate in code and what you see in something
like ADSI Edit or the GUI. Since LowPart runs from -2^31 to 2^31-1, the
correction is needed half the time. Incrementing the HighPart by 1 is
equivalent to 7 minutes 9.5 seconds. I'm assuming the same correction must
be made if you use the GetEx method, but I would have to experiment more.