legend Posted November 25, 2019 Share Posted November 25, 2019 Just now, water said: The wiki is your friend A computer account needs a trailing "$": If _AD_IsObjectDisabled("FT4534$") Then Ah that rings a bell, I completely forgot that, thanks so much Link to comment Share on other sites More sharing options...
water Posted November 25, 2019 Author Share Posted November 25, 2019 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...
mprudhomme Posted September 14, 2020 Share Posted September 14, 2020 (edited) Hello, To begin with I have been using the UDF for several years, it is great. However, I have two problems: 1- See the screenshot above, it seems that there is a bad recognition when the names include a - Everything that is in the OU "Et_2" is found by mistake in the OU "Et_-2". 2- I also have names with spaces. I saw the remark on this subject "If an OU contains spaces the sorting is wrong and might lead to problems in further processing. Please have a look at http://www.autoitscript.com/forum/topic/106163-active-directory-udf/page__view__findpost__p__943892 " But I admit that I did not quite understand the solution that must be put in place to correct this, can you give me more specific information? Thank you in advance for your help. Edited September 14, 2020 by mprudhomme Link to comment Share on other sites More sharing options...
water Posted September 14, 2020 Author Share Posted September 14, 2020 I have taken and added the modifications made by trancexx (they are quite old and I'm sure the Array-functions have evolved over time). You get the array and then the function displays the empty GUI. If the content of the array is correct, you can remove the lines makred with ("; <== Remove if the Treeview should be generated") in function _AD_GetOUTreeView. Spoiler expandcollapse popup#Region ;**** Directives created by AutoIt3Wrapper_GUI **** #AutoIt3Wrapper_UseX64=n #EndRegion ;**** Directives created by AutoIt3Wrapper_GUI **** #include <AD.au3> #include <Excel.au3> #include <TreeviewConstants.au3> #include <WindowsConstants.au3> #include <GUIConstants.au3> #include <GuiTreeView.au3> Global $sTitle = "Active Direcory OU Treeview" #Region ### START Koda GUI section ### Form= Global $hMain = GUICreate($sTitle, 743, 683, -1, -1) Global $idTree = GUICtrlCreateTreeView(6, 6, 600, 666, -1, $WS_EX_CLIENTEDGE) Global $idExit = GUICtrlCreateButton("Exit", 624, 8, 97, 33) Global $idExpand = GUICtrlCreateButton("Expand all", 624, 56, 97, 33) Global $idCollapse = GUICtrlCreateButton("Collapse all", 624, 104, 97, 33) Global $idSelect = GUICtrlCreateButton("Select OU", 624, 152, 97, 33) Global $idExport = GUICtrlCreateButton("Export -> Excel", 624, 200, 97, 33) Global $idProgress = GUICtrlCreateProgress(624, 248, 97, 20) GUISetState(@SW_SHOW) #EndRegion ### END Koda GUI section ### Global $__aTreeView ;------------------------------ ; Make your changes below ;------------------------------ Global $sOU = "" ; FQDN of the OU where to start Global $sCategory = "computer" ; Category to select when counts should be displayed or full LDAP query Global $sText = " (Computer: %)" ; Text to use for the counts to display. % is replaced with the count Global $iScope = 1 ; Scope for the LDAP search to calculate the count. 1 = Only the OU, 2 = OU + sub-OUs Global $bCount = True ; True = Display the object count right to the OU Global $bDisplay = True ; True = Display objects in the OU as well (selection = $sCategory) Global $iTimerTotal, $iTimerOU, $iTimerGroups, $iTimerTV, $iTimerPerm = 0, $iTimerLoop = 0 Global $iCountSamFQDN = 0, $iCountLoop = 0 Global $oDict = ObjCreate("Scripting.Dictionary") ;------------------------------ ; Make your changes above ;------------------------------ $iTimerTotal = TimerInit() Global $aTreeView = _AD_GetOUTreeView($sOU, $idTree, False, $bCount, $bDisplay, $sCategory, $sText, $iScope, $idProgress) If @error <> 0 Then MsgBox(16, "Active Direcory OU Treeview", "Error creating list of OUs starting with '" & $sOU & "'." & @CRLF & _ "Error returned by function _AD_GetALLOUs: @error = " & @error & ", @extended = " & @extended) Global $sResult = StringFormat("Total: " & "%.2f" & "sec" & @CRLF & _ "Get OUs: " & "%.2f sec" & @CRLF & _ "Get Groups: " & "%.2f sec" & @CRLF & _ "Check Permissions: " & "%.2f sec" & @CRLF & _ " SamToFQDN called: " & "%.0i times" & @CRLF & _ " Time in Loop: " & "%.2f sec" & @CRLF & _ " Count Loop: " & "%.0i times" & @CRLF & _ "Display TreeView: " & "%.2f sec", _ TimerDiff($iTimerTotal) / 1000, $iTimerOU / 1000, $iTimerGroups / 1000, $iTimerPerm / 1000, $iCountSamFQDN, $iTimerLoop / 1000, $iCountLoop, $iTimerTV / 1000) MsgBox(0, "Timers and Counters", $sResult) ; Sleep(1000) GUICtrlDelete($idProgress) While 1 $Msg = GUIGetMsg() Switch $Msg Case $GUI_EVENT_CLOSE, $idExit Exit Case $idExpand _GUICtrlTreeView_Expand($idTree) Case $idCollapse _GUICtrlTreeView_Expand($idTree, 0, False) Case $idSelect $hSelection = _GUICtrlTreeView_GetSelection($idTree) $sSelection = _GUICtrlTreeView_GetText($idTree, $hSelection) For $i = 1 To $aTreeView[0][0] If $hSelection = $aTreeView[$i][2] Then ExitLoop Next $sOU = $aTreeView[$i][1] MsgBox(64, $sTitle & " - Selected OU", "Name: " & $sSelection & @CRLF & "FQDN: " & $sOU) Case $idExport If IsArray($__aTreeView) Then Global $aExcelData[$__aTreeView[0][0]][99] For $i = 1 To $__aTreeView[0][0] $iPos = StringInStr($__aTreeView[$i][0], "#") $aExcelData[$i - 1][$iPos - 1] = StringMid($__aTreeView[$i][0], $iPos + 1) Next $oExcel = _Excel_Open() $oWorkbook = _Excel_BookNew($oExcel) _Excel_RangeWrite($oWorkbook, Default, $aExcelData) _Excel_Close($oExcel) EndIf EndSwitch WEnd ; #FUNCTION# ==================================================================================================================== ; Name...........: _AD_GetOUTreeView ; Description ...: Fills a given TreeView control with all OUs starting with a given OU. ; Syntax.........: _AD_GetOUTreeView($sOU, $idTreeView[, $bIsADOpen = False[, $bCount = False[, $bDisplay = False[, $sCategory = ""[, $sText = " (%)"[, $iSearchScope = 1[, $idProgress = Default]]]]]]]) ; Parameters ....: $sOU - FQDN of the OU where to start. "" displays all OUs ; $idTreeView - Handle of the TreeView where the OUs will be displayed. Has to be created in advance ; $bIsADOpen - Optional: Pass as True if the connection to the AD has already been made by the calling script (default = False) ; $bCount - Optional: True will display the count of objects in the OU right to the OU name (default = False) ; The LDAP query to determine the count is built from $sCategory ; $bDisplay - Optional: True will display the objects in the OU below the OU itself (default = False) ; $sCategory - Optional: Category to search for or the complete LDAP search string e.g. "computer" and "(objectcategory=computer)" are equivalent ; The number of found objects is added to the OUs name (default = "" = don't count objects) ; $sText - Optional: Text to display the count. Must contain a % which will be replaced by the actual number (default = " (%)") ; $iSearchScope - Optional: Search scope for function _AD_GetObjectsInOU: 0 = base, 1 = one-level, 2 = sub-tree (default = 1) ; $idProgress - Optional: ControlID of a progress bar to show during creation of the TreeView (default = Default) ; Return values .: Success - 1 ; Failure - Returns 0 and sets @error: ; |x - Function _AD_Open or _AD_GetAllOUs failed. @error and @extended are set by _AD_Open or _AD_GetAllOUs ; Author ........: water based on code by ReFran - http://www.autoitscript.com/forum/topic/84119-treeview-read-to-from-file ; Modified.......: water including ideas by HaeMHuK ; Remarks .......: Use $iSearchScope = 1 to get the number of objects of a single OU. ; Use $iSearchScope = 2 to get the number of objects in the OU plus all sub-OUs. ; Related .......: ; Link ..........: ; Example .......: ; =============================================================================================================================== Func _AD_GetOUTreeView($sOU, $idTreeView, $bIsADOpen = False, $bCount = False, $bDisplay = False, $sCategory = "", $sText = " (%)", $iSearchScope = 1, $idProgress = Default) Local $iCount, $aObjects If $bIsADOpen = False Then _AD_Open() If @error Then Return SetError(@error, @extended, 0) EndIf $sSeparator = "\" $iTimerOU = TimerInit() Local $aOUs = _AD_GetAllOUs($sOU, $sSeparator) If @error <> 0 Then Return SetError(@error, @extended, 0) _ArrayDisplay($aOUs) ; <== Remove if the Treeview should be generated Return ; <== Remove if the Treeview should be generated $iTimerOU = TimerDiff($iTimerOU) Global $__aTreeView[$aOUs[0][0] + 1][3] = [[$aOUs[0][0], 3]] Local $aResult = $__aTreeView Local $iIndexTV = 0, $sIgnoreOU = "" $iTimerGroups = TimerInit() Local $aMemberOf = _AD_GetUserGroups(@UserName) ; Dummy can be removed $iTimerGroups = TimerDiff($iTimerGroups) For $i = 1 To $aOUs[0][0] If $idProgress <> Default Then GUICtrlSetData($idProgress, $i * 100 / $aOUs[0][0] / 2) ; 50 of the progress by processing the OUs If $sIgnoreOU = "" Or ($sIgnoreOU <> "" And StringInStr($aOUs[$i][1], $sIgnoreOU, -1) = 0) Then ; OU to ignore if not set or OU to ignore is set and entry to check isn't a sub-OU of the ignored OU then check permissions If _AD_HasRequiredRights__GivenMembers($aOUs[$i][1], 0, @UserName, $aMemberOf) = 0 Then ; User doesn't have needed permissions. Ignore this OU and all sub-OUs $sIgnoreOU = $aOUs[$i][1] Else $sIgnoreOU = "" EndIf EndIf If $sIgnoreOU = "" Then $iIndexTV = $iIndexTV + 1 $aTemp = StringSplit($aOUs[$i][0], $sSeparator) $__aTreeView[$iIndexTV][0] = StringFormat("%" & $aTemp[0] - 1 & "s", "") & "#" & $aTemp[$aTemp[0]] $__aTreeView[$iIndexTV][1] = $aOUs[$i][1] EndIf Next ReDim $__aTreeView[$iIndexTV + 1][3] $__aTreeView[0][0] = $iIndexTV $iTimerTV = TimerInit() _GUICtrlTreeView_BeginUpdate($idTreeView) Local $ah[50], $sLDAPString If $sCategory <> "" And StringIsAlNum($sCategory) Then $sLDAPString = "(objectcategory=" & $sCategory & ")" Else $sLDAPString = $sCategory EndIf $iOutIndex = 0 For $iIndex = 1 To $__aTreeView[0][0] If $idProgress <> Default Then GUICtrlSetData($idProgress, 50 + $iIndex * 100 / $__aTreeView[0][0] / 2) ; 50 of the progress by processing the result $iOutIndex += 1 $aObjects = "" $sLine = StringSplit(StringStripCR($__aTreeView[$iIndex][0]), @TAB) $iLevel = StringInStr($sLine[1], "#") If $iLevel = 0 Then ExitLoop If ($bCount Or $bDisplay) And $sLDAPString <> "" Then If $bDisplay Then $aObjects = _AD_GetObjectsInOU($__aTreeView[$iIndex][1], $sLDAPString, 1, "samaccountname,distinguishedname", "", False) If @error Then $iCount = 0 Else $iCount = $aObjects[0][0] EndIf Else $iCount = _AD_GetObjectsInOU($__aTreeView[$iIndex][1], $sLDAPString, $iSearchScope, "samaccountname,distinguishedname", "", True) EndIf EndIf $sTemp = "" If $bCount And $sLDAPString <> "" Then $sTemp = StringReplace($sText, "%", $iCount) If $iLevel = 1 Then $ah[$iLevel] = _GUICtrlTreeView_Add($idTreeView, 0, StringMid($sLine[1], $iLevel + 1) & $sTemp) Else $ah[$iLevel] = _GUICtrlTreeView_AddChild($idTreeView, $ah[$iLevel - 1], StringMid($sLine[1], $iLevel + 1) & $sTemp) EndIf $aResult[$iOutIndex][0] = $__aTreeView[$iIndex][0] $aResult[$iOutIndex][1] = $__aTreeView[$iIndex][1] $aResult[$iOutIndex][2] = $ah[$iLevel] ; Add the objects of the OU to the TreeView If IsArray($aObjects) Then ReDim $aResult[UBound($aResult, 1) + $aObjects[0][0]][UBound($aResult, 2)] For $iIndex2 = 1 To $aObjects[0][0] $iOutIndex += 1 If StringRight($aObjects[$iIndex2][0], 1) = "$" Then $aObjects[$iIndex2][0] = StringLeft($aObjects[$iIndex2][0], StringLen($aObjects[$iIndex2][0]) - 1) $aResult[$iOutIndex][0] = $aObjects[$iIndex2][0] $aResult[$iOutIndex][1] = $aObjects[$iIndex2][1] $aResult[$iOutIndex][2] = _GUICtrlTreeView_AddChild($idTreeView, $ah[$iLevel], $aObjects[$iIndex2][0]) Next EndIf Next If $bIsADOpen = False Then _AD_Close() _GUICtrlTreeView_EndUpdate($idTreeView) $aResult[0][0] = UBound($aResult, 1) - 1 $aResult[0][1] = UBound($aResult, 2) $iTimerTV = TimerDiff($iTimerTV) Return $aResult EndFunc ;==>_AD_GetOUTreeView Func _AD_HasRequiredRights__GivenMembers($sAD_Object, $iAD_Right = 983551, $sAD_User = @UserName, $aAD_MemberOf = "") Local $iPerm = TimerInit() Local $iLoop = TimerInit() If StringMid($sAD_Object, 3, 1) <> "=" Then $sAD_Object = _AD_SamAccountNameToFQDN($sAD_Object) ; sAMAccountName provided Local $aAD_TrusteeArray, $sAD_TrusteeGroup, $sAD_TrusteeArrayFQDN Local $oAD_Object = __AD_ObjGet("LDAP://" & $sAD_HostServer & "/" & $sAD_Object) If IsObj($oAD_Object) Then Local $oAD_Security = $oAD_Object.Get("ntSecurityDescriptor") Local $oAD_DACL = $oAD_Security.DiscretionaryAcl For $oAD_ACE In $oAD_DACL If BitAND($oAD_ACE.AccessMask, $iAD_Right) <> $iAD_Right Then ContinueLoop $aAD_TrusteeArray = StringSplit($oAD_ACE.Trustee, "\") $sAD_TrusteeGroup = "CN=" & $aAD_TrusteeArray[$aAD_TrusteeArray[0]] & "," If $aAD_TrusteeArray[0] = 2 Then If $aAD_TrusteeArray[2] = $sAD_User And BitAND($oAD_ACE.AccessMask, $iAD_Right) = $iAD_Right Then Return 1 ; Check if the entry exists in the Dictionary If $oDict.Exists($aAD_TrusteeArray[2]) Then $sAD_TrusteeArrayFQDN = $oDict.Item($aAD_TrusteeArray[2]) Else $iCountSamFQDN = $iCountSamFQDN + 1 $sAD_TrusteeArrayFQDN = _AD_SamAccountNameToFQDN($aAD_TrusteeArray[2]) $oDict.Add($aAD_TrusteeArray[2], $sAD_TrusteeArrayFQDN) EndIf EndIf $iLoop = TimerInit() For $iCount1 = 0 To UBound($aAD_MemberOf) - 1 $iCountLoop = $iCountLoop + 1 If StringInStr($aAD_MemberOf[$iCount1], $sAD_TrusteeArrayFQDN) Then $iTimerPerm = $iTimerPerm + TimerDiff($iPerm) Return 1 ElseIf StringInStr($aAD_MemberOf[$iCount1], $sAD_TrusteeGroup) Then $iTimerPerm = $iTimerPerm + TimerDiff($iPerm) Return 1 EndIf Next $iTimerLoop = $iTimerLoop + TimerDiff($iLoop) Next EndIf $iTimerPerm = $iTimerPerm + TimerDiff($iPerm) Return 1 ; 1: Test. Change to 0 for production EndFunc ;==>_AD_HasRequiredRights__GivenMembers ; #FUNCTION# ==================================================================================================================== ; Name...........: _AD_GetAllOUs ; Description ...: Retrieves an array of OUs. The paths are separated by the '\' character. ; Syntax.........: _AD_GetAllOUs([$sRoot = ""[, $sSeparator = "\"[, $iSelect = 0[, $iSearchScope = 2]]]]) ; Parameters ....: $sRoot - [optional] OU (FQDN) where to start in the AD tree (default = "", equals "start at the AD root") ; $sSeparator - [optional] Single character to separate the OU names (default = "\") ; $iSelect - [optional] Which objects should be returned in the result (default = 0) ; |0 - Return OUs (Organizational Units) (default) ; |1 - Return CNs (Containers) ; |2 - Return OUs + CNs ; $iSearchScope - [optional] 0 = base, 1 = one-level, 2 = sub-tree (default) ; Return values .: Success - One-based two dimensional array of OUs starting with the given OU. The paths are separated by "\" ; |0 - ... \name of grandfather OU\name of father OU\name of son OU ; |1 - Distinguished Name (FQDN) of the son OU ; Failure - "", sets @error to: ; |1 - No OUs found ; |2 - Specified $sRoot does not exist ; |3 - $iSelect is not an integer or < 0 or > 2 ; Author ........: Jonathan Clelland ; Modified.......: water ; Remarks .......: If an OU contains spaces the sorting is wrong and might lead to problems in further processing. ; Please have a look at http://www.autoitscript.com/forum/topic/106163-active-directory-udf/page__view__findpost__p__943892 ; Related .......: _AD_GetObjectsInOU ; Link ..........: ; Example .......: Yes ; =============================================================================================================================== Func _AD_GetAllOUsEX($sRoot = "", $sSeparator = "\", $iSelect = 0, $iSearchScope = 2) If $sRoot = Default Then $sRoot = "" If $sSeparator = Default Then $sSeparator = "\" If $iSelect = Default Then $iSelect = 0 If $iSearchScope = Default Then $iSearchScope = 2 If $sRoot = "" Then $sRoot = $sAD_DNSDomain Else If _AD_ObjectExists($sRoot, "distinguishedName") = 0 Then Return SetError(2, 0, "") EndIf If Not IsInt($iSelect) Or $iSelect < 0 Or $iSelect > 2 Then Return SetError(3, 0, "") If $sSeparator <= " " Or StringLen($sSeparator) > 1 Then $sSeparator = "\" $__oAD_Command.Properties("Searchscope") = $iSearchScope $__oAD_Command.CommandText = "<LDAP://" & $sAD_HostServer & "/" & $sRoot & ">;" Switch $iSelect Case 0 $__oAD_Command.CommandText = $__oAD_Command.CommandText & "(objectCategory=organizationalUnit);distinguishedName" Case 1 $__oAD_Command.CommandText = $__oAD_Command.CommandText & "(objectCategory=container);distinguishedName" Case 2 $__oAD_Command.CommandText = $__oAD_Command.CommandText & "(|(objectCategory=organizationalUnit)(objectCategory=container));distinguishedName" EndSwitch Local $oRecordSet = $__oAD_Command.Execute Local $iCount1 = $oRecordSet.RecordCount If $iCount1 = 0 Then Return SetError(1, 0, "") Local $aOUs[$iCount1 + 1][2] Local $iCount2 = 1, $aTempOU $oRecordSet.MoveFirst Do $aOUs[$iCount2][1] = $oRecordSet.Fields("distinguishedName").Value $aOUs[$iCount2][0] = "," & StringTrimRight($aOUs[$iCount2][1], StringLen($sAD_DNSDomain) + 1) $aTempOU = StringSplit($aOUs[$iCount2][0], "," & StringLeft($aOUs[$iCount2][1], 3), 1) ; Split at ",OU=" or ",CN=" _ArrayReverseEX($aTempOU) $aOUs[$iCount2][0] = StringTrimRight(_ArrayToString($aTempOU, $sSeparator), 3) $iCount2 += 1 $oRecordSet.MoveNext Until $oRecordSet.EOF _ArraySortEX($aOUs) $aOUs[0][0] = UBound($aOUs, 1) - 1 $aOUs[0][1] = 2 Return $aOUs EndFunc ;==>_AD_GetAllOUsEX ; #FUNCTION# ==================================================================================================================== ; Name...........: _ArraySortEX ; Description ...: Sort a 1D or 2D array on a specific index using the quicksort/insertionsort algorithms. ; Syntax.........: _ArraySortEX(ByRef $avArray[, $iDescending = 0[, $iStart = 0[, $iEnd = 0[, $iSubItem = 0]]]]) ; Parameters ....: $avArray - Array to sort ; $iDescending - [optional] If set to 1, sort descendingly ; $iStart - [optional] Index of array to start sorting at ; $iEnd - [optional] Index of array to stop sorting at ; $iSubItem - [optional] Sub-index to sort on in 2D arrays ; Return values .: Success - 1 ; Failure - 0, sets @error: ; |1 - $avArray is not an array ; |2 - $iStart is greater than $iEnd ; |3 - $iSubItem is greater than subitem count ; |4 - $avArray has too many dimensions ; Author ........: Jos van der Zande <jdeb at autoitscript dot com> ; Modified.......: LazyCoder - added $iSubItem option, Tylo - implemented stable QuickSort algo, Jos van der Zande - changed logic to correctly Sort arrays with mixed Values and Strings, Ultima - major optimization, code cleanup, removed $i_Dim parameter ; Remarks .......: ; Related .......: ; Link ..........: ; Example .......: Yes ; =============================================================================================================================== Func _ArraySortEX(ByRef $avArray, $iDescending = 0, $iStart = 0, $iEnd = 0, $iSubItem = 0) If Not IsArray($avArray) Then Return SetError(1, 0, 0) Local $iUBound = UBound($avArray) - 1 ; Bounds checking If $iEnd < 1 Or $iEnd > $iUBound Then $iEnd = $iUBound If $iStart < 0 Then $iStart = 0 If $iStart > $iEnd Then Return SetError(2, 0, 0) ; Sort Switch UBound($avArray, 0) Case 1 __ArrayQuickSort1DEX($avArray, $iStart, $iEnd) If $iDescending Then _ArrayReverseEX($avArray, $iStart, $iEnd) Case 2 Local $iSubMax = UBound($avArray, 2) - 1 If $iSubItem > $iSubMax Then Return SetError(3, 0, 0) If $iDescending Then $iDescending = -1 Else $iDescending = 1 EndIf __ArrayQuickSort2DEX($avArray, $iDescending, $iStart, $iEnd, $iSubItem, $iSubMax) Case Else Return SetError(4, 0, 0) EndSwitch Return 1 EndFunc ;==>_ArraySortEX ; #INTERNAL_USE_ONLY# =========================================================================================================== ; Name...........: __ArrayQuickSort1DEX ; Description ...: Helper function for sorting 1D arrays ; Syntax.........: __ArrayQuickSort1DEX(ByRef $avArray, ByRef $iStart, ByRef $iEnd) ; Parameters ....: $avArray - Array to sort ; $iStart - Index of array to start sorting at ; $iEnd - Index of array to stop sorting at ; Return values .: None ; Author ........: Jos van der Zande, LazyCoder, Tylo, Ultima ; Modified.......: ; Remarks .......: For Internal Use Only ; Related .......: ; Link ..........: ; Example .......: ; =============================================================================================================================== Func __ArrayQuickSort1DEX(ByRef $avArray, ByRef $iStart, ByRef $iEnd) If $iEnd <= $iStart Then Return Local $vTmp ; InsertionSort (faster for smaller segments) If ($iEnd - $iStart) < 15 Then Local $vCur For $i = $iStart + 1 To $iEnd $vTmp = $avArray[$i] If IsNumber($vTmp) Then For $j = $i - 1 To $iStart Step -1 $vCur = $avArray[$j] ; If $vTmp >= $vCur Then ExitLoop If ($vTmp >= $vCur And IsNumber($vCur)) Or (Not IsNumber($vCur) And StringCompare($vTmp, $vCur) >= 0) Then ExitLoop $avArray[$j + 1] = $vCur Next Else For $j = $i - 1 To $iStart Step -1 If (StringCompare($vTmp, $avArray[$j], 2) >= 0) Then ExitLoop ;<- !Here! $avArray[$j + 1] = $avArray[$j] Next EndIf $avArray[$j + 1] = $vTmp Next Return EndIf ; QuickSort Local $L = $iStart, $R = $iEnd, $vPivot = $avArray[Int(($iStart + $iEnd) / 2)], $fNum = IsNumber($vPivot) Do If $fNum Then ; While $avArray[$L] < $vPivot While ($avArray[$L] < $vPivot And IsNumber($avArray[$L])) Or (Not IsNumber($avArray[$L]) And StringCompare($avArray[$L], $vPivot) < 0) $L += 1 WEnd ; While $avArray[$R] > $vPivot While ($avArray[$R] > $vPivot And IsNumber($avArray[$R])) Or (Not IsNumber($avArray[$R]) And StringCompare($avArray[$R], $vPivot) > 0) $R -= 1 WEnd Else While (StringCompare($avArray[$L], $vPivot) < 0) $L += 1 WEnd While (StringCompare($avArray[$R], $vPivot) > 0) $R -= 1 WEnd EndIf ; Swap If $L <= $R Then $vTmp = $avArray[$L] $avArray[$L] = $avArray[$R] $avArray[$R] = $vTmp $L += 1 $R -= 1 EndIf Until $L > $R __ArrayQuickSort1DEX($avArray, $iStart, $R) __ArrayQuickSort1DEX($avArray, $L, $iEnd) EndFunc ;==>__ArrayQuickSort1DEX ; #INTERNAL_USE_ONLY# =========================================================================================================== ; Name...........: __ArrayQuickSort2DEX ; Description ...: Helper function for sorting 2D arrays ; Syntax.........: __ArrayQuickSort2DEX(ByRef $avArray, ByRef $iStep, ByRef $iStart, ByRef $iEnd, ByRef $iSubItem, ByRef $iSubMax) ; Parameters ....: $avArray - Array to sort ; $iStep - Step size (should be 1 to sort ascending, -1 to sort descending!) ; $iStart - Index of array to start sorting at ; $iEnd - Index of array to stop sorting at ; $iSubItem - Sub-index to sort on in 2D arrays ; $iSubMax - Maximum sub-index that array has ; Return values .: None ; Author ........: Jos van der Zande, LazyCoder, Tylo, Ultima ; Modified.......: ; Remarks .......: For Internal Use Only ; Related .......: ; Link ..........: ; Example .......: ; =============================================================================================================================== Func __ArrayQuickSort2DEX(ByRef $avArray, ByRef $iStep, ByRef $iStart, ByRef $iEnd, ByRef $iSubItem, ByRef $iSubMax) If $iEnd <= $iStart Then Return ; QuickSort Local $vTmp, $L = $iStart, $R = $iEnd, $vPivot = $avArray[Int(($iStart + $iEnd) / 2)][$iSubItem], $fNum = IsNumber($vPivot) Do If $fNum Then ; While $avArray[$L][$iSubItem] < $vPivot While ($iStep * ($avArray[$L][$iSubItem] - $vPivot) < 0 And IsNumber($avArray[$L][$iSubItem])) Or (Not IsNumber($avArray[$L][$iSubItem]) And $iStep * StringCompare($avArray[$L][$iSubItem], $vPivot) < 0) $L += 1 WEnd ; While $avArray[$R][$iSubItem] > $vPivot While ($iStep * ($avArray[$R][$iSubItem] - $vPivot) > 0 And IsNumber($avArray[$R][$iSubItem])) Or (Not IsNumber($avArray[$R][$iSubItem]) And $iStep * StringCompare($avArray[$R][$iSubItem], $vPivot) > 0) $R -= 1 WEnd Else While ($iStep * StringCompare($avArray[$L][$iSubItem], $vPivot) < 0) $L += 1 WEnd While ($iStep * StringCompare($avArray[$R][$iSubItem], $vPivot) > 0) $R -= 1 WEnd EndIf ; Swap If $L <= $R Then For $i = 0 To $iSubMax $vTmp = $avArray[$L][$i] $avArray[$L][$i] = $avArray[$R][$i] $avArray[$R][$i] = $vTmp Next $L += 1 $R -= 1 EndIf Until $L > $R __ArrayQuickSort2DEX($avArray, $iStep, $iStart, $R, $iSubItem, $iSubMax) __ArrayQuickSort2DEX($avArray, $iStep, $L, $iEnd, $iSubItem, $iSubMax) EndFunc ;==>__ArrayQuickSort2DEX ; #FUNCTION# ==================================================================================================================== ; Name...........: _ArrayReverseEX ; Description ...: Takes the given array and reverses the order in which the elements appear in the array. ; Syntax.........: _ArrayReverseEX(ByRef $avArray[, $iStart = 0[, $iEnd = 0]]) ; Parameters ....: $avArray - Array to modify ; $iStart - [optional] Index of array to start modifying at ; $iEnd - [optional] Index of array to stop modifying at ; Return values .: Success - 1 ; Failure - 0, sets @error: ; |1 - $avArray is not an array ; |2 - $iStart is greater than $iEnd ; |3 - $avArray is not a 1 dimensional array ; Author ........: Brian Keene ; Modified.......: Jos van der Zande <jdeb at autoitscript dot com> - added $iStart parameter and logic, Tylo - added $iEnd parameter and rewrote it for speed, Ultima - code cleanup, minor optimization ; Remarks .......: ; Related .......: _ArraySwap ; Link ..........: ; Example .......: Yes ; =============================================================================================================================== Func _ArrayReverseEX(ByRef $avArray, $iStart = 0, $iEnd = 0) If Not IsArray($avArray) Then Return SetError(1, 0, 0) If UBound($avArray, 0) <> 1 Then Return SetError(3, 0, 0) Local $vTmp, $iUBound = UBound($avArray) - 1 ; Bounds checking If $iEnd < 1 Or $iEnd > $iUBound Then $iEnd = $iUBound If $iStart < 0 Then $iStart = 0 If $iStart > $iEnd Then Return SetError(2, 0, 0) ; Reverse For $i = $iStart To Int(($iStart + $iEnd - 1) / 2) $vTmp = $avArray[$i] $avArray[$i] = $avArray[$iEnd] $avArray[$iEnd] = $vTmp $iEnd -= 1 Next Return 1 EndFunc ;==>_ArrayReverseEX 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...
mprudhomme Posted September 15, 2020 Share Posted September 15, 2020 Thank you for your reply, but unfortunately I cannot solve my problem :-(. I admit that I have trouble understanding the modifications that must be made and in particular the use of "_AD_Example_GetOUTreeView" and "_AD_GetOUTreeView" which lose me because I do not use them in my program. However, I copied your modifications so as not to use "_ArraySort" but rather "_ArraySortEX" and I have the same result. My problem is indeed with the _ArraySort in the _AD_GetAllOUs function of the AD.au3 file. In my code I run the command below to recreate a Treeview from my AD. _AD_GetAllOUs ('OU = Computers, OU = distinguishedName ..., "\") Below are different captures. The one without the _ArraySort is correct except that it is not sorted alphabetically like in the AD tree. Do you have any additional solution to help me or it is a problem on my end that I cannot understand the use of your changes? Thanks again for your help Link to comment Share on other sites More sharing options...
water Posted September 15, 2020 Author Share Posted September 15, 2020 I will need to do some testing. As I do not have OUs with dashes or spaces in our AD (and as I'm just an ordinary user which can't modify our AD) I need to create the array by hand. Then I will try to find out what I did wrong when implementing the solution by trancexx or which change in the Array UDF since then makes her solution work no longer 🤔 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 September 20, 2020 Author Share Posted September 20, 2020 I had a look at the function and did some tests. I then realized that the whole sorting thing isn't working. I need to rewrite the function so it uses a multicolumn sort algorithm. Please stay tuned but don't hold your breath 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...
mprudhomme Posted September 21, 2020 Share Posted September 21, 2020 Thanks for your research, I stay tuned while breathing behind my mask 😉 Link to comment Share on other sites More sharing options...
water Posted September 21, 2020 Author Share Posted September 21, 2020 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 October 1, 2020 Author Share Posted October 1, 2020 The following (first version) of a function pads the subitems of a cell to a specified length so sorting returns the correct order. Could you please run the example script (if you like you can add more of your data entries) and check if you get the desired result? expandcollapse popup#include <Array.au3> #include <debug.au3> ;----- Test Data Local $aOUs[14][2] $aOUs[1][0] = "01300_TEST\Ordinateurs" $aOUs[1][1] = "OU=01300_TEST,OU=Ordinateurs,DC=company,DC=COM" $aOUs[2][0] = "01300_TEST\Ordinateurs\Administratif" $aOUs[2][1] = "OU=01300_TEST,OU=Ordinateurs,OU=Administratif,DC=company,DC=COM" $aOUs[3][0] = "01300_TEST\Ordinateurs\Pedagogique" $aOUs[3][1] = "OU=01300_TEST,OU=Ordinateurs,OU=Pedagogique,DC=company,DC=COM" $aOUs[4][0] = "01300_TEST\Ordinateurs\Pedagogique\Bat_A" $aOUs[4][1] = "OU=01300_TEST,OU=Ordinateurs,OU=Pedagogique,DC=Bat_A,DC=company,DC=COM" $aOUs[5][0] = "01300_TEST\Ordinateurs\Pedagogique\Bat_A\ET_-2" $aOUs[5][1] = "OU=01300_TEST,OU=Ordinateurs,OU=Pedagogique,DC=Bat_A,DC=ET_-2,DC=company,DC=COM" $aOUs[6][0] = "01300_TEST\Ordinateurs\Pedagogique\Bat_A\ET_-2\Salle_02moins" $aOUs[6][1] = "OU=01300_TEST,OU=Ordinateurs,OU=Pedagogique,DC=Bat_A,DC=ET_-2,DC=Salle_02moins,DC=company,DC=COM" $aOUs[7][0] = "01300_TEST\Ordinateurs\Pedagogique\Bat_A\ET_1" $aOUs[7][1] = "OU=01300_TEST,OU=Ordinateurs,OU=Pedagogique,DC=Bat_A,DC=ET_1,DC=company,DC=COM" $aOUs[8][0] = "01300_TEST\Ordinateurs\Pedagogique\Bat_A\ET_1\Salle_01" $aOUs[8][1] = "OU=01300_TEST,OU=Ordinateurs,OU=Pedagogique,DC=Bat_A,DC=ET_1,DC=Salle_01,DC=company,DC=COM" $aOUs[9][0] = "01300_TEST\Ordinateurs\Pedagogique\Bat_A\ET_1\Salle_02" $aOUs[9][1] = "OU=01300_TEST,OU=Ordinateurs,OU=Pedagogique,DC=Bat_A,DC=ET_1,DC=Salle_02,DC=company,DC=COM" $aOUs[10][0] = "01300_TEST\Ordinateurs\Pedagogique 2019" $aOUs[10][1] = "OU=01300_TEST,OU=Ordinateurs,OU=Pedagogique 2019,DC=company,DC=COM" $aOUs[11][0] = "01300_TEST\Ordinateurs\Pedagogique 2019\Bat_B" $aOUs[11][1] = "OU=01300_TEST,OU=Ordinateurs,OU=Pedagogique 2019,DC=Bat_B,DC=company,DC=COM" $aOUs[12][0] = "01300_TEST\Ordinateurs\Pedagogique 2019\Bat_B\ET_2" $aOUs[12][1] = "OU=01300_TEST,OU=Ordinateurs,OU=Pedagogique 2019,DC=Bat_B,DC=ET_2,DC=company,DC=COM" $aOUs[13][0] = "01300_TEST\Ordinateurs\Pedagogique 2019\Bat_B\ET_2\Salle_20" $aOUs[13][1] = "OU=01300_TEST,OU=Ordinateurs,OU=Pedagogique 2019,DC=Bat_B,DC=ET_2,DC=Salle_20,DC=company,DC=COM" ;----- _ExtendCells($aOUs) _ArraySort($aOUs, 0, 0, 0, 0) _DebugArrayDisplay($aOUs) Exit Func _ExtendCells(ByRef $aArray, $iStartRow = 0, $iColumn = 0, $sSeparator = "\", $iLength = 50) Local $aTemp, $sTemp, $iSubtract = 0, $sPadString = StringFormat("%" & $iLength & "s", " ") ; Pad the substrings of the cells of the specified column to the specified length If UBound($aArray, 0) = 1 Then ; 1D array ; Insert code for a 1D array here Else If $iStartRow = 0 Then $iSubtract = 1 For $i = $iStartRow To UBound($aArray, 1) - $iSubtract $aTemp = StringSplit($aArray[$i][$iColumn], $sSeparator) If @error = 0 Then For $j = 1 To UBound($aTemp, 1) - 1 $sTemp = StringLeft($aTemp[$j] & $sPadString, $iLength) $aArray[$i][$iColumn] = ($j > 1) ? ($aArray[$i][$iColumn] & $sSeparator & $sTemp) : ($sTemp) Next EndIf Next EndIf ; Sort the array on the padded column _ArraySort($aArray, 0, $iStartRow, 0, $iColumn) ; Remove the padding characters If UBound($aArray, 0) = 1 Then ; 1D array ; Insert code for a 1D array here Else If $iStartRow = 0 Then $iSubtract = 1 For $i = $iStartRow To UBound($aArray, 1) - $iSubtract While 1 $aArray[$i][$iColumn] = StringReplace($aArray[$i][$iColumn], " " & $sSeparator, $sSeparator) If @extended = 0 Then ExitLoop WEnd Next EndIf EndFunc ;==>_ExtendCells 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 October 3, 2020 Author Share Posted October 3, 2020 Second version (fixing some problems with first version): expandcollapse popup#Region ;**** Directives created by AutoIt3Wrapper_GUI **** #AutoIt3Wrapper_AU3Check_Parameters=-d -w 1 -w 2 -w 3 -w 4 -w 5 -w 6 -w 7 -w 8 #EndRegion ;**** Directives created by AutoIt3Wrapper_GUI **** #include <Array.au3> #include <debug.au3> ;----- Test Data Global $aOUs[16][2] = [[15, 2]] $aOUs[01][0] = "01300_TEST\Ordinateurs" $aOUs[02][0] = "01300_TEST\Ordinateurs\Administratif" $aOUs[03][0] = "01300_TEST\Ordinateurs\Pedagogique" $aOUs[04][0] = "01300_TEST\Ordinateurs\Pedagogique\Bat A" $aOUs[05][0] = "01300_TEST\Ordinateurs\Pedagogique\Bat A\ET_-2" $aOUs[06][0] = "01300_TEST\Ordinateurs\Pedagogique\Bat A\ET_-2\Salle_02moins" $aOUs[07][0] = "01300_TEST\Ordinateurs\Pedagogique\Bat A\ET_1" $aOUs[08][0] = "01300_TEST\Ordinateurs\Pedagogique\Bat A\ET_1\Salle_01" $aOUs[09][0] = "01300_TEST\Ordinateurs\Pedagogique\Bat A\ET_1\Salle_02" $aOUs[10][0] = "01300_TEST\Ordinateurs\Pedagogique 2019" $aOUs[11][0] = "01300_TEST\Ordinateurs\Pedagogique 2019\Bat_B" $aOUs[12][0] = "01300_TEST\Ordinateurs\Pedagogique 2019\Bat_B\ET_2" $aOUs[13][0] = "01300_TEST\Ordinateurs\Pedagogique 2019\Bat_B\ET_2\Salle_20" $aOUs[14][0] = "01300_TEST\Ordinateurs\Pedagogique\Bat A\ET_-1" $aOUs[15][0] = "01300_TEST\Ordinateurs\Pedagogique\Bat A\ET_-1\Salle_10" ;----- _ExtendCells($aOUs, 1) Exit Func _ExtendCells(ByRef $aArray, $iStartRow = 0, $iColumn = 0, $sUsedSeparator = "\", $sSortSeparator = "|", $sPaddingCharacter = " ", $iLength = 50) Local $aTemp, $sTemp, $sPadString = StringFormat("%" & $iLength & "s", $sPaddingCharacter) ; Pad the substrings of the cells of the specified column to the specified length If UBound($aArray, 0) = 1 Then ; 1D array ; Insert code for a 1D array here Else For $i = $iStartRow To UBound($aArray, 1) - 1 $aArray[$i][$iColumn] = Stringreplace($aArray[$i][$iColumn], $sUsedSeparator, $sSortSeparator) $aTemp = StringSplit($aArray[$i][$iColumn], $sSortSeparator, $STR_NOCOUNT) If @error = 0 Then For $j = 0 To UBound($aTemp, 1) - 1 $sTemp = StringLeft($aTemp[$j] & $sPadString, $iLength - 1) $aArray[$i][$iColumn] = ($j = 0) ? ($sTemp & $sSortSeparator) : ($aArray[$i][$iColumn] & $sTemp & $sSortSeparator) Next EndIf Next EndIf ; Sort the array on the padded column _DebugArrayDisplay($aOUs, "Before sorting") _ArraySort($aArray, 0, $iStartRow, 0, $iColumn) _DebugArrayDisplay($aOUs, "After sorting") ; Remove the padding characters If UBound($aArray, 0) = 1 Then ; 1D array ; Insert code for a 1D array here Else For $i = $iStartRow To UBound($aArray, 1) - 1 If StringRight($aArray[$i][$iColumn], 1) = $sSortSeparator Then $aArray[$i][$iColumn] = StringTrimRight($aArray[$i][$iColumn], 1) ; Remove rightmost separator character $aArray[$i][$iColumn] = StringReplace($aArray[$i][$iColumn], $sPaddingCharacter & $sSortSeparator, $sUsedSeparator) While 1 $aArray[$i][$iColumn] = StringReplace($aArray[$i][$iColumn], $sPaddingCharacter & $sUsedSeparator, $sUsedSeparator) If @extended = 0 Then ExitLoop WEnd Next EndIf _DebugArrayDisplay($aOUs, "After sorting and removing padding characters") EndFunc ;==>_ExtendCells What do you think? Does it work for you? 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...
mprudhomme Posted October 9, 2020 Share Posted October 9, 2020 Hi, First of all thank you for researching this problem and sorry for the delay in responding. I encountered problems with the first version but the second seems to work perfectly! To make sure I didn't make any mistakes, here's what I did to integrate the changes into my project: - In my au3 file I added <Degug.au3> - In the AD.au3 file - In the "Func _AD_GetAllOUs" function I replaced "ArraySort ($aOUs)" by "_ExtendCells ($aOUs, 1)" - In this same file I copied the function "_ExtendCells" - In this same file I had to declare the variable $aOUs (global $aOUs) otherwise I have a use message before declaration Are the changes I made correct or do I have to do it differently? Really a HUGE thank you for fixing this problem. Marcel Link to comment Share on other sites More sharing options...
water Posted October 10, 2020 Author Share Posted October 10, 2020 (edited) Looks good! I will add the modification to the AD UDF and hope to release a new version (1.5.2.1) quite soon. Edit: - In my au3 file I added <Degug.au3> No longer needed with the latest version of the UDF - In the AD.au3 file - In the "Func _AD_GetAllOUs" function I replaced "ArraySort ($aOUs)" by "_ExtendCells ($aOUs, 1)" No longer needed with the latest version of the UDF - In this same file I copied the function "_ExtendCells" No longer needed with the latest version of the UDF - In this same file I had to declare the variable $aOUs (global $aOUs) otherwise I have a use message before declaration. No longer needed with the latest version of the UDF Edited October 10, 2020 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...
mprudhomme Posted October 12, 2020 Share Posted October 12, 2020 It works well, everything is perfect with version 1.5.2.1. Thank you again for your help and your responsiveness, it's great 🙂. Link to comment Share on other sites More sharing options...
water Posted October 12, 2020 Author Share Posted October 12, 2020 Thanks a lot for your feedback Glad you like the UDF and the support 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...
fuse59650 Posted January 26, 2021 Share Posted January 26, 2021 Hello, great library and work very well ! With the function _AD_GetAllOUs I have strange backslash at the end of line on some OU : ULilleRessources\DSI\DSISHS\Pont_de_Bois\Pedagogie\TICE\DEDIEES\Angellier OU=Angellier,OU=DEDIEES,OU=TICE,OU=Pedagogie,OU=Pont_de_Bois,OU=DSISHS,OU=DSI,OU=ULilleRessources,DC=ad,DC=univ-lille,DC=fr ULilleRessources\DSI\DSISHS\Pont_de_Bois\Pedagogie\TICE\DEDIEES\Angellier\B1619(tbi)\ OU=B1619(tbi),OU=Angellier,OU=DEDIEES,OU=TICE,OU=Pedagogie,OU=Pont_de_Bois,OU=DSISHS,OU=DSI,OU=ULilleRessources,DC=ad,DC=univ-lille,DC=fr ULilleRessources\DSI\DSISHS\Pont_de_Bois\Pedagogie\TICE\DEDIEES\ArtsCulture OU=ArtsCulture,OU=DEDIEES,OU=TICE,OU=Pedagogie,OU=Pont_de_Bois,OU=DSISHS,OU=DSI,OU=ULilleRessources,DC=ad,DC=univ-lille,DC=fr ULilleRessources\DSI\DSISHS\Pont_de_Bois\Pedagogie\TICE\DEDIEES\ArtsCulture\B2451\ OU=B2451,OU=ArtsCulture,OU=DEDIEES,OU=TICE,OU=Pedagogie,OU=Pont_de_Bois,OU=DSISHS,OU=DSI,OU=ULilleRessources,DC=ad,DC=univ-lille,DC=fr ULilleRessources\DSI\DSISHS\Pont_de_Bois\Pedagogie\TICE\DEDIEES\CIREL OU=CIREL,OU=DEDIEES,OU=TICE,OU=Pedagogie,OU=Pont_de_Bois,OU=DSISHS,OU=DSI,OU=ULilleRessources,DC=ad,DC=univ-lille,DC=fr ULilleRessources\DSI\DSISHS\Pont_de_Bois\Pedagogie\TICE\DEDIEES\CIREL\B3328\ OU=B3328,OU=CIREL,OU=DEDIEES,OU=TICE,OU=Pedagogie,OU=Pont_de_Bois,OU=DSISHS,OU=DSI,OU=ULilleRessources,DC=ad,DC=univ-lille,DC=fr ULilleRessources\DSI\DSISHS\Pont_de_Bois\Pedagogie\TICE\DEDIEES\CIREL\B3332\ OU=B3332,OU=CIREL,OU=DEDIEES,OU=TICE,OU=Pedagogie,OU=Pont_de_Bois,OU=DSISHS,OU=DSI,OU=ULilleRessources,DC=ad,DC=univ-lille,DC=fr I remove them in my code but it's normal ? Link to comment Share on other sites More sharing options...
water Posted January 26, 2021 Author Share Posted January 26, 2021 How do you call _AD_GetAllOUs (which parameters do you pass)? 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...
fuse59650 Posted January 27, 2021 Share Posted January 27, 2021 Hello, I call it with Local $root_ou = "" _AD_GetAllOUs($root_ou) or Local $root_ou = "OU=Pedagogie,OU=Pont_de_Bois,OU=DSISHS,OU=DSI,OU=ULilleRessources,DC=ad,DC=univ-lille,DC=fr" _AD_GetAllOUs($root_ou) I have the same result with backslash on certain OU Maybe is the start of parenthesis ? OU=B1619(tbi),OU=Angellier,OU=DEDIEES,OU=TICE,OU=Pedagogie,OU=Pont_de_Bois,OU=DSISHS,OU=DSI,OU=ULilleRessources,DC=ad,DC=univ-lille,DC=fr Link to comment Share on other sites More sharing options...
water Posted January 27, 2021 Author Share Posted January 27, 2021 Good point! I will do some checks and come back later 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...
fuse59650 Posted January 27, 2021 Share Posted January 27, 2021 I have notice other strange thing with version 1.5.2.1 (before I use the 1.4.14.0) for the first column of array : - I have to remove extra space otherwise Stringlen function return incorrect number of character - when I use _ArraySearch function I must set the $iCompare parameter to 1 otherwise the function found nothing That's all for the moment. 😅 Thank you again and good luck. 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