Jump to content
Sign in to follow this  
water

Active Directory UDF - Help & Support (II)

Recommended Posts

@minimen456

This is because every UDF tries to register it's own error handler. But there can be only one error handler at a time. AD registers the COM error handler when _AD_Open is called.

If possible run _AD_Open, do all the AD related stuff, then use _AD_Close. Now you shouldn't see any further error messages by the IE UDF.

You're suggesting that I run _AD_Open, do all the AD related stuff, then use _AD_Close. But I'm pretty sure that I tested that and there was no _AD_Open or any AD UDF function in my script. Just

#include <AD.au3>

for the test. And IE UDF stops working properly

Edited by minimen456

Share this post


Link to post
Share on other sites

The AD UDF only creates a few variables and constants when included. Everything else is packed into functions.

Which version of the UDF do you run?

Edited by water

My UDFs and Tutorials:

Spoiler

UDFs:
Active Directory (NEW 2019-10-24 - Version 1.4.14.0) - Download - General Help & Support - Example Scripts - Wiki
OutlookEX (NEW 2019-11-30 - Version 1.4.0.0) - Download - General Help & Support - Example Scripts - Wiki
Outlook Tools (2019-07-22 - Version 0.6.0.0) - Download - General Help & Support - Wiki
ExcelChart (2017-07-21 - Version 0.4.0.1) - Download - General Help & Support - Example Scripts
PowerPoint (2017-06-06 - Version 0.0.5.0) - Download - General Help & Support
Excel - Example Scripts - Wiki
Word - Wiki
Task Scheduler (NEW 2019-12-03 - Version 1.5.1.0) - Download - General Help & Support - Wiki

Tutorials:
ADO - Wiki

 

Share this post


Link to post
Share on other sites

Glad the problem could be solved this way ;)


My UDFs and Tutorials:

Spoiler

UDFs:
Active Directory (NEW 2019-10-24 - Version 1.4.14.0) - Download - General Help & Support - Example Scripts - Wiki
OutlookEX (NEW 2019-11-30 - Version 1.4.0.0) - Download - General Help & Support - Example Scripts - Wiki
Outlook Tools (2019-07-22 - Version 0.6.0.0) - Download - General Help & Support - Wiki
ExcelChart (2017-07-21 - Version 0.4.0.1) - Download - General Help & Support - Example Scripts
PowerPoint (2017-06-06 - Version 0.0.5.0) - Download - General Help & Support
Excel - Example Scripts - Wiki
Word - Wiki
Task Scheduler (NEW 2019-12-03 - Version 1.5.1.0) - Download - General Help & Support - Wiki

Tutorials:
ADO - Wiki

 

Share this post


Link to post
Share on other sites

Func _ISObjectDisabled()
_AD_Open()
; Do processing with logged on user permissions
$DisabledResult = _AD_GetObjectAttribute($rIsDisabled & "$", "distinguishedname")
$rIsDisabled = GUICtrlRead($IsDisabled)
If _AD_IsObjectDisabled($DisabledResult) = @error Then

If _AD_IsObjectDisabled($DisabledResult) Then
MsgBox(64, "Active Directory Domain Services", "Computer account '" & $rIsDisabled & "' is disabled!")
Else
MsgBox(64, "Active Directory Domain Services", "Computer account '" & $rIsDisabled & "' is not disabled!")
EndIf
Else
MsgBox(64, "Active Directory Domain Services", "Computer account '" & $rIsDisabled & "' doesn't exist")
EndIf
_AD_Close()
EndFunc ;==>_ISObjectDisabled

Hi Water

Hopefully you can help me out?

When checking if a computer is disabled or not in AD I get the same results if the computer is disabled or it doesn't exist i.e the return I get is it doesn't exist even if it does exist but is disabled.

Results are correct if its not disabled.

$IsDisabled is the computer computer name.

Edited by Iceman682

Share this post


Link to post
Share on other sites

Shouldn't you first get the input from the GUI and then call the AD function?

$rIsDisabled = GUICtrlRead($IsDisabled)
$DisabledResult = _AD_GetObjectAttribute($rIsDisabled & "$", "distinguishedname")
Edited by water

My UDFs and Tutorials:

Spoiler

UDFs:
Active Directory (NEW 2019-10-24 - Version 1.4.14.0) - Download - General Help & Support - Example Scripts - Wiki
OutlookEX (NEW 2019-11-30 - Version 1.4.0.0) - Download - General Help & Support - Example Scripts - Wiki
Outlook Tools (2019-07-22 - Version 0.6.0.0) - Download - General Help & Support - Wiki
ExcelChart (2017-07-21 - Version 0.4.0.1) - Download - General Help & Support - Example Scripts
PowerPoint (2017-06-06 - Version 0.0.5.0) - Download - General Help & Support
Excel - Example Scripts - Wiki
Word - Wiki
Task Scheduler (NEW 2019-12-03 - Version 1.5.1.0) - Download - General Help & Support - Wiki

