![]() |
![]() | ![]() | ![]() | ![]() | ![]() | ![]() | ![]() |
| Welcome to Windows Vista Forums. Our forum is dedicated to helping you find solutions with any problems, errors or issues you are experiencing with Windows Vista. The Vista forum also covers news and updates and has an extensive Windows Vista tutorial section that covers a wide range of tips and tricks. |
| |||||||
![]() |
| |
| | #1 (permalink) |
| | Return Group Members I have written a script to return all members of a group but it will only return users. I would like it to return users and nested groups. Anyone know how this is done? Here is a code snippet: objGroup1 = InputBox("Enter the first group name:", "Group Name #1") Set objGroup = GetObject("WinNT://" & objNetwork.UserDomain & "/" & objGroup1 & ",group") objGroup.GetInfo For Each objUser in objGroup.Members wscript.echo objUser.Name Next |
My System Specs![]() |
| | #2 (permalink) |
| | Re: Return Group Members Brian Cahill wrote: Quote: >I have written a script to return all members of a group but it will > only return users. I would like it to return users and nested > groups. Anyone know how this is done? Here is a code snippet: > > objGroup1 = InputBox("Enter the first group name:", "Group Name #1") > Set objGroup = GetObject("WinNT://" & objNetwork.UserDomain & "/" & > objGroup1 & ",group") > objGroup.GetInfo > > For Each objUser in objGroup.Members > wscript.echo objUser.Name > Next the member is "Group", recusively call the subroutine to enmumerate the members. However, the WinNT provider is blind to global and univerisal security groups (they were not allowed in NT domains). You need to use the LDAP provider. With the LDAP provider you need the full Distinguished Name (DN) of the group. An example could be: ============ strGroup = InputBox("Enter Distinguished Name of group") Set objGroup = GetObject("LDAP://" & strGroup) Call EnumMembers(objGroup) Sub EnumMembers(objGroup) For Each objMember In objGroup.Members Wscript.Echo objMember.sAMAccountName If (LCase(objGroup.Class) = "group") Then Call EnumMembers(objMember) End If Next End Sub ========= You could use objGroup.distinguishedName to output the DN of the members instead of the NT names (sAMAccountName). If you want to have users enter the NT names of the groups (the NetBIOS or "pre-Windows 2000" names), you can use the NameTranslate object to convert to the DN required by the LDAP provider. See this link for details: http://www.rlmueller.net/NameTranslateFAQ.htm Also, the example I gave above will get into an infinite loop if there are circular nested groups. This is unlikely, but can happen. The example below prevents this by keeping track of the groups in a dictionary object, so the subroutine recognizes when it has seen a group before: ============ Option Explicit Dim objRootDSE, strDNSDomain, objTrans, strNetBIOSDomain Dim strGroup, strGroupDN, objGroup, objGroupList ' Constants for the NameTranslate object. Const ADS_NAME_INITTYPE_GC = 3 Const ADS_NAME_TYPE_NT4 = 3 Const ADS_NAME_TYPE_1779 = 1 ' Determine DNS name of domain from RootDSE. Set objRootDSE = GetObject("LDAP://RootDSE") strDNSDomain = objRootDSE.Get("defaultNamingContext") ' Use the NameTranslate object to find the NetBIOS domain name from the ' DNS domain name. Set objTrans = CreateObject("NameTranslate") objTrans.Init ADS_NAME_INITTYPE_GC, "" objTrans.Set ADS_NAME_TYPE_1779, strDNSDomain strNetBIOSDomain = objTrans.Get(ADS_NAME_TYPE_NT4) ' Remove trailing backslash. strNetBIOSDomain = Left(strNetBIOSDomain, Len(strNetBIOSDomain) - 1) ' Ask for group name (pre-Windows 2000). strGroup = InputBox("Enter group name") ' Specify the NT format of the name. objTrans.Set ADS_NAME_TYPE_NT4, strNetBIOSDomain & "\" & strGroup ' Retrieve DN. strGroupDN = objTrans.Get(ADS_NAME_TYPE_1779) ' Bind to group object. Set objGroup = GetObject("LDAP://" & strGroupDN) ' Create dictionary object of groups. Set objGroupList = CreateObject("Scripting.Dictionary") objGroupList.CompareMode = vbTextCompare ' Enumerate members of the group. Call EnumMembers(objGroup) Sub EnumMembers(objGroup) ' Recursive subroutine to enumerate group members. ' Requires that objGroupList be set in the main program ' so it has global scope. Dim objMember For Each objMember In objGroup.Members Wscript.Echo objMember.sAMAccountName If (LCase(objGroup.Class) = "group") Then ' Check if group seen before. If (objGroupList.Exists(objGroup.distinguishedName) = False) Then ' Add this group to the dictionary object. objGroupList(objGroup.distinguishedName) = True ' Enumerate members of nested group. Call EnumMembers(objMember) End If End If Next End Sub ====== I didn't test the above, but you get the idea. -- Richard Mueller MVP Directory Services Hilltop Lab - http://www.rlmueller.net -- |
My System Specs![]() |
| | #3 (permalink) |
| | Re: Return Group Members On Jul 24, 11:01*am, "Richard Mueller [MVP]" <rlmueller- nos...@xxxxxx> wrote: Quote: > Brian Cahill wrote: Quote: > >I have written a script to return all members of a group but it will > > only return users. *I would like it to return users and nested > > groups. *Anyone know how this is done? *Here is a code snippet: Quote: > > objGroup1 = InputBox("Enter the first group name:", "Group Name #1") > > Set objGroup = GetObject("WinNT://" & objNetwork.UserDomain & "/" & > > objGroup1 & ",group") > > objGroup.GetInfo Quote: > > For Each objUser in objGroup.Members > > wscript.echo objUser.Name > > Next > A recursive subroutine is the most common method. If the .Class property of > the member is "Group", recusively call the subroutine to enmumerate the > members. However, the WinNT provider is blind to global and univerisal > security groups (they were not allowed in NT domains). You need to use the > LDAP provider. With the LDAP provider you need the full Distinguished Name > (DN) of the group. An example could be: > ============ > strGroup = InputBox("Enter Distinguished Name of group") > > Set objGroup = GetObject("LDAP://" & strGroup) > > Call EnumMembers(objGroup) > > Sub EnumMembers(objGroup) > * * For Each objMember In objGroup.Members > * * * * Wscript.Echo objMember.sAMAccountName > * * * * If (LCase(objGroup.Class) = "group") Then > * * * * * * Call EnumMembers(objMember) > * * * * End If > * * Next > End Sub > ========= > You could use objGroup.distinguishedName to output the DN of the members > instead of the NT names (sAMAccountName). If you want to have users enter > the NT names of the groups (the NetBIOS or "pre-Windows 2000" names), you > can use the NameTranslate object to convert to the DN required by the LDAP > provider. See this link for details: > > http://www.rlmueller.net/NameTranslateFAQ.htm > > Also, the example I gave above will get into an infinite loop if there are > circular nested groups. This is unlikely, but can happen. The example below > prevents this by keeping track of the groups in a dictionary object, so the > subroutine recognizes when it has seen a group before: > ============ > Option Explicit > Dim objRootDSE, strDNSDomain, objTrans, strNetBIOSDomain > Dim strGroup, strGroupDN, objGroup, objGroupList > > ' Constants for the NameTranslate object. > Const ADS_NAME_INITTYPE_GC = 3 > Const ADS_NAME_TYPE_NT4 = 3 > Const ADS_NAME_TYPE_1779 = 1 > > ' Determine DNS name of domain from RootDSE. > Set objRootDSE = GetObject("LDAP://RootDSE") > strDNSDomain = objRootDSE.Get("defaultNamingContext") > > ' Use the NameTranslate object to find the NetBIOS domain name from the > ' DNS domain name. > Set objTrans = CreateObject("NameTranslate") > objTrans.Init ADS_NAME_INITTYPE_GC, "" > objTrans.Set ADS_NAME_TYPE_1779, strDNSDomain > strNetBIOSDomain = objTrans.Get(ADS_NAME_TYPE_NT4) > ' Remove trailing backslash. > strNetBIOSDomain = Left(strNetBIOSDomain, Len(strNetBIOSDomain) - 1) > > ' Ask for group name (pre-Windows 2000). > strGroup = InputBox("Enter group name") > > ' Specify the NT format of the name. > objTrans.Set ADS_NAME_TYPE_NT4, strNetBIOSDomain & "\" & strGroup > ' Retrieve DN. > strGroupDN = objTrans.Get(ADS_NAME_TYPE_1779) > > ' Bind to group object. > Set objGroup = GetObject("LDAP://" & strGroupDN) > > ' Create dictionary object of groups. > Set objGroupList = CreateObject("Scripting.Dictionary") > objGroupList.CompareMode = vbTextCompare > > ' Enumerate members of the group. > Call EnumMembers(objGroup) > > Sub EnumMembers(objGroup) > * * ' Recursive subroutine to enumerate group members. > * * ' Requires that objGroupList be set in the main program > * * ' so it has global scope. > * * Dim objMember > > * * For Each objMember In objGroup.Members > * * * * Wscript.Echo objMember.sAMAccountName > * * * * If (LCase(objGroup.Class) = "group") Then > * * * * * * ' Check if group seen before. > * * * * * * If (objGroupList.Exists(objGroup.distinguishedName) = False) > Then > * * * * * * * * ' Add this group to the dictionary object.. > * * * * * * * * objGroupList(objGroup.distinguishedName) = True > * * * * * * * * ' Enumerate members of nested group. > * * * * * * * * Call EnumMembers(objMember) > * * * * * * End If > * * * * End If > * * Next > End Sub > ====== > I didn't test the above, but you get the idea. > > -- > Richard Mueller > MVP Directory Services > Hilltop Lab -http://www.rlmueller.net > -- what I ended up with: Set objFSO = CreateObject("Scripting.FileSystemObject") Set objNetwork = WScript.CreateObject("WScript.Network") Set objAdRootDSE = GetObject("LDAP://RootDSE") Set objRS = CreateObject("adodb.recordset") varConfigNC = objAdRootDSE.Get("defaultNamingContext") strConnString = "Provider=ADsDSOObject" ' Setup the container that will contain all users in objGroup1 by an LDAP query Do err.number = 0 objGroup1 = InputBox("Enter the first group name:", "Group Name #1") strSQL = "SELECT * FROM 'LDAP://" & varConfigNC & "' WHERE objectCategory= 'Group' and SAMAccountName = '" & objGroup1 & "'" objRS.Open strSQL, strConnstring Set objGroup = GetObject(objRS.Fields.Item(0)) objRS.Close If err.number <> 0 Then errResponse = MsgBox("Please check the group name and try again: " & err.description, 53, "Error Message") If errResponse = 2 Then WScript.quit End If End If Loop Until err.number = 0 For Each objUser in objGroup.Member wscript.echo (mid(objUser.Name,4)) Next |
My System Specs![]() |
| | #4 (permalink) |
| | Re: Return Group Members "Brian Cahill" <brianccahill@xxxxxx> wrote in message news:ef8e171a-09c7-4c1f-85e5-cc35e5ac05da@xxxxxx Quote: >Snip... what I ended up with: Set objFSO = CreateObject("Scripting.FileSystemObject") Set objNetwork = WScript.CreateObject("WScript.Network") Set objAdRootDSE = GetObject("LDAP://RootDSE") Set objRS = CreateObject("adodb.recordset") varConfigNC = objAdRootDSE.Get("defaultNamingContext") strConnString = "Provider=ADsDSOObject" ' Setup the container that will contain all users in objGroup1 by an LDAP query Do err.number = 0 objGroup1 = InputBox("Enter the first group name:", "Group Name #1") strSQL = "SELECT * FROM 'LDAP://" & varConfigNC & "' WHERE objectCategory= 'Group' and SAMAccountName = '" & objGroup1 & "'" objRS.Open strSQL, strConnstring Set objGroup = GetObject(objRS.Fields.Item(0)) objRS.Close If err.number <> 0 Then errResponse = MsgBox("Please check the group name and try again: " & err.description, 53, "Error Message") If errResponse = 2 Then WScript.quit End If End If Loop Until err.number = 0 For Each objUser in objGroup.Member wscript.echo (mid(objUser.Name,4)) Next ---------- You can use ADO in this way to retrieve DN of the group. Your code assumes that the DN is the first field in the recordset. I would need to check if that is true. If your code works, I suppose it is. I would only add that the NameTranslate object is more efficient, but that doesn't matter much here. Also, if you want to display the Common Name (without the "cn=" prefix), you can use: Wscript.Echo objUser.cn And, if you want the NT name (your objGroup1 is the NT name of the group, for example), use: Wscript.Echo objUser.sAMAccountName The cn and sAMAccountName attributes often have the same value, but it is not necessary. The sAMAccountName attribute (pre-Windows 2000 logon name) uniquely identifies the member (user or group), while cn technically does not. There can be several objects with the same Common Name, as long as they are in different OU's. -- Richard Mueller MVP Directory Services Hilltop Lab - http://www.rlmueller.net -- |
My System Specs![]() |
![]() |
| Thread Tools | |
| |
Similar Threads | ||||
| Thread | Forum | |||
| Get members of a group | PowerShell | |||
| Remove members of the group. Members are from different domains | PowerShell | |||
| Members of Group | PowerShell | |||
| Return of object with synthetic members from functions | PowerShell | |||
| Identifying group members | Vista mail | |||