Re: List Members of a Group (with user input)



You can either pass the group name to the script as a parameter using the
Wscript.Arguments collection, or have the program prompt for the group name
using the InputBox function.

You can retrieve the DNS name of the domain from the RootDSE object. For
example:
=======
' Retrieve DNS domain name from RootDSE.
Set objRootDSE = GetObject("LDAP://RootDSE";)
strDNSDomain = objRootDSE.Get("defaultNamingContext")
=======
Most likely, you will want to use the NetBIOS name of the group. Most likely
this will match the Common Name of the group (the value of the cn
attribute), but it may not. Really, you should use the NameTranslate object
to convert the NetBIOS name to the Distinguished Name. This also makes it
unnecessary to know the OU or container the group is in.

Next, the example you posted will raise an error if the member attribute of
the group has no entries (is empty). The error is raised by the GetEx
method. If you use GetEx, the only solution is to trap the possible error.
For example:
===========
On Error Resume Next
arrMembers = objGroup.GetEx("member")
If (Err.Number <> 0) Then
On Error GoTo 0
Wscript.Echo "No members"
Else
On Error GoTo 0
For Each strMember In arrMembers
Wscript.Echo strMember
Next
End If
=========
However, since your example uses the Distinguished Name of each group to
bind to the group object, to retrieve sAMAccountName and the class of the
member, it makes more sense to get an object reference directly. The Members
method of the group object does this.

Finally, the recursive subroutine, while it does a good job of revealing
membership due to group nesting, will get caught in an infinite loop if you
have any instances of circular group nesting. I use a dictionary object to
track groups and prevent this. So, I would suggest something similar to the
example below. You might want to improve the format of the output written to
the file:
============
Option Explicit

Dim objRootDSE, objTrans, strNetBIOSDomain, strGroup
Dim strGroupDN, strDNSDomain, objGroup
Dim objMember, objList
Dim objFSO, objFile, strFile

' Constants for the NameTranslate object.
Const ADS_NAME_INITTYPE_GC = 3
Const ADS_NAME_TYPE_NT4 = 3
Const ADS_NAME_TYPE_1179 = 1

' Prompt for group name.
strGroup = InputBox("Enter NetBIOS name of group", "List Group Members")

' Specify the name of the text file.
' You could also prompt for this, or use the wshShell object
' to retrieve the path to the desktop and place the file there,
' as in your example.
strFile = "c:\Scripts\GroupList.txt"

' Open the text file.
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objFile = objFSO.CreateTextFile(strFile, True)

' Setup dictionary object of groups.
Set objList = CreateObject("Scripting.Dictionary")
objList.CompareMode = vbTextCompare

' Determine DNS domain name from RootDSE object.
Set objRootDSE = GetObject("LDAP://RootDSE";)
strDNSDomain = objRootDSE.Get("DefaultNamingContext")

' Use the NameTranslate object to convert the DNS name
' of the domain to the NetBIOS name.
Set objTrans = CreateObject("NameTranslate")

' Initialize NameTranslate by locating the Global Catalog.
objTrans.Init ADS_NAME_INITTYPE_GC, ""

' Use the Set method to specify the DNS name of the domain.
objTrans.Set ADS_NAME_TYPE_1179, strDNSDomain

' Use the Get method to retrieve the NetBIOS name.
strNetBIOSDomain = objTrans.Get(ADS_NAME_TYPE_NT4)

' Remove trailing backslash.
strNetBIOSDomain = Left(strNetBIOSDomain, Len(strNetBIOSDomain) - 1)

' Use the NameTranslate object to convert the NetBIOS name
' of the group to the Distinguished Name.
On Error Resume Next
objTrans.Set ADS_NAME_TYPE_NT4, strNetBIOSDomain & "\" & strGroup
If (Err.Number <> 0) Then
On Error GoTo 0
Wscript.Echo "Group not found. Program will abort."
Wscript.Quit
End If
On Error GoTo 0
strGroupDN = objTrans.Get(ADS_NAME_TYPE_1179)

' Bind to the group object.
Set objGroup = GetObject("LDAP://"; & strGroupDN)

' Add the NetBIOS name of this group to the dictionary object.
objList.Add objGroup.sAMAccountName, True

' Enumerate members of group.
Call EnumMembers(objGroup, "")

' Clean up.
objFile.Close
Wscript.Echo "Done"

Sub EnumMembers(objGroup, strOffset)
' Recursive subroutine to enumerate direct members of
' a group. If any members are groups, this sub calls itself.
' strOffset serves to indent nested groups in the output.