Tutorials:
ADO - Wiki

 

Share this post


Link to post
Share on other sites

I don't believe I had them the wrong way around. :wacko:

Even though, it still indicates it doesn't exist when its disabled

Func _ISObjectDisabled()
_AD_Open(); Do processing with logged on user permissions
$rIsDisabled = GUICtrlRead($IsDisabled)
$DisabledResult = _AD_GetObjectAttribute($rIsDisabled & "$", "distinguishedname")
If _AD_IsObjectDisabled($DisabledResult) = @error Then
If _AD_IsObjectDisabled($DisabledResult) Then
MsgBox(64, "Active Directory Domain Services", "Computer account '" & $rIsDisabled & "' is disabled!")
Else
MsgBox(64, "Active Directory Domain Services", "Computer account '" & $rIsDisabled & "' is not disabled!")
EndIf
Else
MsgBox(64, "Active Directory Domain Services", "Computer account '" & $rIsDisabled & "' doesn't exist!")
EndIf
_AD_Close()
EndFunc ;==>_ISObjectDisabled
Edited by Iceman682

Share this post


Link to post
Share on other sites

This should work. I changed the variable names to the scheme used by UDFs:

Func _ISObjectDisabled()
    _AD_Open(); Do processing with logged on user permissions
    $sComputer = GUICtrlRead($hComputer) & "$" ; Was: $IsDisabled
    $sFQDN = _AD_GetObjectAttribute($sComputer, "distinguishedname")
    $iDisabled = _AD_IsObjectDisabled($sFQDN)
    If @error Then
        MsgBox(16, "Active Directory Domain Services", "Computer account '" & $sComputer & "' doesn't exist!")
    ElseIf $iDisabled = 0 Then
        MsgBox(64, "Active Directory Domain Services", "Computer account '" & $sComputer & "' is not disabled!")
    Else
        MsgBox(64, "Active Directory Domain Services", "Computer account '" & $sComputer & "' is disabled!")
    EndIf
    _AD_Close()
EndFunc   ;==>_ISObjectDisabled

My UDFs and Tutorials:

Spoiler

UDFs:
Active Directory (NEW 2019-10-24 - Version 1.4.14.0) - Download - General Help & Support - Example Scripts - Wiki
OutlookEX (NEW 2019-11-30 - Version 1.4.0.0) - Download - General Help & Support - Example Scripts - Wiki
Outlook Tools (2019-07-22 - Version 0.6.0.0) - Download - General Help & Support - Wiki
ExcelChart (2017-07-21 - Version 0.4.0.1) - Download - General Help & Support - Example Scripts
PowerPoint (2017-06-06 - Version 0.0.5.0) - Download - General Help & Support
Excel - Example Scripts - Wiki
Word - Wiki
Task Scheduler (NEW 2019-12-03 - Version 1.5.1.0) - Download - General Help & Support - Wiki

Tutorials:
ADO - Wiki

 

Share this post


Link to post
Share on other sites
:D

My UDFs and Tutorials:

Spoiler

UDFs:
Active Directory (NEW 2019-10-24 - Version 1.4.14.0) - Download - General Help & Support - Example Scripts - Wiki
OutlookEX (NEW 2019-11-30 - Version 1.4.0.0) - Download - General Help & Support - Example Scripts - Wiki
Outlook Tools (2019-07-22 - Version 0.6.0.0) - Download - General Help & Support - Wiki
ExcelChart (2017-07-21 - Version 0.4.0.1) - Download - General Help & Support - Example Scripts
PowerPoint (2017-06-06 - Version 0.0.5.0) - Download - General Help & Support
Excel - Example Scripts - Wiki
Word - Wiki
Task Scheduler (NEW 2019-12-03 - Version 1.5.1.0) - Download - General Help & Support - Wiki

Tutorials:
ADO - Wiki

 

Share this post


Link to post
Share on other sites

Hi Water.

Now that we've got _AD_HasRequiredRights mostly fixed (I think), I'm needing some help with the script I initially wanted to code.

Basically I am using your _AD_Example_GetOUTreeView as a starting point. What I'd like to do is to modify it so that it checks the permissions for the given user account on the top level OU only (to save time; in my organization you basically have all or nothing), and then populate the tree view with those OUs and their sub-OUs. The main problem is that I honestly can't tell where those are getting added to the tree view in the first place. I have no experience with tree views or multidimensional arrays, so it's a little difficult to follow your script in some places. Can you help out with this when you have some time?

I also made another modification to _AD_HasRequiredRights. In fact I copied it and modified it to make _AD_HasRequiredRights__GivenMembers. I made this because it allows me to supply the groups the user is a member of, so that it doesn't check for that every time I ask for the permissions of the object. It cut down the time it takes to run the script on every OU drastically, but I doubt others will need it.

