Jump to content
Sign in to follow this  
rudi

AD: Nested Group Membership: Get the "chain"

Recommended Posts

Hello,

 

<edit>

In this posting below you will find a script to get an Active Directory User's Group Memberships including nested Group Memberships:

 

</edit>

quite a while ago I started this thread: https://www.autoitscript.com/forum/topic/193984-ad-member-of-group-in-group/

 

#include <AD.au3>

_AD_Open()
$user=_AD_SamAccountNameToFQDN("ASP")
$group=_AD_SamAccountNameToFQDN("daten-Bestellung-QS_lesen")
$result=_AD_IsMemberOf($group,$user,false,True) ; $Group is the 1st, $User the 2nd param
ConsoleWrite('@@ Debug(' & @ScriptLineNumber & ') : $result = ' & $result & @CRLF & '>Error code: ' & @error & @CRLF) ;### Debug Console

_AD_Close()

this works fine, thanks for the help in the other thread.

Howto to get the "chain" of groups for nested group memberships?

In AD.AU3 I found the function _AD_RecursiveGetMemberOf(), which might be an approach, (get all the group content then sort out what's needed), just wondering if there is another function that I've overlooked, that directly would give me the "nested membership chain" *ONLY*?

 

Regards, Rudi.

Edited by rudi

Earth is flat, pigs can fly, and Nuclear Power is SAFE!

Share this post


Link to post
Share on other sites

Hello,

This is now working quite fine for me. Maybe someone else can make use of this script, at least as a "starter" ...

 

It's giving an output like this one

 

Dieses Script: \\file03\file03-data01\DATEN\EDV\Anleitungen Hilfe Doku\microsoft\AD\Auswertung-Rechte-Zustand\Get-UserInGroupsWithNestedGroups.exe
Ausgeführt von AD\Rudi auf PC-Rudi
Diese  Ergebnis-Datei: C:\Users\admin\AppData\Local\Temp\Gruppenauswertung-Fuer-TestUserNestedGroups_2019-01-24_17h-16m-10_Result.txt
Ausgewerteter AD User: TestUserNestedGroups
----------------------------------------------------------------------------
............................................ 

Gruppe: TestNestedGroup-A
    Direkt
............................................ 

Gruppe: TestNestedGroup-B
    Direkt
............................................ 

Gruppe: TestNestedGroup-Sub1
        Nested: TestNestedGroup-A MemberOf TestNestedGroup-Sub1
............................................ 

Gruppe: TestNestedGroup-Sub2
        Nested: TestNestedGroup-A MemberOf TestNestedGroup-Sub2
............................................ 

Gruppe: TestNestedGroup-Sub2-1
    Direkt
        Nested: TestNestedGroup-B MemberOf TestNestedGroup-Sub2-1
        Nested: TestNestedGroup-A MemberOf TestNestedGroup-Sub2 MemberOf TestNestedGroup-Sub2-1
----------------------------------- EOF --------------------------------------------

 

#Region ;**** Directives created by AutoIt3Wrapper_GUI ****
#AutoIt3Wrapper_Res_Description=Für einen einzelnen AD User Gruppenmitgliedschaften mit Verschachtelungen darstellen
#AutoIt3Wrapper_Res_Fileversion=1.0.0.4
#AutoIt3Wrapper_Res_Fileversion_AutoIncrement=p
#AutoIt3Wrapper_Res_LegalCopyright=(c) 2019 by Rudolf Thilo, IT-Beratung Rudolf Thilo
#AutoIt3Wrapper_Res_SaveSource=y
#AutoIt3Wrapper_Res_Language=1031
#AutoIt3Wrapper_Add_Constants=n
#EndRegion ;**** Directives created by AutoIt3Wrapper_GUI ****
#include <AD.au3>
#include <File.au3>
#include <Debug.au3>


$SAM = InputBox("Get Group Memberships including nested ones","Enter user's SAMACCOUNTNAME","SomeUsersSAMaccountName")
_AD_Open()
$user = _AD_SamAccountNameToFQDN($SAM)
; $result=_AD_IsMemberOf($user,$group,false,True)
$aMemberOf = _AD_RecursiveGetMemberOf($user, 100, True, False)

_ArraySort($aMemberOf, 0, 1)

Dim $aResult[1][2] = [[0]]


; _DebugArrayDisplay($aMemberOf)

$MemberOf = " MemberOf "

For $a = 1 To $aMemberOf[0]
    $NextGroup = $aMemberOf[$a]
    ConsoleWrite('@@ Debug(' & @ScriptLineNumber & ') : $NextGroup = ' & $NextGroup & @CRLF & '>Error code: ' & @error & @CRLF) ;### Debug Console
    $aNested = StringSplit($NextGroup, "|")
    If IsArray($aNested) Then
        Switch $aNested[0]
            Case 1 ; nicht verschachtelt
                $iFound = _ArraySearch($aResult, $aNested[1], 1, 0, 0, 0, 1, 0) ; Start, Stop (alles), caseinsensitive, tolerant match, vorwärts, Spalte 0
                If @error Then
                    _ArrayAdd($aResult, $NextGroup & "|Direkt")
                    ; _DebugArrayDisplay($aResult, "ResultArray ergänzt")
                Else
                    ; _DebugArrayDisplay($aResult, "Gefunden an Pos. " & $iFound & " --> " & $aNested[1])
                EndIf
            Case Else ; verschachtelt
                ConsoleWrite("--> Verschachtelt: " & $NextGroup & @CRLF)
                ; _DebugArrayDisplay($aNested,$a & " - Verschachtelt: " & $NextGroup)
                $foo = "Nested: "
                For $x = $aNested[0] To 1 Step -1
                    $foo &= $aNested[$x] & $MemberOf
                Next
                If StringRight($foo, StringLen($MemberOf)) = $MemberOf Then $foo = StringTrimRight($foo, StringLen($MemberOf))
                ConsoleWrite('@@ Debug(' & @ScriptLineNumber & ') : $foo = ' & $foo & @CRLF & '>Error code: ' & @error & @CRLF) ;### Debug Console
                $iFound = _ArraySearch($aResult, $aNested[1], 1, 0, 0, 0, 1, 0) ; Start, Stop (alles), caseinsensitive, tolerant match, vorwärts, Spalte 0
                $err=@error
                If $err Then ; noch nicht im Array eingetragen
                _ArrayAdd($aResult, $aNested[1] & "|" & $foo)
                ; _DebugArrayDisplay($aResult,$aNested[1] & " eingetragen")
                Else
                $aResult[$iFound][1] &= "*" & $foo
                ;_DebugArrayDisplay($aResult,$aNested[1] & " an Pos. " & $iFound & " ergänzt")
                EndIf
        EndSwitch
    Else
        MsgBox(48, "Fehler", "Konnte Gruppenstring nicht zerlegen" & @CRLF & $NextGroup)
    EndIf
Next


_ArraySort($aResult,0,1)
$aResult[0][0]=UBound($aResult)-1
; _DebugArrayDisplay($aResult,"Ergebnis der Auswertung")




$ResultFile=@TempDir & "\Gruppenauswertung-Fuer-" & $SAM & "_" & @YEAR & "-" & @MON & "-" & @MDAY & "_" & @HOUR & "h-" & @MIN & "m-" & @SEC & "_Result.txt"
$hResFile=FileOpen($ResultFile,8+2)

FileWriteLine($hResFile,"Dieses Script: " & @ScriptFullPath)
FileWriteLine($hResFile,"Ausgeführt von " & @LogonDomain & "\" & @UserName & " auf " & @ComputerName)
FileWriteLine($hResFile,"Diese  Ergebnis-Datei: " & $ResultFile)
FileWriteLine($hResFile,"Ausgewerteter AD User: " & $SAM)
FileWriteLine($hResFile,"----------------------------------------------------------------------------")
for $R = 1 to $aResult[0][0]
    FileWriteLine($hResFile,"............................................ ")
    FileWriteLine($hResFile,"")
    FileWriteLine($hResFile,"Gruppe: " & $aResult[$R][0])
    $Quellen=$aResult[$R][1]
    $aQuellen=StringSplit($Quellen,"*")
    if IsArray ($aQuellen) Then
        for $Q = 1 to $aQuellen[0]
            FileWriteLine($hResFile,@TAB & StringReplace($aQuellen[$Q],"Nested: ", @TAB & "Nested: "))
        Next
        Else
        FileWriteLine($hResFile,"Zerlegen des Array Elements mit den Gruppen-Infos gescheitert!")
        FileWriteLine($hResFile,@TAB & $aResult[$r][1])
        FileWriteLine($hResFile,"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!")
        EndIf
Next
FileWriteLine($hResFile,"----------------------------------- EOF --------------------------------------------")
FileClose($hResFile)
ShellExecute($ResultFile)






#cs
_DebugArrayDisplay($aNested, "Verschachtelt: " & $NextGroup)
For $x = $aNested[0] To 1 Step -1
    $iFound = _ArraySearch($aResult, $aNested[$x], 1, 0, 0, 0, 1, 0) ; Start, Stop (alles), caseinsensitive, tolerant match, vorwärts, Spalte 0
    $err = @error
    ConsoleWrite($aNested[$x] & " an Pos. " & $x & " schon da!" & @CRLF)
    If $err Then ; noch nicht im Array eingetragen.
        ConsoleWrite("Nix da,  $x = " & $x & ", $aNested[" & $x & "] = " & $aNested[$x] & @CRLF)
        $foo = "Nested: "
        For $Rest = $x To 1 Step -1
            $foo &= $aNested[$Rest] & $MemberOf
        Next
        If StringRight($foo, StringLen($MemberOf)) = $MemberOf Then $foo = StringTrimRight($foo, StringLen($MemberOf))
        _DebugArrayDisplay($aResult, "Nix da: " & $x & "=" & $aNested[$x] & " - " & $NextGroup)
    Else ; schon im Result Array enthalten
        $foo = "Nested: "
        For $Rest = $x To 1 Step -1
            $foo &= $aNested[$Rest] & $MemberOf
        Next
        If StringRight($foo, StringLen($MemberOf)) = $MemberOf Then $foo = StringTrimRight($foo, StringLen($MemberOf))
        $aResult[$iFound][1] &= "*" & $foo
        _DebugArrayDisplay($aResult, "*Dabei* Index = " & $iFound & " - " & $x & "=" & $aNested[$x] & " - " & $NextGroup)
    EndIf
Next
#ce




Exit




$GroupDir = "h:\daten\edv\Anleitungen Hilfe Doku\microsoft\ad\Gruppen"


$aGroupFiles = _FileListToArray($GroupDir, "Daten-*-group.txt", 1, 0)

_DebugArrayDisplay($aGroupFiles)

For $i = 1 To $aGroupFiles[0]
    $GroupFile = $aGroupFiles[$i]
    $GroupName = StringReplace($GroupFile, "-group.txt", "")
    $GroupFileFPFN = $GroupDir & "\" & $GroupFile
    If FileExists($GroupFileFPFN) Then
        $aContent = FileReadToArray($GroupFileFPFN)
        If Not IsArray($aContent) Then
            ConsoleWrite("Fehler beim einlesen der vorhandenen Datei!" & @CRLF)
            ConsoleWrite($GroupFileFPFN & @CRLF)
            ConsoleWrite(" # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #" & @CRLF)
            ContinueLoop
        EndIf
        $Member = ""
        #Region Prüfen, ob direkt Mitglied in der Gruppe, Auslesen aus dem AD (tatsächlich wirksamer Zustand unabhängig vom Eintrag in der Datei
        $group = _AD_SamAccountNameToFQDN($GroupName)
        $Direkt = _AD_IsMemberOf($group, $user, False, False)
        $Verschachtelt = _AD_IsMemberOf($group, $user, False, True)
        If $Direkt Then
            $Member &= "Gruppenmitglied (direkt): " & $group & @CRLF
        ElseIf $Verschachtelt Then
            $Member &= "Gruppenmitglied (verschachtelt): " & $group & @CRLF
        EndIf
        #EndRegion Prüfen, ob direkt Mitglied in der Gruppe, Auslesen aus dem AD (tatsächlich wirksamer Zustand unabhängig vom Eintrag in der Datei

        #Region Prüfen, ob direkt oder indirekt in den Eintragungen in dieser Gruppendatei "dabei"
        For $L = 0 To UBound($aContent) - 1
            $Zeile = $aContent[$L]
            $Zeile = StringStripWS($Zeile, 8)
            $Zeile = StringLeft($Zeile, StringInStr($Zeile, ";") - 1)
            If $Zeile = $user Then
                $Member &= "Direkt eingetragen"
            Else
                $group = _AD_SamAccountNameToFQDN($Zeile)
                $Direkt = _AD_IsMemberOf($group, $user, False, False)
                $Verschachtelt = _AD_IsMemberOf($group, $user, False, True)
                If $Direkt Then
                    $Member &= "Eingetragen in Datei: Gruppenmitglied (direkt): " & $group & @CRLF
                ElseIf $Verschachtelt Then
                    $Member &= "Eingetragen in Datei: Gruppenmitglied (verschachtelt): " & $group & @CRLF
                EndIf

            EndIf
        Next
        If $Member Then
            ConsoleWrite("------ " & $GroupName & " ----------" & @CRLF)
            ConsoleWrite($Member & @CRLF)
            ConsoleWrite("" & @CRLF)
        EndIf
    Else
        ConsoleWrite("Datei fehlt: " & $GroupFileFPFN & @CRLF)
    EndIf
Next

_AD_Close()

 


Earth is flat, pigs can fly, and Nuclear Power is SAFE!

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  

  • Similar Content

    • By tweakster2010
      Hello All,
      It has been a long time since I posted, role changes etc involving work and I finally am back to modifying a program I write in AutoIt that has AD integration. I am at a point where we are modifying our structure where I am validating users access via what Distribution List they belong to in our AD OU's. What I have run into is the OU is a sub OU of a sub OU now. Meaning: CN=team, OU=DL, OU=Groups, DC=business.com(working), is now CN=Team, OU=SubDL, OU=DL, OU=Groups, DC=business.com (Not working).  Just curious if the AD functionality should be able to read it or maybe I am missing something?
       
      ElseIf _AD_IsMemberOf("CN=Team,OU=Distribution Lists,OU=Groups,DC=business,DC=com", $sFQDN_User) Then #works for primary Distro ElseIf _AD_IsMemberOf("CN=Team,OU=SubDL,OU=Distribution Lists,OU=Groups,DC=business,DC=com", $sFQDN_User) Then #fails for subOU of DL How I am accessing AD to get the information:
      _AD_Open() Global $aUser = _AD_GetObjectsInOU("", "(&(objectCategory=person)(objectClass=user)(samaccountname=" & @UserName & "))", 2, "ADsPath,Displayname,distinguishedName") Global $sDisplayName0 = $aUser[1][1] ; Displayname ;MsgBox(0,"", $sDisplayName0) If StringLeft($sDisplayName0, 2) = "9-" Then $Displaynamestring = StringTrimLeft($sDisplayName0, 2) $Displaynamestring1 = StringTrimRight($Displaynamestring, 6) The error code generated is a 1 with a 0 extended. I assume it is because it cannot find the SubOU.
       
      Thanks for any assistance.
    • By antmar904
      I'm trying to read all cells used in column "C" in excel to an array but not sure how.
       
      Local $NameArray = _Excel_RangeRead($oWorkbook, $oWorkbook.Activesheet, $oWorkbook.Range["C"].End)  
    • By Blois
      Hey Guys,
      Good?
      I'm ned help to consult in other domain. My three domain contains any domains.
      How do I get this query done?
       
      Tks for the Help!
       
    • By rudi
      Hello,
       
      from this posting of @Jos https://www.autoitscript.com/forum/topic/162005-getting-windows-users-account-type/?do=findComment&comment=1176831
      I can smoothly check, if a user is a *DIRECT* group member. Has anybody some code to check also, if a user is a *INDIRECT* member of a cascaded group construct?  Maybe with @Melba23 's AD UDF?
       
      The required rights are granted to group "Dept_B" User John is member of group "Dept_A" Group "Dept_A" is member of the group "Dept_B" So in the AD / NTFS FS environment John finally has the rights of both groups But when checking his "membership to group Dept_B" the result is "no member". The approach I can think of would be, to check all Group Members of group "Dept_B" whether they are of type group, then check again if "John" is member of than " 2nd level group"
      Func UserInGroup($InGroup,$ThisUser=@LogonDomain & "/" & @UserName) Local $objUser = ObjGet("WinNT://" & $ThisUser ) For $oGroup in $objUser.Groups If $oGroup.Name = $InGroup Then Return 1 EndIf Next Return 0 EndFunc Any suggestions appreciated, regards, Rudi.
×
×
  • Create New...