Jump to content
Sign in to follow this  
lcty

Nested AD Groups

Recommended Posts

lcty

Hi Community,

I'm currently trying to realise a delicate algorithm in AutoIt.

We want to receive all members of an AD group. If there are more (nested) groups inside we want to get their members as well. If in these are also groups we want the members.

My problem is, I cannot think of an appropriate solution for this at the moment as this can be infinite at some point.

What I already have is a function

   ... that can read out all the Groups in a Group and returns 0 if there are none

   ... that can read out all the Users in a Group.

Now I was thinking of following pseudo code:

ROOT = getNestedGroups(<any group>)
If not ROOT = 0 Then
   ; There are groups below
   For every Nested Group Do
     CHILD1 = getNestedGroups(Nested Group [$ii])
     If not CHILD1 = 0 Then
       ; there are as well groups below
       CHILD2 = getNested...
       ....
       ..... and so on
     EndIf   
  Next
EndIf

And this is going to be infinite since I do not know how many groups are linked together.

Does anybody of you guys have an idea that could point me to the right direction?

Thanks a lot in advance!

Best regards

lcty

Share this post


Link to post
Share on other sites
czardas

It is not clear to me what you want. For an infinite loop look at While ... WEnd, and to escape an infinite loop use ExitLoop. There is a recursion limit in AutoIt, so infinitely nested loops will always fail. No infinite run time is feasible, nor can an infinite amount of data be parsed, so you probably want to define some reasonable limits.

Share this post


Link to post
Share on other sites
BrewManNH

Have you looked at the >AD UDF for doing what you're looking to do? I'm not sure if it can do it, but it's a place to start.

Edited by BrewManNH

If I posted any code, assume that code was written using the latest release version unless stated otherwise. Also, if it doesn't work on XP I can't help with that because I don't have access to XP, and I'm not going to.
Give a programmer the correct code and he can do his work for a day. Teach a programmer to debug and he can do his work for a lifetime - by Chirag Gude
How to ask questions the smart way!

I hereby grant any person the right to use any code I post, that I am the original author of, on the autoitscript.com forums, unless I've specifically stated otherwise in the code or the thread post. If you do use my code all I ask, as a courtesy, is to make note of where you got it from.

Back up and restore Windows user files _Array.au3 - Modified array functions that include support for 2D arrays.  -  ColorChooser - An add-on for SciTE that pops up a color dialog so you can select and paste a color code into a script.  -  Customizable Splashscreen GUI w/Progress Bar - Create a custom "splash screen" GUI with a progress bar and custom label.  -  _FileGetProperty - Retrieve the properties of a file  -  SciTE Toolbar - A toolbar demo for use with the SciTE editor  -  GUIRegisterMsg demo - Demo script to show how to use the Windows messages to interact with controls and your GUI.  -   Latin Square password generator

Share this post


Link to post
Share on other sites
water

Please have a look at my AD UDF, function_AD_RecursiveGetGroupMembers.


My UDFs and Tutorials:

Spoiler

UDFs:
Active Directory (2018-06-01 - Version 1.4.9.0) - Download - General Help & Support - Example Scripts - Wiki
OutlookEX (NEW 2018-09-01 - Version 1.3.4.0) - Download - General Help & Support - Example Scripts - 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
 
Tutorials:

ADO - Wiki

 

Share this post


Link to post
Share on other sites
czardas

It seems this has already been dealt with in detail, and I advise you follow the MVP suggestions. Anyway I wrote an example to illustrate the AutoIt features I mentioned in my previous post, for you to noodle over as well. :)

;

Global $gInteger = 0

ConsoleWrite(_Recursion() & @LF)

Func _Recursion() ; Recursive function
    While 1 ; Infinite Loop
        $gInteger += 2
        If Mod($gInteger, 3) = 0 Then ExitLoop ; Exit the loop on this condition
    WEnd
    If $gInteger < 10 Then _Recursion() ; Function calls itself again on this condition
    Return $gInteger ; Finally we get the answer
