Jump to content

AD: Nested Group Membership: Get the "chain"


rudi
 Share

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!

Link to comment
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!

Link to comment
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
 Share

×
×
  • Create New...