Share this post


Link to post
Share on other sites

This line retrieves the list of all OUs

Local $aAD_OUs = _AD_GetAllOUs($sAD_OU, $sSeparator)
Here a temporary array is filled with the OUs
For $i = 1 To $aAD_OUs[0][0]
$aAD_Temp = StringSplit($aAD_OUs[$i][0], $sSeparator)
$aAD_TreeView[$i][0] = StringFormat("%" & $aAD_Temp[0] - 1 & "s", "") & "#" & $aAD_Temp[$aAD_Temp[0]]
$aAD_TreeView[$i][1] = $aAD_OUs[$i][1]
Next
I think it would be best to not write the entries with the wrong permissions to this array. This means: If a user isn't allowed to access an OU drop all entries that start with this string.

Can't test at the moment. Maybe tomorrow.


My UDFs and Tutorials:

Spoiler

UDFs:
Active Directory (NEW 2019-10-24 - Version 1.4.14.0) - Download - General Help & Support - Example Scripts - Wiki
OutlookEX (NEW 2019-11-30 - Version 1.4.0.0) - Download - General Help & Support - Example Scripts - Wiki
Outlook Tools (2019-07-22 - Version 0.6.0.0) - Download - General Help & Support - Wiki
ExcelChart (2017-07-21 - Version 0.4.0.1) - Download - General Help & Support - Example Scripts
PowerPoint (2017-06-06 - Version 0.0.5.0) - Download - General Help & Support
Excel - Example Scripts - Wiki
Word - Wiki
Task Scheduler (NEW 2019-12-03 - Version 1.5.1.0) - Download - General Help & Support - Wiki

Tutorials:
ADO - Wiki

 

Share this post


Link to post
Share on other sites

Thanks for the suggestion, Water. I've tried this just to see if it works, but the tree view comes up completely blank.

Local $aAD_TreeView[$aAD_OUs[0][0] + 1][3] = [[$aAD_OUs[0][0], 3]]
Local $aAD_Result = $aAD_TreeView
$aAD_MemberOf = _AD_GetUserGroups(@UserName, 1)
For $i = 1 To $aAD_OUs[0][0]
   $aAD_TopLevelOU = StringSplit($aAD_OUs[$i][1],"OU=",1)
   ;check to see if it's a top level OU
   If $aAD_TopLevelOU[0] = 2 Then
      If _AD_HasRequiredRights__GivenMembers($aAD_OUs[$i][1],983551,@UserName,$aAD_MemberOf) Then
         _ArrayAdd($aAD_TopOUPermissions,$aAD_OUs[$i][1])
         $aAD_Temp = StringSplit($aAD_OUs[$i][0], $sSeparator)
         $aAD_TreeView[$i][0] = StringFormat("%" & $aAD_Temp[0] - 1 & "s", "") & "#" & $aAD_Temp[$aAD_Temp[0]]
         $aAD_TreeView[$i][1] = $aAD_OUs[$i][1]
         MsgBox(0,"",$aAD_OUs[$i][1])
      EndIf
   ;if it's not a top level OU...
   ElseIf $aAD_TopLevelOU[0] > 2 Then
      For $t = 1 To UBound($aAD_TopOUPermissions) - 1
         If StringInStr($aAD_OUs[$i][1],$aAD_TopOUPermissions[$t]) Then
            $aAD_Temp = StringSplit($aAD_OUs[$i][0], $sSeparator)
            $aAD_TreeView[$i][0] = StringFormat("%" & $aAD_Temp[0] - 1 & "s", "") & "#" & $aAD_Temp[$aAD_Temp[0]]
            $aAD_TreeView[$i][1] = $aAD_OUs[$i][1]
            MsgBox(0,"",$aAD_OUs[$i][1])
         EndIf
      Next
   EndIf
Next

It gets through the entire code; all the if statements and everything. The MsgBox in each if statement after the top level OU check returns the correct values. But the tree comes up empty. Any suggestions?

Edited by chaoticyeshua

Share this post


Link to post
Share on other sites

Example code. Set the OU you want to exclude in function _AD_HasRequiredRights__GivenMembers at the end of the script to test the functionality.

If it works you then can add your own permission checking function.

#region ;**** Directives created by AutoIt3Wrapper_GUI ****
#AutoIt3Wrapper_UseX64=n
#endregion ;**** Directives created by AutoIt3Wrapper_GUI ****
#include <AD.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 $hTree = GUICtrlCreateTreeView(6, 6, 600, 666, -1, $WS_EX_CLIENTEDGE)
Global $bExit = GUICtrlCreateButton("Exit", 624, 8, 97, 33)
Global $bExpand = GUICtrlCreateButton("Expand", 624, 56, 97, 33)
Global $bCollapse = GUICtrlCreateButton("Collapse", 624, 104, 97, 33)
Global $bSelect = GUICtrlCreateButton("Select OU", 624, 152, 97, 33)
#endregion ### END Koda GUI section ###

