Active Directory Funktionen - Neue Version 1.5.0.0 freigegeben!

  • Hi,
    ich glaube ich habe gerade einen eventuellen Fehler oder Fehlverhalten der _AD_GetGroupMembers Funktion gefunden:

    Wenn ich eine AD Gruppe habe und diese vom Typ "Sicherheitsgruppe - Universal" ist, dann kann ich darin befindliche Universelle Gruppe nicht sehen....
    User, die sich in der Hauptgruppe befinden werden angezeigt.


    Gruß
    GerhardSchr

    Das muss eine Eigenheit von AD sein. Obwohl ich mich ehrlich gesagt da nicht so besonders auskenne. Muss dem Problem nachgegangen werden?

  • Für welche Fälle benötigt Ihr eine rekursive Funktion von _AD_IsMemberOf?

    In der Anleitung steht: This function does not verify membership in any nested groups."
    Ich dachte, dass es nützlich wäre, wenn man mit dieser Funktion auch herausfinden könnte, dass jemand indirekt Mitglied der Gruppe ist.
    (Im Moment mache ich den Umweg über _AD_RecursiveGetMemberOf und suche dann mit _ArraySearch :P )


    So nun zur _Ad_RecursiveGetGroupMembers :
    Funktioniert soweit :)
    Kleiner Fehler habe ich noch gefunden: Im Array befinden sich auch noch die Gruppen, die in den Gruppen sind.
    Ist dies richtig? oder sollten da am Schluss nurnoch die Mitglieder vorhanden sein?

    Beides könnte nützlich sein.

    Meistens (in meinen Fällen) benötigt man nur die Mitglieder der Gruppen, nicht die verschachtelten Gruppen selber :) oder?
    Wenn es für dich nicht soviel Aufwand macht, dann würde ich noch einen oder zwei Parameter hinzufügen, wo man dies Regeln kann. (Nur Gruppen Rekusiv anzeigen, nur User anzeigen, wenn beide TRUE, dann beide anzeigen). Nur ein Vorschlag :)

    Oder sollte dies schon der 3 Parameter ($bListInherited) festlegen?
    Wenn ja, dann scheint er nicht zu funktionieren (bei mir).

    Wieder mal vielen Dank!


    Gruß
    GerhardSchr


    //Edit: habe gerade bemerkt, dass nach dem Update der AD.au3 _AD_RecursiveGetMemberOf nicht mehr funktioniert. Anscheinend hat sich dort auch etwas geändert?

    6 Mal editiert, zuletzt von GerhardSchr (3. Juni 2013 um 12:19) aus folgendem Grund: Noch was vergessen ;)

  • Zitat

    habe gerade bemerkt, dass nach dem Update der AD.au3 _AD_RecursiveGetMemberOf nicht mehr funktioniert. Anscheinend hat sich dort auch etwas geändert?

    Nicht mehr funktioniert heisst Crash oder falsches oder gar kein Ergebnis?

  • Hab's bei mir ausprobiert - funktioniert.
    Verwendest Du das _AD_RecursiveGetMemberOf.au3 Beispielscript?

  • hmm auch im beispielscript wird im _ArrayDisplay nur eine 0 angezeigt.
    Ich habe alle Biespielscripte im Include verzeichnis....
    habe _AD_RecursiveGetMemberOf.au3 auch mal umbenannt in __AD_RecursiveGetMemberOf.au3 hat aber auch nix geholfen.
    (Ich dachte eventuell, dass autoit denkt, dass es die Funktion 2mal gibt)

    so sieht die Datei aus:

    [autoit]

    #AutoIt3Wrapper_AU3Check_Parameters= -d -w 1 -w 2 -w 3 -w 4 -w 5 -w 6
    #AutoIt3Wrapper_AU3Check_Stop_OnWarning=Y
    ; *****************************************************************************
    ; Example 1
    ; Returns a recursively searched list of groups the currently logged on user
    ; is a member of.
    ; For groups that are inherited, the FQDN of the group or user, and the FQDN(s)
    ; of the group(s) it was inherited from, seperated by '|'
    ; *****************************************************************************
    #include <AD.au3>

    [/autoit][autoit][/autoit][autoit]

    ; Open Connection to the Active Directory
    _AD_Open()
    If @error Then Exit MsgBox(16, "Active Directory Example Skript", "Function _AD_Open encountered a problem. @error = " & @error & ", @extended = " & @extended)

    [/autoit][autoit][/autoit][autoit]

    ; Returns a recursively searched list of groups the currently logged on user is a member of
    Global $aUser = _AD_RecursiveGetMemberOf(@UserName, 10, 1)
    If @error > 0 Then
    MsgBox(64, "Active Directory Functions - Example 1", "User '" & @UserName & "' has not been assigned to any group")
    Else
    ; For groups that are inherited, the return is the FQDN of the group or user, and the FQDN(s) of the group(s) it
    ; was inherited from, seperated by '|'
    _ArrayDisplay($aUser, "Active Directory Functions - Example 1 - Group names user '" & @UserName & "' is a member of")
    EndIf

    [/autoit][autoit][/autoit][autoit]

    ; Close Connection to the Active Directory
    _AD_Close()

    [/autoit]
  • Die einzige Änderung in der Funktion ist das Escapen der Eingabe.
    Kannst Du bitte mal folgende Zeile auskommentieren?

    [autoit]

    ; $sObject = _AD_FixSpecialChars($sObject, 1) ; the object needs to be unescaped for the LDAP query but the result might be escaped

    [/autoit]
  • ja dann geht es

    der user sah so aus: (distinguishedname über _AD_GetObjectProperties)

    CN=Nachname\, Vorname,OU=XXX,OU=YYY,OU=ZZZ,DC=ort,DC=firma,DC=de

    //edit: ich sehe gerade, dass in dieser Funktion "\," mit ',' ersetzt wird, glaube daran liegt es.
    _AD_RecursiveGetMemberOf benötigt bestimmt "\," :)

    Einmal editiert, zuletzt von GerhardSchr (4. Juni 2013 um 09:43)

  • Ersetz mal die Zeile mit

    [autoit]

    $sAD_Object = StringReplace($sAD_Object, "\/", "/")

    [/autoit]


    Details dazu findest Du hier und den nachfolgenden Einträgen.

  • Danke!

    [autoit]

    $sObject = _AD_FixSpecialChars($sObject, 1) ; the object needs to be unescaped for the LDAP query but the result might be escaped

    [/autoit]


    habe ich auskommentiert....

    nach

    [autoit]

    If StringMid($sObject, 3, 1) <> "=" Then $sObject = _AD_SamAccountNameToFQDN($sObject) ; sAMAccountName provided

    [/autoit]


    habe ich

    [autoit]

    $sObject = StringReplace($sObject, "\/", "/")

    [/autoit]

    eingefügt. (Es war $sObject anstatt $sAD_Object :) )


    so sieht es jetzt aus:

    [autoit]

    ; #FUNCTION# ====================================================================================================================
    ; Name...........: _AD_RecursiveGetMemberOf
    ; Description ...: Takes a group, user or computer and recursively returns a list of groups the object is a member of.
    ; Syntax.........: _AD_RecursiveGetMemberOf($sObject[, $iDepth = 10[, $bListInherited = True[, $bFQDN = True]]])
    ; Parameters ....: $sObject - User, group or computer for which the group membership is to be returned. Can be specified as Fully Qualified Domain Name (FQDN) or sAMAccountName
    ; $iDepth - Optional: Maximum depth of recursion (default = 10)
    ; $bListInherited - Optional: Defines if the function returns the group(s) it was inherited from (default = True)
    ; $bFQDN - Optional: Specifies the attribute to be returned. True = distinguishedName (FQDN), False = SamAccountName (default = True)
    ; Return values .: Success - Returns an one-based one dimensional array of group names (FQDN or sAMAccountName) the user or group is a member of
    ; Failure - "", sets @error to:
    ; |1 - Specified user, group or computer does not exist
    ; Author ........: Jonathan Clelland
    ; Modified.......: water
    ; Remarks .......: This function traverses the groups that the object is immediately a member of while also checking its group membership.
    ; For groups that are inherited, the return is the FQDN or sAMAccountname of the group, user or computer, and the FQDN(s) or sAMAccountname(s) of the group(s) it
    ; was inherited from, seperated by '|'(s) if flag $bListInherited is set to True.
    ;+
    ; If flag $bListInherited is set to False then the group names are sorted and only unique groups are returned.
    ; Related .......: _AD_IsMemberOf, _AD_GetUserGroups, _AD_GetUserPrimaryGroup
    ; Link ..........:
    ; Example .......: Yes
    ; ===============================================================================================================================
    Func _AD_RecursiveGetMemberOf($sObject, $iDepth = 10, $bListInherited = True, $bFQDN = True)

    [/autoit][autoit][/autoit][autoit]

    If _AD_ObjectExists($sObject) = 0 Then Return SetError(1, 0, "")
    If StringMid($sObject, 3, 1) <> "=" Then $sObject = _AD_SamAccountNameToFQDN($sObject) ; sAMAccountName provided

    $sObject = StringReplace($sObject, "\/", "/")

    [/autoit][autoit][/autoit][autoit]

    ;$sObject = _AD_FixSpecialChars($sObject, 1) ; the object needs to be unescaped for the LDAP query but the result might be escaped

    [/autoit][autoit][/autoit][autoit]

    Local $iCount1, $iCount2
    Local $sField = "distinguishedName"
    If Not $bFQDN Then $sField = "samaccountname"
    $__oAD_Command.CommandText = "<LDAP://" & $sAD_HostServer & "/" & $sAD_DNSDomain & ">;(member=" & $sObject & ");" & $sField & ";subtree"
    Local $oRecordSet = $__oAD_Command.Execute
    Local $aGroups[$oRecordSet.RecordCount + 1] = [0]
    If $oRecordSet.RecordCount = 0 Then Return $aGroups
    $oRecordSet.MoveFirst
    $iCount1 = 1
    Local $aTempMemberOf[1]
    Do
    $aGroups[$iCount1] = $oRecordSet.Fields(0).Value
    If $iDepth > 0 Then
    $aTempMemberOf = _AD_RecursiveGetMemberOf($aGroups[$iCount1], $iDepth - 1, $bListInherited, $bFQDN)
    If $bListInherited Then
    For $iCount2 = 1 To $aTempMemberOf[0]
    $aTempMemberOf[$iCount2] &= "|" & $aGroups[$iCount1]
    Next
    EndIf
    _ArrayDelete($aTempMemberOf, 0)
    _ArrayConcatenate($aGroups, $aTempMemberOf)
    EndIf
    $iCount1 += 1
    $oRecordSet.MoveNext
    Until $oRecordSet.EOF
    $oRecordSet.Close
    If $bListInherited = False Then
    _ArraySort($aGroups, 0, 1)
    $aGroups = _ArrayUnique($aGroups, 1, 1)
    EndIf
    $aGroups[0] = UBound($aGroups) - 1
    Return $aGroups

    [/autoit][autoit][/autoit][autoit]

    EndFunc ;==>_AD_RecursiveGetMemberOf

    [/autoit]
  • [autoit]

    $sObject = _AD_FixSpecialChars($sObject, 1, '"\/#+<>;=') ; the object needs to be unescaped (except a comma) for the LDAP query but the result might be escaped

    [/autoit]


    Kannst Du das bitte mal testen. Denn eigentlich muss alles außer Komma unescaped werden.

  • Super. Ist bereits eingebaut.

  • super, lade ich dann mal die neue version :)

    jetzt fehlt nurnoch (meinerseits):
    - _AD_RecursiveGetGroupMembers ohne die Gruppen im Array
    - _AD_IsMemberOf rekusive Prüfung

    Wenn du Zeit hast!

    Danke!

  • Hier ist mal die _AD_IsMemberOf mit Rekursion:

    [autoit]

    ; #FUNCTION# ====================================================================================================================
    ; Name...........: _AD_IsMemberOf
    ; Description ...: Returns 1 if the object (user, group, computer) is an immediate member of the group.
    ; Syntax.........: _AD_IsMemberOf($sGroup[, $sObject = @Username[, $bIncludePrimaryGroup = False[, $bRecursive = False[, $iDepth = 10]]]])
    ; Parameters ....: $sGroup - Group to be checked for membership. Can be specified as sAMAccountName or Fully Qualified Domain Name (FQDN)
    ; $sObject - Optional: Object type (user, group, computer) to check for membership of $sGroup. Can be specified as sAMAccountName or Fully Qualified Domain Name (FQDN) (default = @UserName)
    ; $bIncludePrimaryGroup - Optional: Additionally checks the primary group for object membership (default = False)
    ; $bRecursive - Optional: Recursively check all groups of $sGroup up to the depth defined by $iDepth (default = False)
    ; $iDepth - Optional: Maximum depth of recursion (default = 10)
    ; Return values .: Success - 1, Specified object (user, group, computer) is a member of the specified group
    ; Failure - 0, @error set
    ; |0 - $sObject is not a member of $sGroup
    ; |1 - $sGroup does not exist
    ; |2 - $sObject does not exist
    ; Author ........: Jonathan Clelland
    ; Modified.......: water
    ; Remarks .......: Determines if the object is an immediate member of the group. This function does not verify membership in any nested groups.
    ; Related .......: _AD_GetUserGroups, _AD_GetUserPrimaryGroup, _AD_RecursiveGetMemberOf
    ; Link ..........:
    ; Example .......: Yes
    ; ===============================================================================================================================
    Func _AD_IsMemberOfEx($sGroup, $sObject = @UserName, $bIncludePrimaryGroup = False, $bRecursive = False, $iDepth = 10)

    [/autoit][autoit][/autoit][autoit]

    If _AD_ObjectExists($sGroup) = 0 Then Return SetError(1, 0, 0)
    If _AD_ObjectExists($sObject) = 0 Then Return SetError(2, 0, 0)
    If StringMid($sObject, 3, 1) <> "=" Then $sObject = _AD_SamAccountNameToFQDN($sObject) ; sAMAccountName provided
    If StringMid($sGroup, 3, 1) <> "=" Then $sGroup = _AD_SamAccountNameToFQDN($sGroup) ; sAMAccountName provided
    Local $oGroup = __AD_ObjGet("LDAP://" & $sAD_HostServer & "/" & $sGroup)
    Local $iResult = $oGroup.IsMember("LDAP://" & $sAD_HostServer & "/" & $sObject)
    If $iResult = 0 And $bRecursive = True Then
    For $oMember In $oGroup.Members
    If StringLower($oMember.Class) = 'group' Then
    If $iDepth > 0 Then
    If _AD_IsMemberOfEx($oMember.distinguishedName, $sObject, $bRecursive, $iDepth - 1) Then Return 1
    EndIf
    Else
    If StringLower($oMember.distinguishedName) = $sObject Then Return 1
    EndIf
    Next
    EndIf
    ; Check Primary Group if $sObject isn't a member of the specified group and the flag is set
    If $iResult = 0 And $bIncludePrimaryGroup Then $iResult = (_AD_GetUserPrimaryGroup($sObject) = $sGroup)
    ; Abs is necessary to make it work for AutoIt versions < 3.3.2.0 with bug #1068
    Return Abs($iResult)

    [/autoit][autoit][/autoit][autoit]

    EndFunc ;==>_AD_IsMemberOfEx

    [/autoit]
  • Hallo Water!

    sieht gut aus!
    Bei mir hat sie funktioniert :)

    Danke für deine Zeit!

    Willst du die dann mit in die AD.au3 packen und ersetzt dann die "normale" _Ad_IsMemberOf?
    Alte Script sollten ja noch laufen, da die beiden letzten Optionen optional sind...

    Wiedermal super arbeit!

    Gruß
    GerhardSchr

  • Richtig. Die nächste Version der AD UDF sollte alle Änderungen inkludiert haben.

  • Version 1.4.0.0 ist freigegeben.

    Bitte ausgiebig testen vor Übernahme in die Produktion!

    Für download siehe bitte den Link in meiner Signatur.