EndFunc
Edited by czardas

Share this post


Link to post
Share on other sites
lcty

Thanks for your quick answers! I really appreciate that!!

czardas, your recursive loop makes sense. You probably got me an idea! I'm going to try something and post it here if it was successfull.

... and water, as you are the developer of the AD UDF - thank you very much for sharing this, you made my life a lot easier!!

Edited by lcty
  • Like 1

Share this post


Link to post
Share on other sites
water

Thanks! But at least 50% go to Jonathan Clelland, the original author of the adfunctions UDF.


My UDFs and Tutorials:

Spoiler

UDFs:
Active Directory (2018-06-01 - Version 1.4.9.0) - Download - General Help & Support - Example Scripts - Wiki
OutlookEX (NEW 2018-09-01 - Version 1.3.4.0) - Download - General Help & Support - Example Scripts - 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
 
Tutorials:

ADO - Wiki

 

Share this post


Link to post
Share on other sites
lcty

Hi again :)

Since three days I am working on this script now. I suppose I got quite close. However the recursive AD check didn't work for me. Though I got a different solution almost working ;)

_AD_Open()
$group = "<My starting AD group>"
__getAllGroups($group)


; get All AD groups and sub-groups
Func __getAllGroups($group)
   Dim $aMaster[1]
   Dim $aLevel[1]
   $aMaster[0] = $group
   $aLevel[0] = $group

   While 1
      ; check Level of current scope in $aLevel
      $aLevel = __checkLevels($aLevel)

      If $aLevel[0] = 0 Then
         ; if function returns no groups in this scope
         ExitLoop
      Else
         ; if groups were returned save to master array
         ; continue with $aLevel as current scope
         _ArrayConcatenate($aMaster, $aLevel)
      EndIf
   WEnd

   ; display once all sub-groups are collected
   _ArrayDisplay($aMaster)
EndFunc


; check the current scope and return all sub-groups
; of the queried groupS (array $aGroup). Duplicates removed
Func __checkLevels($aGroup)
   Dim $aResult[0]
   If UBound($aGroup) >= 1 Then
      For $j = 0 to UBound($aGroup)-1
         ConsoleWrite("checking "& $aGroup[$j] & @CRLF)
         $aMembers = _AD_GetGroupMembers($aGroup[$j])
         For $i = 1 to UBound($aMembers)-1
            If __IsADGroup($aMembers[$i]) Then
               _ArrayAdd($aResult, $aMembers[$i])
               ConsoleWrite("  adding " & $aMembers[$i] & " as result of check " & $aGroup[$j] & @CRLF)
            EndIf
         Next
      Next
   EndIf
   $aResult = _ArrayUnique($aResult)
   Return $aResult
EndFunc

; check whether an AD object is a group
; needs possibly to be improved!!
Func __IsADGroup($sGroup)
  $aDelimited = StringSplit($sGroup, ",")
   If UBound($aDelimited) > 2 Then
      If ($aDelimited[2] = "OU=Groups" AND $aDelimited[2] <> "") OR ($aDelimited[2]="CN=Users" AND $aDelimited[2] <> "" AND StringInStr($aDelimited[1], "Domain Admins")) Then
         Return True
      EndIf
   Else
      Return False
   EndIf
EndFunc

_AD_Close()

Strangely it never exits the loop and always checks the same scope. I'm a bit helpless at the moment as I already investigated for hours.

Maybe you have an idea what is going wrong? Maybe at one sight as you're all professionals :P

Additionally I'm searching for a way to improve the function __IsADGroup() to determine whether an entry returned by _AD_GetGroupMembers is a group or a user object.

Hoping for your help.

Tahnk you!

Share this post


Link to post
Share on other sites
water

I will have a look at _AD_IsMemberOf again. The recursive check should run anyway!


My UDFs and Tutorials:

Spoiler