;------------------------------
; 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 ; 1 = Display the object count right to the OU
Global $bDisplay = True ; True = Display objects in the OU as well (selection = $sCategory)
;------------------------------
; Make your changes above
;------------------------------
Global $aTreeView = _AD_GetOUTreeView($sOU, $hTree, False, $bCount, $bDisplay, $sCategory, $sText, $iScope)
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)
GUISetState(@SW_SHOW)

While 1
$Msg = GUIGetMsg()
Switch $Msg
Case $GUI_EVENT_CLOSE, $bExit
Exit
Case $bExpand
_GUICtrlTreeView_Expand($hTree)
Case $bCollapse
_GUICtrlTreeView_Expand($hTree, 0, False)
Case $bSelect
$hSelection = _GUICtrlTreeView_GetSelection($hTree)
$sSelection = _GUICtrlTreeView_GetText($hTree, $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)
EndSwitch
WEnd

; #FUNCTION# ====================================================================================================================
; Name...........: _AD_GetOUTreeView
; Description ...: Fills a given TreeView control with all OUs starting with a given OU.
; Syntax.........: _AD_GetOUTreeView($sAD_OU, $hAD_TreeView[, $bAD_IsADOpen = False[, $bAD_Count = False[, $bAD_Display = False[, $sAD_Category = ""[, $sAD_Text = " (%)"[, $iAD_SearchScope = 1]]]]]])
; Parameters ....: $sAD_OU       - FQDN of the OU where to start. "" displays all OUs
;                $hAD_TreeView - Handle of the TreeView where the OUs will be displayed. Has to be created in advance
;                $bAD_IsADOpen - Optional: Pass as True if the connection to the AD has already been made by the calling script (default = False)
;                $bAD_Count  - 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 $sAD_Category
;                $bAD_Display    - Optional: True will display the objects in the OU below the OU itself (default = False)
;                $sAD_Category - 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)
;                $sAD_Text   - Optional: Text to display the count. Must contain a % which will be replaced by the actual number (default = " (%)")
;                $iAD_SearchScope - Optional: Search scope for function _AD_GetObjectsInOU: 0 = base, 1 = one-level, 2 = sub-tree (default = 1)
; 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 bnased on code by ReFran - http://www.autoitscript.com/forum/topic/84119-treeview-read-to-from-file
; Modified.......: water including ideas by HaeMHuK
; Remarks .......: Use $iAD_SearchScope = 1 to get the number of objects of a single OU.
;                Use $iAD_SearchScope = 2 to get the number of objects in the OU plus all sub-OUs.
; Related .......:
; Link ..........:
; Example .......:
; ===============================================================================================================================
Func _AD_GetOUTreeView($sAD_OU, $hAD_TreeView, $bAD_IsADOpen = False, $bAD_Count = False, $bAD_Display = False, $sAD_Category = "", $sAD_Text = " (%)", $iAD_SearchScope = 1)

