Jump to content

Recommended Posts

I modified the _AD_GetPasswordExpired function above to create a new function, and it seems to work.

 

; #FUNCTION# ====================================================================================================================
; Name...........: _AD_GetLastLogonTimeStamp
; Description ...: Returns an array of FQDNs of user or computer accounts with last logon time stamp for age specified.
; Syntax.........: _AD_GetLastLogonTimeStamp([$sAD_Root = ""[, $iAD_LastLogonAge = 0[, $bAD_Computer = False]]])
; Parameters ....: $sAD_Root - Optional: FQDN of the OU where the search should start (default = "" = search the whole tree)
; $iAD_LastLogonAge - Optional: Last logon age. (default = 0 = all ages)
; $bAD_Computer - Optional: If True queries computer accounts, if False queries user accounts (default = False)
; Return values .: Success - One-based two dimensional array of FQDNs of user accounts with last logon time stamp.
; |0 - FQDNs of user or computer accounts.
; |1 - last logon time stamp YYYY/MM/DD HH:NMM:SS UTC
; |2 - last logon time stamp YYYY/MM/DD HH:NMM:SS local time of calling user
; Failure - "", sets @error to:
; |1 - No last log on found with age.
; |2 - Specified $sAD_Root does not exist.
; |3 - $iAD_LastLogonAge is not numeric.
; Author ........: Adam Lawrence (AdamUL)
; Modified.......:
; Remarks .......: Modified from _AD_GetPasswordExpired by water.
; Related .......: _AD_GetLastLoginDate, _AD_GetPasswordExpired
; Link ..........:
; Example .......:
; ===============================================================================================================================
Func _AD_GetLastLogonTimeStamp($sAD_Root = "", $iAD_LastLogonAge = 0, $bAD_Computer = False)

If $sAD_Root = "" Then
$sAD_Root = $sAD_DNSDomain
Else
If _AD_ObjectExists($sAD_Root, "distinguishedName") = 0 Then Return SetError(2, 0, "")
EndIf
If $iAD_LastLogonAge <> 0 And Not IsNumber($iAD_LastLogonAge) Then Return SetError(3, 0, "")
Local $iAD_Temp = 0
Local $sAD_DTExpire = _Date_Time_GetSystemTime() ; Get current date/time
$sAD_DTExpire = _Date_Time_SystemTimeToDateTimeStr($sAD_DTExpire, 1) ; convert to system time
If $iAD_LastLogonAge <> 0 Then
$sAD_DTExpire = _DateAdd("D", $iAD_LastLogonAge * - 1, $sAD_DTExpire) ; substract maximum password age
Else
$sAD_DTExpire = _DateAdd("D", $iAD_Temp * - 1, $sAD_DTExpire) ; substract maximum password age
EndIf
Local $iAD_DTExpire = _DateDiff("s", "1601/01/01 00:00:00", $sAD_DTExpire) * 10000000 ; convert to Integer8
Local $sAD_DTStruct = DllStructCreate("dword low;dword high")
Local $sAD_Temp, $iAD_LowerDate = 110133216000000001 ; 110133216000000001 = 01/01/1959 00:00:00 UTC
Local $sAD_Category = "(objectCategory=Person)(objectClass=User)"
If $bAD_Computer = True Then $sAD_Category = "(objectCategory=computer)"

