Aphotic Posted April 13, 2016 Share Posted April 13, 2016 (edited) Hey Guys, Just wanted to share a snippet I made in case anyone can use it. I needed to list of all User ID's and their respective display names for an MLIST, searched recursively. The recursive function in he UDF returns either only the FQDN or SAM-ID. It also will do a query against all the returned user IDs for if they have any members, and returns group names in the result. It returns 54 members, (4 groups to query). I modified it to return the ID in the first column and the displayname in the second, omitted returning group names, and only querying for members if the ID is a GROUP_OBJECT. (The last part cut the runtime in half, 1.5 to 0.8 seconds, which on a network laggy day could be a much bigger difference as it went from 58 queries to 4.) My use case for this is that I need the IDs to write to a Sharepoint list but need the names so users can select a person via the name in the GUI. expandcollapse popup; #FUNCTION# ==================================================================================================================== ; Name...........: _AD_RecursiveGetGroupMembers ; Description ...: Takes a group and recursively returns a list of groups and members of the group. ; Syntax.........: _AD_RecursiveGetGroupMembers($sGroup[, $iDepth = 10[, $bListInherited = True[, $bFQDN = True]]]) ; Parameters ....: $sGroup - Group for which the members should 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 it is a member of (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 or member names (FQDN or sAMAccountName) ; Failure - "", sets @error to: ; |1 - Specified group does not exist ; Author ........: Jonathan Clelland ; Modified.......: water ; Remarks .......: This function traverses the groups in the specified group until the maximum depth is reached. ; if $bListInherited = True the return is the FQDN or sAMAccountname of the group or member and the FQDN(s) or sAMAccountname(s) of the group it ; is a member of, seperated by '|'(s) if flag $bListInherited is set to True. ;+ ; If flag $bListInherited is set to False then the group/member names are sorted and only unique entries are returned. ; Related .......: _AD_GetGroupMembers ; Link ..........: ; Example .......: Yes ; =============================================================================================================================== Func _AD_RecursiveGetGroupMembers($sGroup, $iDepth = 10, $bListInherited = True, $bFQDN = True) If _AD_ObjectExists($sGroup) = 0 Then Return SetError(1, 0, "") If StringMid($sGroup, 3, 1) <> "=" Then $sGroup = _AD_SamAccountNameToFQDN($sGroup) Local $iCount1, $iCount2 Local $sField = "distinguishedName" If Not $bFQDN Then $sField = "samaccountname" $__oAD_Command.CommandText = "<LDAP://" & $sAD_HostServer & "/" & $sAD_DNSDomain & ">;(memberof=" & $sGroup & ");" & $sField & ";subtree" Local $oRecordSet = $__oAD_Command.Execute Local $aMembers[$oRecordSet.RecordCount + 1] = [0] If $oRecordSet.RecordCount = 0 Then Return $aMembers $oRecordSet.MoveFirst $iCount1 = 1 Local $aTempMembers[1] Do $aMembers[$iCount1] = $oRecordSet.Fields(0).Value If $iDepth > 0 Then $aTempMembers = _AD_RecursiveGetGroupMembers($aMembers[$iCount1], $iDepth - 1, $bListInherited, $bFQDN) If $bListInherited Then For $iCount2 = 1 To $aTempMembers[0] $aTempMembers[$iCount2] &= "|" & $aMembers[$iCount1] Next EndIf _ArrayDelete($aTempMembers, 0) _ArrayConcatenate($aMembers, $aTempMembers) EndIf $iCount1 += 1 $oRecordSet.MoveNext Until $oRecordSet.EOF $oRecordSet.Close If $bListInherited = False Then _ArraySort($aMembers, 0, 1) $aMembers = _ArrayUnique($aMembers, 0, 1) EndIf $aMembers[0] = UBound($aMembers) - 1 Return $aMembers EndFunc ;==>_AD_RecursiveGetGroupMembers ;MODIFIED FUNCTION ABOVE TO INCLUDE DISPLAY NAME IN A SECOND COLUMN Func _AD_RecursiveGetGroupMembersDN($sGroup, $iDepth = 10) If _AD_ObjectExists($sGroup) = 0 Then Return SetError(1, 0, "") If StringMid($sGroup, 3, 1) <> "=" Then $sGroup = _AD_SamAccountNameToFQDN($sGroup) Local $iCount1, $iCount2 Local $sField = "samaccountname,displayname,sAMAccountType" $__oAD_Command.CommandText = "<LDAP://" & $sAD_HostServer & "/" & $sAD_DNSDomain & ">;(memberof=" & $sGroup & ");" & $sField & ";subtree" Local $oRecordSet = $__oAD_Command.Execute Local $aMembers[$oRecordSet.RecordCount + 1][2] $aMembers[0][0] = 0 If $oRecordSet.RecordCount = 0 Then Return $aMembers $oRecordSet.MoveFirst $iCount1 = 1 Local $aTempMembers[1] Do $aMembers[$iCount1][0] = $oRecordSet.Fields(0).Value $aMembers[$iCount1][1] = $oRecordSet.Fields(1).Value If $oRecordSet.Fields(2).Value = 268435456 Then If $iDepth > 0 Then $aTempMembers = _AD_RecursiveGetGroupMembersDN($aMembers[$iCount1][0], $iDepth - 1) _ArrayDelete($aTempMembers, 0) _ArrayDelete($aMembers, $iCount1) _ArrayConcatenate($aMembers, $aTempMembers) EndIf Else $iCount1 += 1 EndIf $oRecordSet.MoveNext Until $oRecordSet.EOF $oRecordSet.Close _ArraySort($aMembers, 0, 1) $aMembers[0][0] = UBound($aMembers) - 1 Return $aMembers EndFunc ;==>_AD_RecursiveGetGroupMembersDN Edited April 13, 2016 by Aphotic GuyFromNJo and boomingranny 2 Link to comment Share on other sites More sharing options...
Recommended Posts
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 accountSign in
Already have an account? Sign in here.
Sign In Now