Local $iAD_Count, $aObjects
If $bAD_IsADOpen = False Then
_AD_Open()
If @error Then Return SetError(@error, @extended, 0)
EndIf
$sSeparator = "\"
Local $aAD_OUs = _AD_GetAllOUs($sAD_OU, $sSeparator)
If @error <> 0 Then Return SetError(@error, @extended, 0)
Local $aAD_TreeView[$aAD_OUs[0][0] + 1][3] = [[$aAD_OUs[0][0], 3]]
Local $aAD_Result = $aAD_TreeView
Local $iIndexTV = 0, $sIgnoreOU = ""
Local $aAD_MemberOf = "" ; Dummy can be removed
For $i = 1 To $aAD_OUs[0][0]
If $sIgnoreOU = "" Or ($sIgnoreOU <> "" And StringInStr($aAD_OUs[$i][1], $sIgnoreOU, -1) = 0) Then ; OU to ignore i 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($aAD_OUs[$i][1], 983551, @UserName, $aAD_MemberOf) = 0 Then ; User doesn't have needed permissions. Ignore this OU and all sub-OUs
$sIgnoreOU = $aAD_OUs[$i][1]
Else
$sIgnoreOU = ""
EndIf
EndIf
If $sIgnoreOU = "" Then
$iIndexTV = $iIndexTV + 1
$aAD_Temp = StringSplit($aAD_OUs[$i][0], $sSeparator)
$aAD_TreeView[$iIndexTV][0] = StringFormat("%" & $aAD_Temp[0] - 1 & "s", "") & "#" & $aAD_Temp[$aAD_Temp[0]]
$aAD_TreeView[$iIndexTV][1] = $aAD_OUs[$i][1]
EndIf
Next
ReDim $aAD_TreeView[$iIndexTV + 1][3]
$aAD_TreeView[0][0] = $iIndexTV
_GUICtrlTreeView_BeginUpdate($hAD_TreeView)
Local $ahAD_Node[50], $sAD_LDAPString
If $sAD_Category <> "" And StringIsAlNum($sAD_Category) Then
$sAD_LDAPString = "(objectcategory=" & $sAD_Category & ")"
Else
$sAD_LDAPString = $sAD_Category
EndIf
$iAD_OutIndex = 0
For $iAD_Index = 1 To $aAD_TreeView[0][0]
$iAD_OutIndex += 1
$aObjects = ""
$sAD_Line = StringSplit(StringStripCR($aAD_TreeView[$iAD_Index][0]), @TAB)
$iAD_Level = StringInStr($sAD_Line[1], "#")
If $iAD_Level = 0 Then ExitLoop
If ($bAD_Count Or $bAD_Display) And $sAD_LDAPString <> "" Then
If $bAD_Display Then
$aObjects = _AD_GetObjectsInOU($aAD_TreeView[$iAD_Index][1], $sAD_LDAPString, $iAD_SearchScope, "samaccountname,distinguishedname", "", False)
If @error Then
$iAD_Count = 0
Else
$iAD_Count = $aObjects[0][0]
EndIf
Else
$iAD_Count = _AD_GetObjectsInOU($aAD_TreeView[$iAD_Index][1], $sAD_LDAPString, $iAD_SearchScope, "samaccountname,distinguishedname", "", True)
EndIf
EndIf
$sAD_Temp = ""
If $bAD_Count And $sAD_LDAPString <> "" Then $sAD_Temp = StringReplace($sAD_Text, "%", $iAD_Count)
If $iAD_Level = 1 Then
$ahAD_Node[$iAD_Level] = _GUICtrlTreeView_Add($hAD_TreeView, 0, StringMid($sAD_Line[1], $iAD_Level + 1) & $sAD_Temp)
Else
$ahAD_Node[$iAD_Level] = _GUICtrlTreeView_AddChild($hAD_TreeView, $ahAD_Node[$iAD_Level - 1], StringMid($sAD_Line[1], $iAD_Level + 1) & $sAD_Temp)
EndIf
$aAD_Result[$iAD_OutIndex][0] = $aAD_TreeView[$iAD_Index][0]
$aAD_Result[$iAD_OutIndex][1] = $aAD_TreeView[$iAD_Index][1]
$aAD_Result[$iAD_OutIndex][2] = $ahAD_Node[$iAD_Level]
; Add the objects of the OU to the TreeView
If IsArray($aObjects) Then
ReDim $aAD_Result[UBound($aAD_Result, 1) + $aObjects[0][0]][UBound($aAD_Result, 2)]
For $iAD_Index2 = 1 To $aObjects[0][0]
$iAD_OutIndex += 1
If StringRight($aObjects[$iAD_Index2][0], 1) = "$" Then $aObjects[$iAD_Index2][0] = StringLeft($aObjects[$iAD_Index2][0], StringLen($aObjects[$iAD_Index2][0]) - 1)
$aAD_Result[$iAD_OutIndex][0] = $aObjects[$iAD_Index2][0]
$aAD_Result[$iAD_OutIndex][1] = $aObjects[$iAD_Index2][1]
$aAD_Result[$iAD_OutIndex][2] = _GUICtrlTreeView_AddChild($hAD_TreeView, $ahAD_Node[$iAD_Level], $aObjects[$iAD_Index2][0])
Next
EndIf
Next
If $bAD_IsADOpen = False Then _AD_Close()
_GUICtrlTreeView_EndUpdate($hAD_TreeView)
$aAD_Result[0][0] = UBound($aAD_Result, 1) - 1
$aAD_Result[0][1] = UBound($aAD_Result, 2)
Return $aAD_Result

EndFunc ;==>_AD_GetOUTreeView

Func _AD_HasRequiredRights__GivenMembers($sAD_OUs, $iPermission, $Username, $aAD_MemberOf)
If $sAD_OUs = "OU=User_Accounts,OU=xyt,DC=company,DC=com" Then Return 0
Return 1
EndFunc

My UDFs and Tutorials:

Spoiler

UDFs:
Active Directory (NEW 2019-10-24 - Version 1.4.14.0) - Download - General Help & Support - Example Scripts - Wiki
OutlookEX (NEW 2019-11-30 - Version 1.4.0.0) - Download - General Help & Support - Example Scripts - Wiki
Outlook Tools (2019-07-22 - Version 0.6.0.0) - Download - General Help & Support - Wiki
ExcelChart (2017-07-21 - Version 0.4.0.1) - Download - General Help & Support - Example Scripts
PowerPoint (2017-06-06 - Version 0.0.5.0) - Download - General Help & Support
Excel - Example Scripts - Wiki
Word - Wiki
Task Scheduler (NEW 2019-12-03 - Version 1.5.1.0) - Download - General Help & Support - Wiki

