WinBatch Tech Support Home

Database Search

If you can't find the information using the categories below, post a question over in our WinBatch Tech Support Forum.

TechHome

ADSI
plus

Can't find the information you are looking for here? Then leave a message over on our WinBatch Tech Support Forum.

Getting LastLoginTimestamp Value in ADSI


Question:

I am running a query against AD for the "lastloginTimestamp". The return I get is a Windows generated string (64-bit integer). W32TM.exe can convert to a date/time stamp that is readable, but I am trying to do all within the Winbatch code. Any help is appreciated.

Answer:

The ADSI extender currently does not properly convert this property to YMDHMS time format. It is an oversight that will be corrected.

There are several ways to get around this until the extender is updated. Below is a couple of approaches.


This makes use of WB's COM subsystem to get the property so that you do not have to convert the large integer string returned by the extender into a two part integer needed by the system time functions.

#DefineFunction ADSITimeToYmdHms(nHighPart, nLowPart)

   FileTime   = BinaryAlloc(8)
   FileTime2  = BinaryAlloc(8)
   SystemTime = BinaryAlloc(16)

   BinaryPoke4(FileTime,0,nLowPart)
   BinaryPoke4(FileTime,4,nHighPart)
   BinaryEodSet(SystemTime,16)

   sdll = StrCat(DirWindows(1),"kernel32.dll")
   flag = DllCall(sdll,long:"FileTimeToLocalFileTime", lpbinary:FileTime, lpbinary:FileTime2)
   flag = DllCall(sdll,long:"FileTimeToSystemTime", lpbinary:FileTime2, lpbinary:SystemTime)

   year   = BinaryPeek2(SystemTime,0)
   month  = StrFixLeft(BinaryPeek2(SystemTime,2),0,2)
   day    = StrFixLeft(BinaryPeek2(SystemTime,6),0,2)
   hour   = StrFixLeft(BinaryPeek2(SystemTime,8),0,2)
   minute = StrFixLeft(BinaryPeek2(SystemTime,10),0,2)
   second = StrFixLeft(BinaryPeek2(SystemTime,12),0,2)
   BinaryFree(FileTime)
   BinaryFree(FileTime2)
   BinaryFree(SystemTime)
   ymdhms = StrCat(year,":",month,":",day,":",hour,":",minute,":",second)

   Return (ymdhms)

#EndFunction


; Use COM so we don't have to take the time to convert from a
; large integer string to a high/low integer pair.
sPath     = "LDAP://shamrock/CN=Homer Simpson,CN=Users,DC=jclass,DC=org"
sProperty = "lastLogonTimeStamp"
objNameSpace = GetObject("LDAP:")

objUser = objNameSpace.OpenDSObject(sPath, "shamrock\guesswho","*topsecret*", 1)
objDate = objUser.Get(sProperty)

time = ADSITimeToYmdHms(objDate.highpart, objDate.lowpart)
Message(sProperty, Time)
objDate = 0
objUser = 0
objNameSpace = 0


Here is a simple way to split the 64 bit integer time returned by the ADSI extender into high and low parts using the huge math extender and the previously posted time conversion UDF.

AddExtender("wwhug34i.dll")

sBigIntTime = "127838008208899037"
sBitShift   = "4294967296"

sTemp       = huge_Divide(sBigIntTime, sBitShift)
sHighPart   = ItemExtract(1, sTemp, ".")

sTemp       = huge_Multiply(sHighPart, sBitShift )
sLowPart    = huge_Subtract(sBigIntTime, sTemp)

sYmdHms = ADSITimeToYmdHms(sHighPart, sLowPart)
Message( "WIL Time:", sYmdHms)


Here is one more way to convert the large int to a date. This is a quick way to get the day to the nearest day. It can be modified to get the exact time if desired.

; Value to convert.
nLastLogon = "127838008208899037"
nLastLogon = StrCat(nLastLogon, ".0")

; January 1, 1601 - day that time began.
DayOne = "1601:01:01:00:00:00"

; 100 nanos to minutes.
nLastLogon = nLastLogon / (60 * 10000000.0)

; Minutes to days.
nLastLogon = nLastLogon / 1440

; Days in WIL time.
Days = StrCat("00:00:", Int(nLastLogon), ":00:00:00")

sLastLogon = TimeAdd( DayOne, Days)
Message("LastLogonTimeStamp", sLastlogon)

Article ID:   W16804
File Created: 2007:07:03:14:26:20
Last Updated: 2007:07:03:14:26:20