For Each objMember In objGroup.Members
objFile.WriteLine strOffset & objMember.sAMAccountName _
& " - " & objMember.Class _
& " - " & objMember.distinguishedName
If (objMember.Class = "group") Then
' Make sure this group has not been seen before,
' to avoid infinite loop if group nesting is circular.
If (objList.Exists(objMember.sAMAccountName) = False) Then
' Add this group to dictionary object.
objList.Add objMember.sAMAccountName, True
Call EnumMembers(objMember, strOffset & "--")
End If
End If
Next
End Sub

--
Richard
Microsoft MVP Scripting and ADSI
Hilltop Lab web site - http://www.rlmueller.net
--

<stewart@xxxxxxxxxxxxxxxxxx> wrote in message
news:1168878091.776722.181810@xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
I'm an auditor and frequenly need to list members in 1 particular AD
Group.
I have found many scripts that show how to list group memberships, but
I would like one that does not require editing of the script each time.
Can you create a script that asks for the domain and the group you
want to list and then sends the membership to a file?

I found this script that does close to this, but requires you to edit
the LDAP path.

On Error Resume Next
Dim UserCount, gga, CNgga
gga= inputbox("Which global group?") 'Get the requested Global Group
CNgga = "CN="&gga 'Change the group to a CN request
Set objShell = Wscript.CreateObject("Wscript.Shell")
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objOU = GetObject("LDAP://OU=users,OU=group,DC=xxx,DC=net";) 'input
the full LDAP path to your group's OU here
objDesktop = objShell.SpecialFolders("Desktop") 'Folder for the output
file
For Each Group In objOU
If InStr(Group.Name, CNgga) Then 'input the name of the AD group to
query here
Set objFile = objFSO.CreateTextFile(objDesktop & "\AD\Members of " &
Group.Name & ".txt", 2) 'Create the file
set UserCount = 0
objFile.WriteLine Group.Name
objFile.WriteLine "=================================="

Set objGroup = GetObject ("LDAP://"; & Group.Name & ",OU=Application
Management Groups,OU=Security Groups,DC=xxxx,DC=net") 'input the full
LDAP path to your group's OU here
objGroup.GetInfo
arrMemberOf = objGroup.GetEx("member")
For Each strMember In arrMemberOf
Set objUser = GetObject("LDAP://"; & strMember)
Select Case objUser.class
Case "user"
objFile.WriteLine " " & objUser.samaccountname &" - " &
objUser.Class
UserCount = UserCount + 1
Case "group"
'objFile.WriteLine objUser.samaccountname &" - " & objUser.Class &"
- " & objUser.distinguishedName
enumGroupMembers(objUser.distinguishedName)
End Select
Next
objFile.WriteLine "Aantal gebruikers: " & UserCount 'Gives a total
count of all the users.
objFile.Close
End If
Next
MsgBox "Completed script.",64,"Informational"
Sub enumGroupMembers(sObjDN)
Dim oContainer, obj, sDN
Set oContainer=GetObject ("LDAP://"; & sObjDN)

For each obj in oContainer.members
Select Case LCase(obj.Class)
Case "user" , "contact"
objFile.WriteLine " " & obj.sAMAccountName &" - " & obj.Class
UserCount = UserCount + 1
Case "group"
'objFile.WriteLine obj.sAMAccountName &" - " & obj.Class &" - " &
objUser.distinguishedName
EnumGroupMembers obj.distinguishedName
End Select
Next
End Sub



.



Relevant Pages

  • List Members of a Group (with user input)
    ... I'm an auditor and frequenly need to list members in 1 particular AD ... I would like one that does not require editing of the script each time. ... Dim UserCount, gga, CNgga ... the full LDAP path to your group's OU here ...
    (microsoft.public.scripting.vbscript)
  • Re: Cleaning up nested groups in Active directory
    ... that have members that are groups. ... we would have circular nested groups. ... the script made some users members of groups repeatedly. ... Dim strBase, strFilter, strAttributes, strQuery, adoRecordset ...
    (microsoft.public.windows.server.scripting)
  • Re: Empty group
    ... > I have a script that I want to run only on AD groups that have members. ... Dim objRootDSE, strDNSDomain, objCommand, objConnection ... Dim strBase, strFilter, strAttributes, strQuery, objRecordSet ... In most cases, the above script will not return the group "Domain Users", ...
    (microsoft.public.windows.server.scripting)
  • Re: Another Scripting Newbie - admin check
    ... members, members due to group nesting of local groups, members of domain ... Dim objRootDSE, strDNSDomain, adoConnection, adoCommand ... ' Bind to the local Administrators group on each computer ... For Each objMember In objLocalGroup.Members ...
    (microsoft.public.windows.server.scripting)
  • RE: Making a collection of EntireRows for copying and then deletin
    ... Dim rngToSearch As Range ... Set rngFoundAll = Union ... ' The rest of the code finds the correct start cell in the archive file; ... I have a small data base (30-40 members of a local club). ...
    (microsoft.public.excel.programming)