IanN1990 Posted April 28, 2016 Share Posted April 28, 2016 (edited) Good Evening, Last AD question for now I am pulling down alot of information from ad using the following ; #include <AD.au3> #include <array.au3> sOU = _AD_Open() $Results = _AD_GetObjectsInOU($sOU, "(name=*)", 2, "name,accountexpires") _Arraydisplay($Results) _AD_Close() It pulls down all the names in colum one but colum 2 is empty If i did $Result = _AD_GetObjectProperties("ian.1990,"accountexpires") _ArrayDisplay($Result) It would bring down when my account expires *Note i am trying to avoid using the function _GetExpiredAccounts as i want to understand why GetObjectsinOU is not working Kind regards Ian Edited April 28, 2016 by IanN1990 Link to comment Share on other sites More sharing options...
water Posted April 28, 2016 Share Posted April 28, 2016 You get the expiration date by _AD_GetObjectsInOU but in a format you can't read. So I suggest to use function _AD__GetAccountsExpired. 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...
IanN1990 Posted April 28, 2016 Author Share Posted April 28, 2016 (edited) So is it the case that colum 2 is not empty and has pulled down the expiry date but because of the format it is not being displayed? Does that also mean in theory i could do something like consolewrite(ConvertExpiretoReadable($Results[1][1])) Func ConvertExpiretoReadable($ArrayExpireResult) Something... Something.. Return $Expire Endfunc Edited April 28, 2016 by IanN1990 Link to comment Share on other sites More sharing options...
water Posted April 28, 2016 Share Posted April 28, 2016 Correct. Check function _AD_GetObjectsInOU to see how it translates property "accountexpires". But be warned: It's a bit complex 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...
IanN1990 Posted April 28, 2016 Author Share Posted April 28, 2016 (edited) I have the source code for _AD_GetObjectsinOU open in a different tab but i admit i am not sure what i am looking for. I cant find any related to "accountexpires" in the function itself? Edited April 28, 2016 by IanN1990 Link to comment Share on other sites More sharing options...
water Posted April 28, 2016 Share Posted April 28, 2016 Ops, my bad. _AD_GetObjectsInOU returns the data "as is". I was talking about _AD_GetObjectProperties which returns the data in readable form. 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...
IanN1990 Posted April 28, 2016 Author Share Posted April 28, 2016 (edited) Ah that makes sense. Looking into _AD_GetObjectProperties i see what you mean. Thanks for givng me a lead to work with as previously i had drawn a blank. Tomorrow i will look into this function in more detail and see what i can glimmer. Edited April 28, 2016 by IanN1990 Link to comment Share on other sites More sharing options...
IanN1990 Posted April 29, 2016 Author Share Posted April 29, 2016 So I have looked into the function but as you said, it is complex. I am only asking you this next question because from what I can see, AD.au3 is something you have created ElseIf $oItem.ADsType = $ADSTYPE_LARGE_INTEGER Then If $oItem.Name = "pwdLastSet" Or $oItem.Name = "accountExpires" Or $oItem.Name = "lastLogonTimestamp" Or $oItem.Name = "badPasswordTime" Or $oItem.Name = "lastLogon" Or $oItem.Name = "lockoutTime" Then If $vPropertyValue.LargeInteger.LowPart = 0 And $vPropertyValue.LargeInteger.HighPart = 0 Then $aObjectProperties[$iCount3][1] = "1601/01/01 00:00:00" Else Local $sTemp = DllStructCreate("dword low;dword high") DllStructSetData($sTemp, "Low", $vPropertyValue.LargeInteger.LowPart) DllStructSetData($sTemp, "High", $vPropertyValue.LargeInteger.HighPart) Local $sTemp2 = _Date_Time_FileTimeToSystemTime(DllStructGetPtr($sTemp)) Local $sTemp3 = _Date_Time_SystemTimeToTzSpecificLocalTime(DllStructGetPtr($sTemp2)) $aObjectProperties[$iCount3][1] = _Date_Time_SystemTimeToDateTimeStr($sTemp3, 1) EndIf Else $aObjectProperties[$iCount3][1] = __AD_LargeInt2Double($vPropertyValue.LargeInteger.LowPart, $vPropertyValue.LargeInteger.HighPart) EndIf Is the code that seams to refer to expired details but I don't seam to be able convert the data gathered from OU Link to comment Share on other sites More sharing options...
water Posted April 29, 2016 Share Posted April 29, 2016 The problem is that _AD_GetObjectsInOU does not return property objects but only strings. So you can't use $oItem.ADsType or $vPropertyValue.LargeInteger.LowPart. The function processes a large integer (https://msdn.microsoft.com/de-de/library/windows/desktop/aa383710(v=vs.85).aspx) and returns a date/time string. As you now have a string you could fill the DllStruct (DllStuctSetData) with the high and low 4 bytes and then call the _Date* functions. Never tried it myself and can't test at the moment. 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...
IanN1990 Posted April 29, 2016 Author Share Posted April 29, 2016 Here is what I tired following your advice #include <AD.au3> #include <array.au3> $sOU = _AD_Open() $Array = _AD_GetObjectsInOU($Domain, "(name=*)", 2, "name, accountexpires", "") For $i=1 to 1000 _AD_GetObjectProperties1($Array[$i][1]) Next _AD_Close() Exit Func _AD_GetObjectProperties1($vPropertyValue) Local $sTemp = DllStructCreate("dword low;dword high") DllStructSetData($sTemp, "Low", $vPropertyValue.LargeInteger.LowPart) DllStructSetData($sTemp, "High", $vPropertyValue.LargeInteger.HighPart) Local $sTemp2 = _Date_Time_FileTimeToSystemTime(DllStructGetPtr($sTemp)) Local $sTemp3 = _Date_Time_SystemTimeToTzSpecificLocalTime(DllStructGetPtr($sTemp2)) ConsoleWrite(_Date_Time_SystemTimeToDateTimeStr($sTemp3, 1) & @crlf) EndFunc ;==>_AD_GetObjectProperties It produces a 1,000 list of 1601/01/01 00:00:00 which from testing is the same if I ran the command with "" Link to comment Share on other sites More sharing options...
IanN1990 Posted April 29, 2016 Author Share Posted April 29, 2016 I have also gone through the list and AD manually to confirm there are defo expired accounts in there Link to comment Share on other sites More sharing options...
water Posted April 29, 2016 Share Posted April 29, 2016 I'm sure $vPropertyValue.LargeInteger.LowPart doesn't work as $vPropertyValue is not an object. What do you get when you run ConsoleWrite(StringLen($vPropertyValue) & @CRLF) in your function? 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...
IanN1990 Posted April 30, 2016 Author Share Posted April 30, 2016 Thanks for sticking with this water and sorry for the delayed response. I remoted into my work pc and added the line. The result was 0 1601/01/01 01:00:00 I fear this means for me to get the expired information, it will mean rewritting or editing the _AD_GetObjectsInOU function as i imagine as that would provide the objects we need? Link to comment Share on other sites More sharing options...
water Posted May 1, 2016 Share Posted May 1, 2016 (edited) I would do it this way: $aArray = _AD_GetObjectsInOU($sDomain, "(name=*)", 2, "samaccountname,name", "") For $i=1 to $aArray[0][0] $aExpires = _AD_GetObjectProperties($aArray[$i][0], "accountexpires") ConsoleWrite("User " & $aArray[$i][0] & " expires on " & $aExpires[1][0]) Next I will check if I can make this a bit faster. Edited May 1, 2016 by water 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...
IanN1990 Posted May 1, 2016 Author Share Posted May 1, 2016 (edited) I tired your function but as you say it is very slow In some instances, taking almost minutes to complete. I tired to dig a little into my previous idea to see if it was to much of a long shot and here is what i found expandcollapse popupFunc _AD_GetObjectsInOU($sOU = "", $sFilter = "(name=*)", $iSearchScope = 2, $sDataToRetrieve = "sAMAccountName", $sSortBy = "sAMAccountName", $bCount = False, $vReturnNull = True) If $sOU = "" Then $sOU = $sAD_DNSDomain Else If _AD_ObjectExists($sOU, "distinguishedName") = 0 Then Return SetError(1, 0, "") EndIf Local $sReturnNull = "" If Not IsBool($vReturnNull) Then $sReturnNull = $vReturnNull $vReturnNull = False EndIf Local $iCount2, $aDataToRetrieve, $aTemp If $sDataToRetrieve = "" Then $sDataToRetrieve = "sAMAccountName" $sDataToRetrieve = StringStripWS($sDataToRetrieve, 8) $__oAD_Command.Properties("Searchscope") = $iSearchScope $__oAD_Command.CommandText = "<LDAP://" & $sAD_HostServer & "/" & $sOU & ">;" & $sFilter & ";" & $sDataToRetrieve $__oAD_Command.Properties("Sort On") = $sSortBy Local $oRecordSet = $__oAD_Command.Execute If @error Or Not IsObj($oRecordSet) Then Return SetError(2, @error, "") Local $iCount1 = $oRecordSet.RecordCount If $iCount1 = 0 Then If $bCount Then Return SetError(3, 0, 0) Return SetError(3, 0, "") EndIf If $bCount Then Return $iCount1 If StringInStr($sDataToRetrieve, ",") Then ConsoleWrite("A") $aDataToRetrieve = StringSplit($sDataToRetrieve, ",") Local $aObjects[$iCount1 + 1][$aDataToRetrieve[0]] $aObjects[0][0] = $iCount1 $aObjects[0][1] = $aDataToRetrieve[0] $iCount2 = 1 $oRecordSet.MoveFirst Do For $iCount1 = 1 To $aDataToRetrieve[0] If IsArray($oRecordSet.Fields($aDataToRetrieve[$iCount1]).Value) Then $aTemp = $oRecordSet.Fields($aDataToRetrieve[$iCount1]).Value $aObjects[$iCount2][$iCount1 - 1] = _ArrayToString($aTemp) Else $aObjects[$iCount2][$iCount1 - 1] = $oRecordSet.Fields($aDataToRetrieve[$iCount1]).Value If Not $vReturnNull And IsKeyword($aObjects[$iCount2][$iCount1 - 1]) = $KEYWORD_NULL Then $aObjects[$iCount2][$iCount1 - 1] = $sReturnNull EndIf Next $oRecordSet.MoveNext $iCount2 += 1 Until $oRecordSet.EOF Else Local $aObjects[$iCount1 + 1] $aObjects[0] = UBound($aObjects) - 1 $iCount2 = 1 $oRecordSet.MoveFirst Do If IsArray($oRecordSet.Fields($sDataToRetrieve).Value) Then $aTemp = $oRecordSet.Fields($sDataToRetrieve).Value $aObjects[$iCount2] = _ArrayToString($aTemp) Else $aTemp = $oRecordSet.Fields($sDataToRetrieve).Value Local $sTemp = DllStructCreate("dword low;dword high") DllStructSetData($sTemp, "Low", $aTemp.LargeInteger.LowPart) DllStructSetData($sTemp, "High", $aTemp.LargeInteger.HighPart) Local $sTemp2 = _Date_Time_FileTimeToSystemTime(DllStructGetPtr($sTemp)) Local $sTemp3 = _Date_Time_SystemTimeToTzSpecificLocalTime(DllStructGetPtr($sTemp2)) ConsoleWrite(_Date_Time_SystemTimeToDateTimeStr($sTemp3, 1) & @crlf) $aObjects[$iCount2] = $oRecordSet.Fields($sDataToRetrieve).Value EndIf $oRecordSet.MoveNext $iCount2 += 1 Until $oRecordSet.EOF EndIf $__oAD_Command.Properties("Sort On") = "" ; Reset sort property Return $aObjects EndFunc ;==>_AD_GetObjectsInOU I found where the code runs when processing accountexpires, we have the code that converts it into an expired date, we have the code processing objects but now finding what object to use doesn't seam to be working Edited May 1, 2016 by IanN1990 Link to comment Share on other sites More sharing options...
water Posted May 1, 2016 Share Posted May 1, 2016 (edited) Another idea is to play with the brushed up version of _AD_GetObjectsInOU written by JoshuaBarnette. Unfortunately it is not faster then the code I posted above. Edited May 1, 2016 by water 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...
water Posted May 1, 2016 Share Posted May 1, 2016 (edited) I was able to reduce execution time of _AD_GetObjectProperties. I query about 3500 users. The following script runs 161 seconds with the current function and 36 seconds with the new one: #include <AD.au3> _AD_Open() Global $iTimer = TimerInit() $aArray = _AD_GetObjectsInOU("", "(&(objectcategory=person)(objectclass=user)(name=*))", 2, "samaccountname,name", "") For $i=1 to $aArray[0][0] $aExpires = _AD_GetObjectPropertiesEX($aArray[$i][0], "accountexpires") Next ConsoleWrite(TimerDiff($iTimer) & @CRLF) _AD_Close() New function (named: _AD_GetobjectPropertiesEX): expandcollapse popup; #FUNCTION# ==================================================================================================================== ; Name...........: _AD_GetObjectProperties ; Description ...: Returns a two-dimensional array of all or selected properties and their values of an object in readable form. ; Syntax.........: _AD_GetObjectProperties([$vObject = @UserName[, $sProperties = ""[, $bSort = True]]]) ; Parameters ....: $vObject - Optional: SamAccountName, FQDN or ADSPath of the object to retrieve properties from (e.g. computer, user, group ...) (default = @Username) ; |Can be of type object as well. Useful to get properties for a schema or configuration object (see _AD_ListRootDSEAttributes) ; $sProperties - Optional: Comma separated list of properties to return (default = "" = return all properties) ; $bSort - Optional: True specifies that the array will be sorted on property name (default = True) ; Return values .: Success - Returns a one based two-dimensional array with all properties and their values of an object in readable form ; Failure - "" or property name, sets @error to: ; |1 - $vObject could not be found ; |2 - No values for the specified property. The property in error is returned as the function result ; |3 - Error retrieving $vObject. @Extended is set to the error returned by LDAP ; Author ........: Sundance ; Modified.......: water ; Remarks .......: Dates are returned in format: YYYY/MM/DD HH:MM:SS local time of the calling user (AD stores all dates in UTC - Universal Time Coordinated) ; Exception: AD internal dates like "whenCreated", "whenChanged" and "dSCorePropagationData". They are returned as UTC ; NT Security Descriptors are returned as: Control:nn, Group:Domain\Group, Owner:Domain\Group, Revision:nn ; No error is returned if there are properties in $sProperties that are not available for the selected object ;+ ; Properties are returned in alphabetical order. If $sProperties is set to "samaccountname,displayname" the returned array will contain ; displayname as the first and samaccountname as the second row. ; Related .......: ; Link ..........: http://www.autoitscript.com/forum/index.php?showtopic=49627&view=findpost&p=422402, http://msdn.microsoft.com/en-us/library/ms675090(VS.85).aspx ; Example .......: Yes ; =============================================================================================================================== Func _AD_GetObjectPropertiesEx($vObject = @UserName, $sProperties = "", $bSort = True) Local $aObjectProperties[1000][2], $oObject Local $oProperty, $oPropertyEntry, $oValue, $iPropertyRecord = 0, $xAD_Dummy ; Data Type Mapping between Active Directory and LDAP ; http://msdn.microsoft.com/en-us/library/aa772375(VS.85).aspx Local Const $ADSTYPE_DN_STRING = 1 Local Const $ADSTYPE_CASE_IGNORE_STRING = 3 Local Const $ADSTYPE_BOOLEAN = 6 Local Const $ADSTYPE_INTEGER = 7 Local Const $ADSTYPE_OCTET_STRING = 8 Local Const $ADSTYPE_UTC_TIME = 9 Local Const $ADSTYPE_LARGE_INTEGER = 10 Local Const $ADSTYPE_NT_SECURITY_DESCRIPTOR = 25 Local Const $ADSTYPE_UNKNOWN = 26 Local $aSAMAccountType[12][2] = [["DOMAIN_OBJECT", 0x0], ["GROUP_OBJECT", 0x10000000], ["NON_SECURITY_GROUP_OBJECT", 0x10000001], _ ["ALIAS_OBJECT", 0x20000000], ["NON_SECURITY_ALIAS_OBJECT", 0x20000001], ["USER_OBJECT", 0x30000000], ["NORMAL_USER_ACCOUNT", 0x30000000], _ ["MACHINE_ACCOUNT", 0x30000001], ["TRUST_ACCOUNT", 0x30000002], ["APP_BASIC_GROUP", 0x40000000], ["APP_QUERY_GROUP", 0x40000001], _ ["ACCOUNT_TYPE_MAX", 0x7fffffff]] Local $aUAC[21][2] = [[0x00000001, "SCRIPT"], [0x00000002, "ACCOUNTDISABLE"], [0x00000008, "HOMEDIR_REQUIRED"], [0x00000010, "LOCKOUT"], [0x00000020, "PASSWD_NOTREQD"], _ [0x00000040, "PASSWD_CANT_CHANGE"], [0x00000080, "ENCRYPTED_TEXT_PASSWORD_ALLOWED"], [0x00000100, "TEMP_DUPLICATE_ACCOUNT"], [0x00000200, "NORMAL_ACCOUNT"], _ [0x00000800, "INTERDOMAIN_TRUST_ACCOUNT"], [0x00001000, "WORKSTATION_TRUST_ACCOUNT"], [0x00002000, "SERVER_TRUST_ACCOUNT"], [0x00010000, "DONT_EXPIRE_PASSWD"], _ [0x00020000, "MNS_LOGON_ACCOUNT"], [0x00040000, "SMARTCARD_REQUIRED"], [0x00080000, "TRUSTED_FOR_DELEGATION"], [0x00100000, "NOT_DELEGATED"], _ [0x00200000, "USE_DES_KEY_ONLY"], [0x00400000, "DONT_REQUIRE_PREAUTH"], [0x00800000, "PASSWORD_EXPIRED"], [0x01000000, "TRUSTED_TO_AUTHENTICATE_FOR_DELEGATION"]] If Not IsObj($vObject) Then If StringLeft($vObject, 7) <> "LDAP://" Then ; No ADsPath If _AD_ObjectExists($vObject) = 0 Then Return SetError(1, 0, "") Local $sProperty = "sAMAccountName" If StringMid($vObject, 3, 1) = "=" Then $sProperty = "distinguishedName"; FQDN provided $__oAD_Command.CommandText = "<LDAP://" & $sAD_HostServer & "/" & $sAD_DNSDomain & ">;(" & $sProperty & "=" & $vObject & ");ADsPath;subtree" Local $oRecordSet = $__oAD_Command.Execute ; Retrieve the ADsPath for the object If @error Or Not IsObj($oRecordSet) Then Return SetError(3, @error, "") $vObject = $oRecordSet.fields(0).Value EndIf $oObject = __AD_ObjGet($vObject) ; Retrieve the COM Object Else $oObject = $vObject EndIf If $sProperties = "" Then $oObject.GetInfo() ; Refresh values of all properties in the property cache of the ADSI object Else Local $aProperties = StringSplit($sProperties, ",", $STR_NOCOUNT) $oObject.GetInfoEX($aProperties, 0) ; Refresh values of the selected properties in the property cache of the ADSI object EndIf Local $iPropertyCount = $oObject.PropertyCount() For $iCurrentProperty = 0 To $iPropertyCount - 1 $oProperty = $oObject.Item($iCurrentProperty) $oPropertyEntry = $oObject.GetPropertyItem($oProperty.Name, $ADSTYPE_UNKNOWN) $sPropertyName = $oProperty.Name If Not IsObj($oPropertyEntry) Then Return SetError(2, 0, $sPropertyName) For $vPropertyValue In $oPropertyEntry.Values $iPropertyRecord = $iPropertyRecord + 1 $aObjectProperties[$iPropertyRecord][0] = $sPropertyName Switch $oProperty.ADsType Case $ADSTYPE_CASE_IGNORE_STRING $aObjectProperties[$iPropertyRecord][1] = $vPropertyValue.CaseIgnoreString Case $ADSTYPE_INTEGER If $sPropertyName = "sAMAccountType" Then For $iCount4 = 0 To UBound($aSAMAccountType) - 1 If $vPropertyValue.Integer = $aSAMAccountType[$iCount4][1] Then $aObjectProperties[$iPropertyRecord][1] = $aSAMAccountType[$iCount4][0] ExitLoop EndIf Next ElseIf $sPropertyName = "userAccountControl" Then $aObjectProperties[$iPropertyRecord][1] = $vPropertyValue.Integer & " = " For $iCount4 = 0 To UBound($aUAC) - 1 If BitAND($vPropertyValue.Integer, $aUAC[$iCount4][0]) = $aUAC[$iCount4][0] Then $aObjectProperties[$iPropertyRecord][1] &= $aUAC[$iCount4][1] & " - " EndIf Next If StringRight($aObjectProperties[$iPropertyRecord][1], 3) = " - " Then $aObjectProperties[$iPropertyRecord][1] = StringTrimRight($aObjectProperties[$iPropertyRecord][1], 3) Else $aObjectProperties[$iPropertyRecord][1] = $vPropertyValue.Integer EndIf Case $ADSTYPE_LARGE_INTEGER If $sPropertyName = "pwdLastSet" Or $sPropertyName = "accountExpires" Or $sPropertyName = "lastLogonTimestamp" Or $sPropertyName = "badPasswordTime" Or $sPropertyName = "lastLogon" Or $sPropertyName = "lockoutTime" Then If $vPropertyValue.LargeInteger.LowPart = 0 And $vPropertyValue.LargeInteger.HighPart = 0 Then $aObjectProperties[$iPropertyRecord][1] = "1601/01/01 00:00:00" Else Local $sTemp = DllStructCreate("dword low;dword high") DllStructSetData($sTemp, "Low", $vPropertyValue.LargeInteger.LowPart) DllStructSetData($sTemp, "High", $vPropertyValue.LargeInteger.HighPart) Local $sTemp2 = _Date_Time_FileTimeToSystemTime(DllStructGetPtr($sTemp)) Local $sTemp3 = _Date_Time_SystemTimeToTzSpecificLocalTime(DllStructGetPtr($sTemp2)) $aObjectProperties[$iPropertyRecord][1] = _Date_Time_SystemTimeToDateTimeStr($sTemp3, 1) EndIf Else $aObjectProperties[$iPropertyRecord][1] = __AD_LargeInt2Double($vPropertyValue.LargeInteger.LowPart, $vPropertyValue.LargeInteger.HighPart) EndIf Case $ADSTYPE_OCTET_STRING $xAD_Dummy = DllStructCreate("byte[56]") DllStructSetData($xAD_Dummy, 1, $vPropertyValue.OctetString) ; objectSID etc. See: http://msdn.microsoft.com/en-us/library/aa379597(VS.85).aspx ; objectGUID etc. See: http://www.autoitscript.com/forum/index.php?showtopic=106163&view=findpost&p=767558 If _Security__IsValidSid(DllStructGetPtr($xAD_Dummy)) Then $aObjectProperties[$iPropertyRecord][1] = _Security__SidToStringSid(DllStructGetPtr($xAD_Dummy)) ; SID Else $aObjectProperties[$iPropertyRecord][1] = _WinAPI_StringFromGUID(DllStructGetPtr($xAD_Dummy)) ; GUID EndIf Case $ADSTYPE_DN_STRING $aObjectProperties[$iPropertyRecord][1] = $vPropertyValue.DNString Case $ADSTYPE_UTC_TIME $aObjectProperties[$iPropertyRecord][1] = StringRegExpReplace($vPropertyValue.UTCTime, "(\d{4})(\d{2})(\d{2})(\d{2})(\d{2})(\d{2})", "$1/$2/$3 $4:$5:$6") ; YYYY/MM/DD HH:MM:SS Case $ADSTYPE_BOOLEAN If $vPropertyValue.Boolean = 0 Then $aObjectProperties[$iPropertyRecord][1] = "False" Else $aObjectProperties[$iPropertyRecord][1] = "True" EndIf Case $ADSTYPE_NT_SECURITY_DESCRIPTOR $oValue = $vPropertyValue.SecurityDescriptor $aObjectProperties[$iPropertyRecord][1] = "Control:" & $oValue.Control & ", " & _ "Group:" & $oValue.Group & ", " & _ "Owner:" & $oValue.Owner & ", " & _ "Revision:" & $oValue.Revision Case Else $aObjectProperties[$iPropertyRecord][1] = "Has the unknown ADsType: " & $oProperty.ADsType EndSwitch Next Next ReDim $aObjectProperties[$iPropertyRecord + 1][2] $aObjectProperties[0][0] = $iPropertyRecord $aObjectProperties[0][1] = 2 If $bSort And $iPropertyRecord > 1 Then _ArraySort($aObjectProperties, 0, 1) ; Only sort if flag is set and array contains > 1 records Return $aObjectProperties EndFunc ;==>_AD_GetObjectPropertiesEx Edit: The new function is included in the new version 1.4.4.0 of the UDF. Edited May 3, 2016 by water IanN1990 1 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...
IanN1990 Posted January 10, 2017 Author Share Posted January 10, 2017 Hey, I am trying to get the information from "LastLogOff" and was reminded of this topic :). I tired _AD_GetObjectAttribute(@UserName, "lastlogoff") Returns Blank I used _AD_GetObjectProperties(@Username) and see LastLogOff is 0 but this seams to be for every user i select. I wondered if it is related to this topic. LastLogOff being an object and to get the values you need to use the high & lows. So i tired _AD_GetObjectPropertiesEX(@username, "lastLogoff") This returns an array with LastLogOff being 0. Where have i gone wrong ^^ Link to comment Share on other sites More sharing options...
water Posted January 10, 2017 Share Posted January 10, 2017 Add "lastLogoff" to this line in function _AD_GetObjectProperties: If $sPropertyName = "pwdLastSet" Or $sPropertyName = "accountExpires" Or $sPropertyName = "lastLogonTimestamp" Or $sPropertyName = "badPasswordTime" Or $sPropertyName = "lastLogon" Or $sPropertyName = "lockoutTime" Or $sPropertyName = "lastLogoff" Then ; "lastLogoff" already added at the end of the line IanN1990 1 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...
water Posted January 10, 2017 Share Posted January 10, 2017 (edited) Seems this attribute still istn't used by MS. How to record the last logoff date/time is described here: https://www.ldapsoft.com/adlogoffreport.html Edit: And it does not get replicated. This means you need to query all DCs to get the "real" lastlogoff date/time. Edited January 10, 2017 by water IanN1990 1 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