AdamUL Posted November 16, 2011 Share Posted November 16, 2011 (edited) I modified the _AD_GetPasswordExpired function above to create a new function, and it seems to work. expandcollapse popup; #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_GetLastLogonTimeStampEdit: Updated code.Adam Edited November 5, 2013 by AdamUL Link to comment Share on other sites More sharing options...
water Posted November 16, 2011 Share Posted November 16, 2011 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 2024-07-28 - Version 1.6.3.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 (2022-07-28 - Version 1.6.0.1) - Download - General Help & Support - Wiki Standard UDFs: Excel - Example Scripts - Wiki Word - Wiki Tutorials: ADO - Wiki WebDriver - Wiki Link to comment Share on other sites More sharing options...
shornw Posted November 17, 2011 Author Share Posted November 17, 2011 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 comment Share on other sites More sharing options...
water Posted November 17, 2011 Share Posted November 17, 2011 No problem My UDFs and Tutorials: Spoiler UDFs: Active Directory (NEW 2024-07-28 - Version 1.6.3.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 (2022-07-28 - Version 1.6.0.1) - Download - General Help & Support - Wiki Standard UDFs: Excel - Example Scripts - Wiki Word - Wiki Tutorials: ADO - Wiki WebDriver - Wiki Link to comment Share on other sites More sharing options...
AdamUL Posted November 17, 2011 Share Posted November 17, 2011 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 comment Share on other sites More sharing options...
shornw Posted November 28, 2011 Author Share Posted November 28, 2011 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 comment Share on other sites More sharing options...
water Posted November 28, 2011 Share Posted November 28, 2011 Try $aResult = _AD_GetPasswordExpiredEX("", False, Number($days), True)because InputBox returns a string. My UDFs and Tutorials: Spoiler UDFs: Active Directory (NEW 2024-07-28 - Version 1.6.3.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 (2022-07-28 - Version 1.6.0.1) - Download - General Help & Support - Wiki Standard UDFs: Excel - Example Scripts - Wiki Word - Wiki Tutorials: ADO - Wiki WebDriver - Wiki Link to comment Share on other sites More sharing options...
shornw Posted November 28, 2011 Author Share Posted November 28, 2011 So easy when you know how, something new learned . Works perfectly, thank you Water [font='Comic Sans MS']Eagles may soar high but weasels dont get sucked into jet engines[/font] Link to comment Share on other sites More sharing options...
water Posted November 28, 2011 Share Posted November 28, 2011 My UDFs and Tutorials: Spoiler UDFs: Active Directory (NEW 2024-07-28 - Version 1.6.3.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 (2022-07-28 - Version 1.6.0.1) - Download - General Help & Support - Wiki Standard UDFs: Excel - Example Scripts - Wiki Word - Wiki Tutorials: ADO - Wiki WebDriver - Wiki Link to comment Share on other sites More sharing options...
Recommended Posts
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 accountSign in
Already have an account? Sign in here.
Sign In Now