UDFs:
Active Directory (2018-06-01 - Version 1.4.9.0) - Download - General Help & Support - Example Scripts - Wiki
OutlookEX (NEW 2018-09-01 - Version 1.3.4.0) - Download - General Help & Support - Example Scripts - 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
 
Tutorials:

ADO - Wiki

 

Share this post


Link to post
Share on other sites
water

Icty,

I had a look at _AD_IsMember and the recursive function works quite well.

_AD_RecursiveGetGroupMembers returns the correct resultsas well.

So can you please describe what doesn't work for you?


My UDFs and Tutorials:

Spoiler

UDFs:
Active Directory (2018-06-01 - Version 1.4.9.0) - Download - General Help & Support - Example Scripts - Wiki
OutlookEX (NEW 2018-09-01 - Version 1.3.4.0) - Download - General Help & Support - Example Scripts - 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
 
Tutorials:

ADO - Wiki

 

Share this post


Link to post
Share on other sites
water

To check the objectclass I suggest:

#include <AD.au3>
_AD_Open()
ConsoleWrite(_CheckObjectClass(@Username, "user") & @LF) ; Is the current user a class "user"?
_AD_Close()
Exit

Func _CheckObjectClass($sObject, $sClass)
    Local $aClasses = _AD_Getobjectattribute($sObject, "objectClass")
    For $iIndex = 0 To UBound($aClasses, 1) - 1
        If $aClasses[$iIndex] = $sClass Then Return 1
    Next
    Return 0
EndFunc
Edited by water

My UDFs and Tutorials:

Spoiler

UDFs:
Active Directory (2018-06-01 - Version 1.4.9.0) - Download - General Help & Support - Example Scripts - Wiki
OutlookEX (NEW 2018-09-01 - Version 1.3.4.0) - Download - General Help & Support - Example Scripts - 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
 
Tutorials:

ADO - Wiki

 

Share this post


Link to post
Share on other sites
lcty

Thank you very much! This helpded me massively.

Strangely the _AD_RecursiveGetGroupMembers function works for me now. This is the actual solution for my issue!

The way you recommended to check the objectclass was very helpful as well!

So this is what I did:

Func _getACLMembers($aGroups)
   Dim $aUserTable[2]
   For $i = 1 to UBound($aGroups)-1
      $aMembers = _AD_RecursiveGetGroupMembers($aGroups[$i])
      For $j = 1 to UBound($aMembers)-1
         $aTrace = StringSplit($aMembers[$j], "|")
         If __CheckObjectClass($aTrace[1], "user") Then
            ReDim $aUserTable[UBound($aUserTable)+1]
            $aUserTable[UBound($aUserTable)-1] = $aTrace[1]
         EndIf
      Next
   Next
   Return _ArrayUnique($aUserTable)
EndFunc

Func __CheckObjectClass($sObject, $sClass)
    Local $aClasses = _AD_Getobjectattribute($sObject, "objectClass")
    For $iIndex = 0 To UBound($aClasses, 1) - 1
        If $aClasses[$iIndex] = $sClass Then Return 1
    Next
    Return 0
EndFunc

Share this post


Link to post
Share on other sites
water

Glad to be of service :)


My UDFs and Tutorials:

Spoiler

UDFs:
Active Directory (2018-06-01 - Version 1.4.9.0) - Download - General Help & Support - Example Scripts - Wiki
OutlookEX (NEW 2018-09-01 - Version 1.3.4.0) - Download - General Help & Support - Example Scripts - 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
 
Tutorials:

ADO - Wiki

 

Share this post


Link to post
Share on other sites
water

vortexed,

did you delete your last question?


My UDFs and Tutorials:

Spoiler

UDFs:
Active Directory (2018-06-01 - Version 1.4.9.0) - Download - General Help & Support - Example Scripts - Wiki
OutlookEX (NEW 2018-09-01 - Version 1.3.4.0) - Download - General Help & Support - Example Scripts - 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
 
Tutorials:

ADO - Wiki

 

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
Sign in to follow this  

×