Tutorials:
ADO - Wiki

 

Share this post


Link to post
Share on other sites

That worked, thanks!

Now an aesthetic piece... is there a way to have a progress bar or some sort of message indicating that it's "working"? It seemingly does nothing for about two minutes while it checks the permissions.

Share this post


Link to post
Share on other sites

Something like this?

#region ;**** Directives created by AutoIt3Wrapper_GUI ****
#AutoIt3Wrapper_UseX64=n
#endregion ;**** Directives created by AutoIt3Wrapper_GUI ****
#include <AD.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 $hTree = GUICtrlCreateTreeView(6, 6, 600, 666, -1, $WS_EX_CLIENTEDGE)
Global $hExit = GUICtrlCreateButton("Exit", 624, 8, 97, 33)
Global $hExpand = GUICtrlCreateButton("Expand", 624, 56, 97, 33)
Global $hCollapse = GUICtrlCreateButton("Collapse", 624, 104, 97, 33)
Global $hSelect = GUICtrlCreateButton("Select OU", 624, 152, 97, 33)
Global $hProgress = GUICtrlCreateProgress(624, 200, 97, 20)
GUISetState(@SW_SHOW)

#endregion ### END Koda GUI section ###

;------------------------------
; 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 ; 1 = Display the object count right to the OU
Global $bDisplay = True ; True = Display objects in the OU as well (selection = $sCategory)
;------------------------------
; Make your changes above
;------------------------------
Global $aTreeView = _AD_GetOUTreeView($sOU, $hTree, False, $bCount, $bDisplay, $sCategory, $sText, $iScope)
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)
GUICtrlDelete($hProgress)
While 1
    $Msg = GUIGetMsg()
    Switch $Msg
        Case $GUI_EVENT_CLOSE, $hExit
            Exit
        Case $hExpand
            _GUICtrlTreeView_Expand($hTree)
        Case $hCollapse
            _GUICtrlTreeView_Expand($hTree, 0, False)
        Case $hSelect
            $hSelection = _GUICtrlTreeView_GetSelection($hTree)
            $sSelection = _GUICtrlTreeView_GetText($hTree, $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)
    EndSwitch
WEnd