"(lastLogonTimestamp<=" & Int($iAD_DTExpire) & ")(lastLogonTimestamp>=" & $iAD_LowerDate & "));distinguishedName,lastLogonTimestamp,useraccountcontrol;subtree"
Local $oAD_RecordSet = $__oAD_Command.Execute
If Not IsObj($oAD_RecordSet) Or $oAD_RecordSet.RecordCount = 0 Then Return SetError(1, 0, "")
Local $aAD_FQDN[$oAD_RecordSet.RecordCount + 1][3]
$aAD_FQDN[0][0] = $oAD_RecordSet.RecordCount
Local $iAD_Count = 1
While Not $oAD_RecordSet.EOF
$aAD_FQDN[$iAD_Count][0] = $oAD_RecordSet.Fields(0).Value
$iAD_Temp = $oAD_RecordSet.Fields(1).Value
If BitAND($oAD_RecordSet.Fields(2).Value, $ADS_UF_DONT_EXPIRE_PASSWD) <> $ADS_UF_DONT_EXPIRE_PASSWD Then
DllStructSetData($sAD_DTStruct, "Low", $iAD_Temp.LowPart)
DllStructSetData($sAD_DTStruct, "High", $iAD_Temp.HighPart)
$sAD_Temp = _Date_Time_FileTimeToSystemTime(DllStructGetPtr($sAD_DTStruct))
$aAD_FQDN[$iAD_Count][1] = _Date_Time_SystemTimeToDateTimeStr($sAD_Temp, 1)
$sAD_Temp = _Date_Time_SystemTimeToTzSpecificLocalTime(DllStructGetPtr($sAD_Temp))
$aAD_FQDN[$iAD_Count][2] = _Date_Time_SystemTimeToDateTimeStr($sAD_Temp, 1)
EndIf
$iAD_Count += 1
$oAD_RecordSet.MoveNext
WEnd
Return $aAD_FQDN

EndFunc ;==>_AD_GetLastLogonTimeStamp
Edit: Updated code.

Adam

Edited by AdamUL
Link to post
Share on other sites
  • Replies 48
  • Created
  • Last Reply

Top Posters In This Topic

Top Posters In This Topic

According to this article the accuracy of the returned data highly depends on the version of the DC you run. Windows 2003 and higher is fine because the lastlogontimestamp is replicated to every DC.

Before Windows 2003 the The lastLogon attribute is not designed to provide real time logon information. With default settings in place the lastLogontimeStamp will be 9-14 days behind the current date.

So we might create a function which takes this into account.

My UDFs and Tutorials:

Spoiler

UDFs:
Active Directory (NEW 2022-02-19 - Version 1.6.1.0) - Download - General Help & Support - Example Scripts - Wiki
ExcelChart (2017-07-21 - Version 0.4.0.1) - Download - General Help & Support - Example Scripts
OutlookEX (2021-11-16 - Version 1.7.0.0) - Download - General Help & Support - Example Scripts - Wiki
OutlookEX_GUI (2021-04-13 - Version 1.4.0.0) - Download
Outlook Tools (2019-07-22 - Version 0.6.0.0) - Download - General Help & Support - Wiki
PowerPoint (2021-08-31 - Version 1.5.0.0) - Download - General Help & Support - Example Scripts - Wiki
Task Scheduler (2019-12-03 - Version 1.5.1.0) - Download - General Help & Support - Wiki

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

Tutorials:
ADO - Wiki
WebDriver - Wiki

 

Link to post
Share on other sites

I plan to release a version 1.2.0 in about a month (as soon as enough changes have accumulated).

Oh Water... what have you done? The requests are going to pour in now

[font='Comic Sans MS']Eagles may soar high but weasels dont get sucked into jet engines[/font]

Link to post
Share on other sites

No problem :D

My UDFs and Tutorials:

Spoiler

UDFs:
Active Directory (NEW 2022-02-19 - Version 1.6.1.0) - Download - General Help & Support - Example Scripts - Wiki
ExcelChart (2017-07-21 - Version 0.4.0.1) - Download - General Help & Support - Example Scripts
OutlookEX (2021-11-16 - Version 1.7.0.0) - Download - General Help & Support - Example Scripts - Wiki
OutlookEX_GUI (2021-04-13 - Version 1.4.0.0) - Download
Outlook Tools (2019-07-22 - Version 0.6.0.0) - Download - General Help & Support - Wiki
PowerPoint (2021-08-31 - Version 1.5.0.0) - Download - General Help & Support - Example Scripts - Wiki
Task Scheduler (2019-12-03 - Version 1.5.1.0) - Download - General Help & Support - Wiki

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

