Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations biv343 on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Enumerating Group Members

Status
Not open for further replies.

acl03

MIS
Jun 13, 2005
1,077
US
I am using a script i found (I think may be marcdmac's, not sure) to enumerate specific groups. Problem is, it only lists users, and if there is a nested group B inside group A, i want the listing of A to show all of it's users as well as listing B.

Here's the code I'm using, and i see it does a search by email. Is there an easy way to search a group for groups, and then search the group for users?



Code:
Dim sResultText,Grps,MemberList
Dim oRootDSE, oConnection, oCommand, oRecordSet
Set oRootDSE = GetObject("LDAP://rootDSE")
Set oConnection = CreateObject("ADODB.Connection")
oConnection.Open "Provider=ADsDSOObject;"
Set objCommand = CreateObject("ADODB.Command")
objCommand.ActiveConnection = oConnection

ldstring = "<LDAP://" & oRootDSE.get("defaultNamingContext") & ">;"
objCommand.CommandText=ldstring & "(objectClass=group);name,SamAccountName"
Set oRecordSet = objCommand.Execute()
Do While Not oRecordSet.EOF
   
    'WScript.Echo oRecordSet.Fields("samAccountName") & vbCrLf
    
    gn = oRecordSet.Fields("samAccountName")
    		  sResultText = sResultText & oRecordSet.Fields("samAccountName") & vbCrLf
    		  MemberList=RetrieveUsers(dom,oRecordSet.Fields("samAccountName"))
    		  sResultText = sResultText & memberlist & vbCrLf & "-------------------------------------" & vbCrLf
    oRecordSet.MoveNext
Loop


filespec = ".\DomainGroupUsers.txt"
Set fso = CreateObject("Scripting.FileSystemObject")
If (fso.FileExists(filespec)) Then
	fso.DeleteFile(filespec)
End if
Set ts = fso.CreateTextFile (filespec, ForWriting)

ts.write sResultText

MsgBox "Done"


'*****************************************************************************************
'*****************************************************************************************
Function RetrieveUsers(domainName,grpName)


Dim dom
dim grp
dim GrpObj
dim mbrlist
dim mbr

'-----------------------------------------------------------------------------------------
' *** Enumerate Group Members ***
'-------------------------------------------------------------------------------

grp = grpName

Set objDomain = getObject("LDAP://rootDse")
domainName = objDomain.Get("dnsHostName")
' Build the ADSI query and retrieve the group object
Set GrpObj = GetObject("WinNT://" & domainName & "/" & grp & ",group")

' Loop through the group membership and build a string containing the names
for each mbr in GrpObj.Members
   On error resume next
   mbremail = SearchEmail(mbr.name)  
   If Err Then
       mbrlist = mbrlist & vbTab & mbr.name & vbCrLf
   Else
   'if you don't want the email addresses, then copy the line 2 up to below
       'mbrlist = mbrlist & mbr.name & vbCrLf
       mbrlist = mbrlist & vbTab & mbr.name & vbTab & vbTab & mbremail+ vbCrLf
   End If
Next

'The next line returns mbrlist back up to the main body
RetrieveUsers=mbrlist

End Function

Public Function SearchEmail(ByVal vSAN)
    ' Function:     SearchDistinguishedName
    ' Description:  Searches the DistinguishedName for a given SamAccountName
    ' Parameters:   ByVal vSAN - The SamAccountName to search
    ' Returns:      The DistinguishedName Name
    Dim oRootDSE, oConnection, oCommand, oRecordSet

    Set oRootDSE = GetObject("LDAP://rootDSE")
    Set oConnection = CreateObject("ADODB.Connection")
    oConnection.Open "Provider=ADsDSOObject;"
    Set oCommand = CreateObject("ADODB.Command")
    oCommand.ActiveConnection = oConnection
    oCommand.CommandText = "<LDAP://" & oRootDSE.get("defaultNamingContext") & _
        ">;(&(objectCategory=User)(samAccountName=" & vSAN & "));name;subtree"
    Set oRecordSet = oCommand.Execute
    On Error Resume Next
    SearchEmail = oRecordSet.Fields("name")
    On Error GoTo 0
    oConnection.Close
    Set oRecordSet = Nothing
    Set oCommand = Nothing
    Set oConnection = Nothing
    Set oRootDSE = Nothing
End Function



Thanks,
Andrew
 
Here is a recursive member search I came up with. Replace "Group1" with the name of the group you wish to list users for.

Code:
'==========================================================================
'
' NAME: RecursiveGroupMemberSearch.vbs
'
' AUTHOR: Mark D. MacLachlan , The Spider's Parlor
' URL: [URL unfurl="true"]http://www.thespidersparlor.com[/URL]
' DATE  : 3/22/2007
' COPYRIGHT (c) 2007 All Rights Reserved
'
' COMMENT: 
'
'    THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
'    ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED To
'    THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
'    PARTICULAR PURPOSE.
'
'    IN NO EVENT SHALL THE SPIDER'S PARLOR AND/OR ITS RESPECTIVE SUPPLIERS 
'    BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY
'    DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
'    WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
'    ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
'    OF THIS CODE OR INFORMATION.
'
'==========================================================================


gDN = SearchGroup("Group1")

GetMembers(gDN)
Function GetMembers(gDN)
	Set objGroup = GetObject("LDAP://" & gDN)
	objGroup.GetInfo
	arrMemberOf = objGroup.GetEx("member")
	
	For Each strMember in arrMemberOf
		Set objMember = GetObject("LDAP://" & strMember)
		ObjDisp = objMember.Name
		oDL = Len(ObjDisp) - 3
		ObjDisp = Right(ObjDisp,oDL)
		ObjCatArray = Split(objMember.objectCategory,",")
		oType = ObjCatArray(0)
		oTL = Len(oType) - 3
		oType = Right(oType,oTL)
	    WScript.Echo "Member:" & ObjDisp & Space(20-Len(ObjDIsp)) &" Type:" & oType
	    If oType = "Group" Then
	    	GetMembers(strMember)
	    End If
	    Set objMember = Nothing
	Next
End Function

Public Function SearchGroup(ByVal vSAN)
    Dim oRootDSE, oConnection, oCommand, oRecordSet
    Set oRootDSE = GetObject("LDAP://rootDSE")
    Set oConnection = CreateObject("ADODB.Connection")
    oConnection.Open "Provider=ADsDSOObject;"
    Set oCommand = CreateObject("ADODB.Command")
    oCommand.ActiveConnection = oConnection
    oCommand.CommandText = "<LDAP://" & oRootDSE.get("defaultNamingContext") & _
        ">;(&(objectCategory=Group)(samAccountName=" & vSAN & "));distinguishedName;subtree"
    Set oRecordSet = oCommand.Execute
    On Error Resume Next
    SearchGroup = oRecordSet.Fields("distinguishedName")
    On Error GoTo 0
    oConnection.Close
    Set oRecordSet = Nothing
    Set oCommand = Nothing
    Set oConnection = Nothing
    Set oRootDSE = Nothing
End Function

I hope you find this post helpful.

Regards,

Mark

Check out my scripting solutions at
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top