; #FUNCTION# ====================================================================================================================
; Name...........: _AD_GetOUTreeView
; Description ...: Fills a given TreeView control with all OUs starting with a given OU.
; Syntax.........: _AD_GetOUTreeView($sAD_OU, $hAD_TreeView[, $bAD_IsADOpen = False[, $bAD_Count = False[, $bAD_Display = False[, $sAD_Category = ""[, $sAD_Text = " (%)"[, $iAD_SearchScope = 1]]]]]])
; Parameters ....: $sAD_OU        - FQDN of the OU where to start. "" displays all OUs
;                 $hAD_TreeView    - Handle of the TreeView where the OUs will be displayed. Has to be created in advance
;                 $bAD_IsADOpen    - Optional: Pass as True if the connection to the AD has already been made by the calling script (default = False)
;                 $bAD_Count       - 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 $sAD_Category
;                 $bAD_Display   - Optional: True will display the objects in the OU below the OU itself (default = False)
;                 $sAD_Category    - 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)
;                 $sAD_Text     - Optional: Text to display the count. Must contain a % which will be replaced by the actual number (default = " (%)")
;                 $iAD_SearchScope - Optional: Search scope for function _AD_GetObjectsInOU: 0 = base, 1 = one-level, 2 = sub-tree (default = 1)
; 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 bnased on code by ReFran - http://www.autoitscript.com/forum/topic/84119-treeview-read-to-from-file
; Modified.......: water including ideas by HaeMHuK
; Remarks .......: Use $iAD_SearchScope = 1 to get the number of objects of a single OU.
;                 Use $iAD_SearchScope = 2 to get the number of objects in the OU plus all sub-OUs.
; Related .......:
; Link ..........:
; Example .......:
; ===============================================================================================================================
Func _AD_GetOUTreeView($sAD_OU, $hAD_TreeView, $bAD_IsADOpen = False, $bAD_Count = False, $bAD_Display = False, $sAD_Category = "", $sAD_Text = " (%)", $iAD_SearchScope = 1)

    Local $iAD_Count, $aObjects
    If $bAD_IsADOpen = False Then
        _AD_Open()
        If @error Then Return SetError(@error, @extended, 0)
    EndIf
    $sSeparator = "\"
    Local $aAD_OUs = _AD_GetAllOUs($sAD_OU, $sSeparator)
    If @error <> 0 Then Return SetError(@error, @extended, 0)
    Local $aAD_TreeView[$aAD_OUs[0][0] + 1][3] = [[$aAD_OUs[0][0], 3]]
    Local $aAD_Result = $aAD_TreeView
    Local $iIndexTV = 0, $sIgnoreOU = ""
    Local $aAD_MemberOf = "" ; Dummy can be removed
    For $i = 1 To $aAD_OUs[0][0]
        If $sIgnoreOU = "" Or ($sIgnoreOU <> "" And StringInStr($aAD_OUs[$i][1], $sIgnoreOU, -1) = 0) Then ; OU to ignore i 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($aAD_OUs[$i][1], 983551, @UserName, $aAD_MemberOf) = 0 Then ; User doesn't have needed permissions. Ignore this OU and all sub-OUs
                $sIgnoreOU = $aAD_OUs[$i][1]
            Else
                $sIgnoreOU = ""
            EndIf
        EndIf
        If $sIgnoreOU = "" Then
            $iIndexTV = $iIndexTV + 1
            $aAD_Temp = StringSplit($aAD_OUs[$i][0], $sSeparator)
            $aAD_TreeView[$iIndexTV][0] = StringFormat("%" & $aAD_Temp[0] - 1 & "s", "") & "#" & $aAD_Temp[$aAD_Temp[0]]
            $aAD_TreeView[$iIndexTV][1] = $aAD_OUs[$i][1]
        EndIf
    Next
    ReDim $aAD_TreeView[$iIndexTV + 1][3]
    $aAD_TreeView[0][0] = $iIndexTV
    _GUICtrlTreeView_BeginUpdate($hAD_TreeView)
    Local $ahAD_Node[50], $sAD_LDAPString
    If $sAD_Category <> "" And StringIsAlNum($sAD_Category) Then
        $sAD_LDAPString = "(objectcategory=" & $sAD_Category & ")"
    Else
        $sAD_LDAPString = $sAD_Category
    EndIf
    $iAD_OutIndex = 0
    For $iAD_Index = 1 To $aAD_TreeView[0][0]
        GUICtrlSetData($hProgress, $iAD_Index * 100 / $aAD_TreeView[0][0])
        $iAD_OutIndex += 1
        $aObjects = ""
        $sAD_Line = StringSplit(StringStripCR($aAD_TreeView[$iAD_Index][0]), @TAB)
        $iAD_Level = StringInStr($sAD_Line[1], "#")
        If $iAD_Level = 0 Then ExitLoop
        If ($bAD_Count Or $bAD_Display) And $sAD_LDAPString <> "" Then
            If $bAD_Display Then
                $aObjects = _AD_GetObjectsInOU($aAD_TreeView[$iAD_Index][1], $sAD_LDAPString, $iAD_SearchScope, "samaccountname,distinguishedname", "", False)
                If @error Then
                    $iAD_Count = 0
                Else
                    $iAD_Count = $aObjects[0][0]
                EndIf
            Else
                $iAD_Count = _AD_GetObjectsInOU($aAD_TreeView[$iAD_Index][1], $sAD_LDAPString, $iAD_SearchScope, "samaccountname,distinguishedname", "", True)
            EndIf
        EndIf
        $sAD_Temp = ""
        If $bAD_Count And $sAD_LDAPString <> "" Then $sAD_Temp = StringReplace($sAD_Text, "%", $iAD_Count)
        If $iAD_Level = 1 Then
            $ahAD_Node[$iAD_Level] = _GUICtrlTreeView_Add($hAD_TreeView, 0, StringMid($sAD_Line[1], $iAD_Level + 1) & $sAD_Temp)
        Else
            $ahAD_Node[$iAD_Level] = _GUICtrlTreeView_AddChild($hAD_TreeView, $ahAD_Node[$iAD_Level - 1], StringMid($sAD_Line[1], $iAD_Level + 1) & $sAD_Temp)
        EndIf
        $aAD_Result[$iAD_OutIndex][0] = $aAD_TreeView[$iAD_Index][0]
        $aAD_Result[$iAD_OutIndex][1] = $aAD_TreeView[$iAD_Index][1]
        $aAD_Result[$iAD_OutIndex][2] = $ahAD_Node[$iAD_Level]
        ; Add the objects of the OU to the TreeView
        If IsArray($aObjects) Then
            ReDim $aAD_Result[UBound($aAD_Result, 1) + $aObjects[0][0]][UBound($aAD_Result, 2)]
            For $iAD_Index2 = 1 To $aObjects[0][0]
                $iAD_OutIndex += 1
                If StringRight($aObjects[$iAD_Index2][0], 1) = "$" Then $aObjects[$iAD_Index2][0] = StringLeft($aObjects[$iAD_Index2][0], StringLen($aObjects[$iAD_Index2][0]) - 1)
                $aAD_Result[$iAD_OutIndex][0] = $aObjects[$iAD_Index2][0]
                $aAD_Result[$iAD_OutIndex][1] = $aObjects[$iAD_Index2][1]
                $aAD_Result[$iAD_OutIndex][2] = _GUICtrlTreeView_AddChild($hAD_TreeView, $ahAD_Node[$iAD_Level], $aObjects[$iAD_Index2][0])
            Next
        EndIf
    Next
    If $bAD_IsADOpen = False Then _AD_Close()
    _GUICtrlTreeView_EndUpdate($hAD_TreeView)
    $aAD_Result[0][0] = UBound($aAD_Result, 1) - 1
    $aAD_Result[0][1] = UBound($aAD_Result, 2)
    Return $aAD_Result