Tutorials:
ADO - Wiki
WebDriver - Wiki

 

Link to post
Share on other sites

I know the issue with the lastLogonTimestamp, and creating a function sounds like a good idea. The function I posted could be used to determine the age of a computer account to delete old ones.

Currently, I am using a script that parses a CSV file created by a command line utility OldCmp with the -llts options. Before using OldCmp, I tried using the _AD_GetLastLoginDate function in the AD UDF to get the data, but it was too slow looping through the array. That is why this topic peaked my interest. I like how you deal with Integer8 dates in the _AD_GetPasswordExpired function, I had no idea how to do it.

Adam

Link to post
Share on other sites
  • 2 weeks later...

After all the work Water put into this, I'm really sorry to ask more.

I am putting together something that other people can use to determine out of date devices on a number of domains, and wanted to make it a bit more flexible, so I tried to make the password age a variable so each user can vary according to their requirements -

#include <ad.au3>
#include <array.au3>
Global $aResult
$days = InputBox("Password age required", "Enter the password age (in days) required.  Devices with passwords this age and older will be displayed")
_AD_Open()
$aResult = _AD_GetPasswordExpiredEX("", False, $days, True)
_ArrayDisplay($aResult)
MsgBox(0, "Complete","")
_AD_Close(

But when I run this it doesn't query AD and immediately displays the MsgBox()

If I run

#include <ad.au3>
#include <array.au3>
Global $aResult
_AD_Open()
$aResult = _AD_GetPasswordExpiredEX("", False, 90, True)
_ArrayDisplay($aResult)
MsgBox(0, "Complete","")
_AD_Close(
it works perfectly and displays the items found.

Is there an obvious reason why I can't use a variable, or even better, a way I can.

Thanks

[font='Comic Sans MS']Eagles may soar high but weasels dont get sucked into jet engines[/font]

Link to post
Share on other sites

Try

$aResult = _AD_GetPasswordExpiredEX("", False, Number($days), True)
because InputBox returns a string.

My UDFs and Tutorials:

Spoiler

UDFs:
Active Directory (NEW 2022-02-19 - Version 1.6.1.0) - Download - General Help & Support - Example Scripts - Wiki
ExcelChart (2017-07-21 - Version 0.4.0.1) - Download - General Help & Support - Example Scripts
OutlookEX (2021-11-16 - Version 1.7.0.0) - Download - General Help & Support - Example Scripts - Wiki
OutlookEX_GUI (2021-04-13 - Version 1.4.0.0) - Download
Outlook Tools (2019-07-22 - Version 0.6.0.0) - Download - General Help & Support - Wiki
PowerPoint (2021-08-31 - Version 1.5.0.0) - Download - General Help & Support - Example Scripts - Wiki
Task Scheduler (2019-12-03 - Version 1.5.1.0) - Download - General Help & Support - Wiki

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

Tutorials:
ADO - Wiki
WebDriver - Wiki

 

Link to post
Share on other sites
:D

My UDFs and Tutorials:

Spoiler

UDFs:
Active Directory (NEW 2022-02-19 - Version 1.6.1.0) - Download - General Help & Support - Example Scripts - Wiki
ExcelChart (2017-07-21 - Version 0.4.0.1) - Download - General Help & Support - Example Scripts
OutlookEX (2021-11-16 - Version 1.7.0.0) - Download - General Help & Support - Example Scripts - Wiki
OutlookEX_GUI (2021-04-13 - Version 1.4.0.0) - Download
Outlook Tools (2019-07-22 - Version 0.6.0.0) - Download - General Help & Support - Wiki
PowerPoint (2021-08-31 - Version 1.5.0.0) - Download - General Help & Support - Example Scripts - Wiki
Task Scheduler (2019-12-03 - Version 1.5.1.0) - Download - General Help & Support - Wiki

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

Tutorials:
ADO - Wiki
WebDriver - Wiki

 

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.

×
×
  • Create New...