Jump to content

AD UDF: lastLogon, lastLogonTimestamp results empty values

Recommended Posts

$l_ret = _AD_GetObjectAttribute(@username,"lastLogon")
MsgBox(64,"whenCreated",$l_ret & @crlf & @error)

$l_ret has no value and no error (error is 0).

Same Probleme here:

$l_user = _AD_GetObjectsInOU("OU=test,OU=example,DC=mydomain,DC=domain,DC=com","(name=*)",2,"sAMAccountName,whenCreated,lastLogon,userAccountControl","sAMAccountName")

If i displays this array sAMAccountName,whenCreated and userAccountControl have values

lastlogon values are missing...

With an LDAP Browser  i could see those values...

any ideas ??

Thanks and Regards



Edited by mko
Link to post
Share on other sites
  • mko changed the title to AD UDF: lastLogon, lastLogonTimestamp results empty values

It returns an object from memory, I use the following to calculate the date from the object:

#include <AD.au3>
#include <Array.au3>
#include <Date.au3>

    Global $g_aUserAccount = _AD_GetObjectProperties(@UserName, "samaccountname,lastlogon")
    Global $g_aUserAccounts = _AD_GetObjectsInOU("", "(&(&(objectcategory=person)(objectclass=user)(samaccountname=*)))", 2, "sAMAccountName,whenCreated,lastLogon,userAccountControl","sAMAccountName")
For $i = 1 To $g_aUserAccounts[0][0]
    $g_aUserAccounts[$i][2] = _Get_LastLogonDate($g_aUserAccounts[$i][2], 1)

Func _Get_LastLogonDate($_oLastLogon, $_iLastLogon = 1)
    Local $sAD_DTStruct, $sTemp3
    If $_iLastLogon = 1 Then
        If Not IsObj($_oLastLogon) Then Return ""
        If $_oLastLogon.LowPart = -1 Then Return ""
        If $_oLastLogon.LowPart > 0 And $_oLastLogon.HighPart > 0 Then
            $sAD_DTStruct = DllStructCreate("dword low;dword high")
            DllStructSetData($sAD_DTStruct, "Low", $_oLastLogon.LowPart)
            DllStructSetData($sAD_DTStruct, "High", $_oLastLogon.HighPart)
            $sAD_Temp = _Date_Time_FileTimeToSystemTime(DllStructGetPtr($sAD_DTStruct))
            $sTemp3 = _Date_Time_SystemTimeToTzSpecificLocalTime(DllStructGetPtr($sAD_Temp))
            Return _Date_Time_SystemTimeToDateTimeStr($sTemp3, 1)
    ; Convert IADsLargeInteger parts to 100ns count
    Local $iLastLogonLow = $_oLastLogon.LowPart
    Local $iLastLogonHigh = $_oLastLogon.HighPart
    If $iLastLogonLow < 0 Then $iLastLogonHigh += 1; Compensate for IADsLargeInteger interface error
    $iLastLogon = $iLastLogonHigh * 2 ^ 32
    $iLastLogon += $iLastLogonLow

    ; Check if user ever logged in
    If $iLastLogon = 0 Then
        Return ""
        ; Convert 100ns count to integer seconds
        Local $iSeconds = Floor($iLastLogon / 10000000)
        ; Convert seconds since 12:00AM January 01, 1601 to date string
        Local $sLastLogon = _DateAdd("S", $iSeconds, "1601/01/01 00:00:00")
        ; Return result
        Return $sLastLogon


Edited by Subz
Link to post
Share on other sites

Function _AD_GetObjectAttribute returns the values AS IS.
To get the attributes in a readable format use function _AD_GetObjetPÜroperties.

I just noticed that the documentation of this two functions needs to be enhanced ;)

My UDFs and Tutorials:


Active Directory (NEW 2021-11-10 - Version - Download - General Help & Support - Example Scripts - Wiki
ExcelChart (2017-07-21 - Version - Download - General Help & Support - Example Scripts
OutlookEX (NEW 2021-11-16 - Version - Download - General Help & Support - Example Scripts - Wiki
OutlookEX_GUI (2021-04-13 - Version - Download
Outlook Tools (2019-07-22 - Version - Download - General Help & Support - Wiki
PowerPoint (NEW 2021-08-31 - Version - Download - General Help & Support - Example Scripts - Wiki
Task Scheduler (2019-12-03 - Version - Download - General Help & Support - Wiki

Standard UDFs:
Excel - Example Scripts - Wiki
Word - Wiki

ADO - Wiki
WebDriver - Wiki


Link to post
Share on other sites

Thanks for your answer.


I cound not imagine how i should create  the $_oLastLogon object.


I have tried this...



Local $oUser = __AD_ObjGet("LDAP://" & $sAD_HostServer & "/" & $sUser)


Result is 0






Link to post
Share on other sites

Realy Great !  - I thought about it too complicated

Thanks for your help - already your first answer was correct, but I didn't read it carefully enough:(

Keypoint is to use: _Ad_GetObjectProperties instead of AD_GetObjectAttribute 

For all who stumble upon it here : If you have more then one domain controller use lastLogonTimestamp instead of lastLogon 



Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Recently Browsing   0 members

    No registered users viewing this page.

  • Similar Content

    • By Nas
      I was stuck on changing some areas on my username for some reason please check the script below :
      #include <AD.au3> #RequireAdmin _AD_Open() ; this portion works just fine _AD_ModifyAttribute("User.a", "GivenName", "John") _AD_ModifyAttribute("User.a", "displayName", "John, Smith") ; this portion I can't get it to work _AD_ModifyAttribute("User.a", "Surname", "Smith") _AD_ModifyAttribute("User.a", "City", "Orlando") _AD_ModifyAttribute("User.a", "State", "FL") _AD_ModifyAttribute("User.a", "country", "US") _AD_Close() Basically the top portion for the Givenname and display name works perfectly but the other portion I am unable to get it to work.
    • By Trinnon
      I have a question about the @error logging features in _AD_CreateUser.  Hopefully I am just missing something obvious.
      In my app I am creating a user if it does not exist then manipulating some attributes. 
      If the user does exist I would then call another function to remove groups from the user and modify some attributes.
      My question is...
      If the user already Exists, the _AD_CreateUser option gives $iValue = 0 and @error = 0.
      How can @error = 1 for the condition that the user already exists?
      I copied a small ship of the code in question along with my full .au3. 
      I am using AD UDF (Water, thanks for the awesome work on this!!!).
      $iValue = _AD_CreateUser ($sOU, $sUser, $sCN)
      If $iValue = 1 Then
            _FileWriteLog ($Log, "Func UserCheck() - User '" & $sUser & "' successfully created ==> Calling UserAttribsNewUser Function.")
            Call ("NewUser")
      ElseIf @error = 1 Then
            _FileWriteLog ($Log, $sUser & " already exists ==> Calling UserAttribsExistingUser Function.")
            Call ("ExistingUser")
    • By water
      When working on the new function _AD_GetObjectOU (returns the OU of a user, group, computer etc.) I noticed the big performance advantage you get when using ADsPath.
      (example: processing 120 users to retrieve the OU takes 207ms compared to 1041ms - so it is about 5 times faster).
      At the moment functions either accept SamAccountName or FQDN as parameters to identify an AD object.
      Where would you benefit?
      It takes a lot fo time when you use _AD_GetObjectsInOU to retrieve objects fitting the search pattern and then need to loop through the resulting array calling _AD_GetobjectProperties for each object to retrieve additional properties.
      By using ADsPath this should run much faster.
      But it needs
      me to modify a lot of functions in the AD UDF to accept ADsPath as a parameter you to change your script What do you think? Is it worth the effort.
  • Create New...