EndFunc   ;==>_AD_GetOUTreeView

Func _AD_HasRequiredRights__GivenMembers($sAD_OUs, $iPermission, $Username, $aAD_MemberOf)
    If $sAD_OUs = "OU=User_Accounts,OU=xyt,DC=company,DC=com" Then Return 0
    Return 1
EndFunc   ;==>_AD_HasRequiredRights__GivenMembers


My UDFs and Tutorials:

Spoiler

UDFs:
Active Directory (NEW 2019-10-24 - Version 1.4.14.0) - Download - General Help & Support - Example Scripts - Wiki
OutlookEX (NEW 2019-11-30 - Version 1.4.0.0) - Download - General Help & Support - Example Scripts - Wiki
Outlook Tools (2019-07-22 - Version 0.6.0.0) - Download - General Help & Support - Wiki
ExcelChart (2017-07-21 - Version 0.4.0.1) - Download - General Help & Support - Example Scripts
PowerPoint (2017-06-06 - Version 0.0.5.0) - Download - General Help & Support
Excel - Example Scripts - Wiki
Word - Wiki
Task Scheduler (NEW 2019-12-03 - Version 1.5.1.0) - Download - General Help & Support - Wiki

Tutorials:
ADO - Wiki

 

Share this post


Link to post
Share on other sites

Yes, exactly like that, except I'd prefer to have it show progress as it is enumerating permissions on the OUs since that is what takes the longest (it takes about 3 minutes). So I moved the progress bar update to the first for loop.

Question, the way it's currently coded in your example, does it check the permissions on the sub-OUs too? Or does it just check to see if you have permission on the top level OU and assume you have permission on the sub-OUs?

Edited by chaoticyeshua

Share this post


Link to post
Share on other sites

No. It checks tehe permission of an OU. If the user doesn't have the proper permissions the FQDN of the OU is stored in variable $sIgnoreOU. As long as the script processes any sub OUs the permission isn't checked. Checking again starts when the OU changes.

But I haven't tested with real permission checking.


My UDFs and Tutorials:

Spoiler

UDFs:
Active Directory (NEW 2019-10-24 - Version 1.4.14.0) - Download - General Help & Support - Example Scripts - Wiki
OutlookEX (NEW 2019-11-30 - Version 1.4.0.0) - Download - General Help & Support - Example Scripts - Wiki
Outlook Tools (2019-07-22 - Version 0.6.0.0) - Download - General Help & Support - Wiki
ExcelChart (2017-07-21 - Version 0.4.0.1) - Download - General Help & Support - Example Scripts
PowerPoint (2017-06-06 - Version 0.0.5.0) - Download - General Help & Support
Excel - Example Scripts - Wiki
Word - Wiki
Task Scheduler (NEW 2019-12-03 - Version 1.5.1.0) - Download - General Help & Support - Wiki

Tutorials:
ADO - Wiki

 

Share this post


Link to post
Share on other sites

It's working just fine and the tree view only has the OUs that I have permission on when I use the _AD_HasRequiredRights__GivenMembers that I modified. I just wanted to make sure sub-OUs were not having their permissions checked because it takes so long to run :) Thank you for your help! I should be able to take it from here!

Share this post


Link to post
Share on other sites

If I find the time I hope to update the example script and post it on the example scripts thread.


My UDFs and Tutorials:

Spoiler

UDFs:
Active Directory (NEW 2019-10-24 - Version 1.4.14.0) - Download - General Help & Support - Example Scripts - Wiki
OutlookEX (NEW 2019-11-30 - Version 1.4.0.0) - Download - General Help & Support - Example Scripts - Wiki
Outlook Tools (2019-07-22 - Version 0.6.0.0) - Download - General Help & Support - Wiki
ExcelChart (2017-07-21 - Version 0.4.0.1) - Download - General Help & Support - Example Scripts
PowerPoint (2017-06-06 - Version 0.0.5.0) - Download - General Help & Support
Excel - Example Scripts - Wiki
Word - Wiki
Task Scheduler (NEW 2019-12-03 - Version 1.5.1.0) - Download - General Help & Support - Wiki

Tutorials:
ADO - Wiki

 

Share this post


Link to post
Share on other sites
Guest
This topic is now closed to further replies.
Sign in to follow this  

×
×
  • Create New...