Werbung: SecurityConsole.de verwaltet Ihre Computer mit Security Essentails aus der Cloud!
30 Tage kostenfrei testen und 20% Rabatt für Ihre Bestellung mit Promocode: WBF2685582
(Promocode gültig bis 31.12.2011)

Group:  English: Windows Server » microsoft.public.windows.server.scripting
Thread: Enumerate members of all groups within a specific OU

HTVi
TV Discussion Newsgroups

Enumerate members of all groups within a specific OU
IG 6/4/2007 3:07:02 PM
I can find several scripts to enumerate members of a specific group, but
nothing to parse all groups in an OU and output members of each group.

Ideally, I would like to output group name, group description and (nested)
group members to a .csv file (with each group as a column).

My first attempts used dsquery & dsget but I could only get either a list of
groups OR a list of members. Using vbscript, I can bind to LDAP successfully
but then it falls apart probably because I'm cutting & pasting from different
scripts.

Any advice would be appreciated!
--
IG
Re: Enumerate members of all groups within a specific OU
"Richard Mueller [MVP]" <rlmueller-nospam[ at ]ameritech.nospam.net> 6/4/2007 6:01:00 PM
IG wrote:

[Quoted Text]
>I can find several scripts to enumerate members of a specific group, but
> nothing to parse all groups in an OU and output members of each group.
>
> Ideally, I would like to output group name, group description and (nested)
> group members to a .csv file (with each group as a column).
>
> My first attempts used dsquery & dsget but I could only get either a list
> of
> groups OR a list of members. Using vbscript, I can bind to LDAP
> successfully
> but then it falls apart probably because I'm cutting & pasting from
> different
> scripts.

Here is a VBScript program that uses a recursive subroutine to enumerate all
the groups in an OU and any child OU's. For each group, another recursive
subroutine enumerates all members. If any members are groups, the sub is
called recursively. A dictionary object is used to prevent enumeration of
duplicate groups (and prevent an infinite loop if any group nesting is
circular).
============
Option Explicit

Dim objMemberList, strOU, objOU

' Dictionary object to track groups.
Set objMemberList = CreateObject("Scripting.Dictionary")
objMemberList.CompareMode = vbTextCompare

' Specify base OU.
strOU = "ou=TestOU,dc=MyDomain,dc=com"

' Bind to base OU.
Set objOU = GetObject("LDAP://" & strOU)

' Enumerate groups in OU.
Call EnumOU(objOU, "")

Sub EnumOU(ByVal objADContainer, ByVal strOffset)
' Recursive subroutine to enumerate groups in the OU
' and all child OU's.

Dim objGroup, objChild

' Output name of OU.
Wscript.Echo strOffset & "OU: " & objADContainer.distinguishedName

' Enumerate groups in OU.
objADContainer.Filter = Array("group")
For Each objGroup In objADContainer
Call EnumGroup(objGroup, strOffset & " ")
Next

' Enumerate child OU's.
objADContainer.Filter = Array("organizationalUnit")
For Each objChild In objADContainer
Call EnumOU(objChild, strOffset & " ")
Next

End Sub

Sub EnumGroup(ByVal objADGroup, ByVal strOffset)
' Recursive subroutine to enumerate group membership.
' objMemberList is a dictionary object with global scope.
' This subroutine outputs group members. Nested group members
' are included. objMemberList prevents an infinite loop if
' nested groups are circular.

Dim objMember

' Check if group already enumerated.
If (objMemberList.Exists(objADGroup.sAMAccountName) = True) Then
Wscript.Echo strOffset & "Group: " & objADGroup.sAMAccountName & "
(Duplicate)"
Else
' Add this group to dictionary object.
objMemberList.Add objADGroup.sAMAccountName, True
Wscript.Echo strOffset & "Group: " & objADGroup.sAMAccountName
For Each objMember In objADGroup.Members
' Check if member is a group.
If (UCase(Left(objMember.objectCategory, 8)) = "CN=GROUP") Then
Wscript.Echo strOffset & " Member: " &
objMember.sAMAccountName & " (Group)"
Call EnumGroup(objMember, strOffset & " ")
Else
Wscript.Echo strOffset & " Member: " &
objMember.sAMAccountName
End If
Next
End If

End Sub
===========
I don't see how a script could arrange the groups in columns, with members
listed below. That would require amazing logic. A better idea would be to
have one group per row, with members listed in columns. However, this would
not accomodate nested OU's. If you skip nested OU's, and have the script
skip any duplicate groups, maybe the script below would work. The comma
delimited output can be redirected to a text file that can be read into a
spreadsheet, where you might be able to switch rows and columns:
=============
Option Explicit

Dim objMemberList, strOU, objOU
Dim objGroup, strGroup

' Dictionary object to track groups.
Set objMemberList = CreateObject("Scripting.Dictionary")
objMemberList.CompareMode = vbTextCompare

' Specify base OU.
strOU = "ou=TestOU,dc=MyDomain,dc=com"

' Bind to base OU.
Set objOU = GetObject("LDAP://" & strOU)

' Filter on groups directly in OU.
objOU.Filter = Array("group")

' Enumerate groups.
For Each objGroup In objOU
strGroup = objGroup.sAMAccountName
Call EnumGroup(objGroup)
Wscript.Echo strGroup
Next

Sub EnumGroup(ByVal objADGroup)
' Recursive subroutine to enumerate group membership.
' objMemberList is a dictionary object with global scope.
' This subroutine outputs group members. Nested group members
' are included. objMemberList prevents an infinite loop if
' nested groups are circular.
' Variable strGroup must have global scope.

Dim objMember

' Check if group already enumerated.
If (objMemberList.Exists(objADGroup.sAMAccountName) = False) Then
' Add this group to dictionary object.
objMemberList.Add objADGroup.sAMAccountName, True
For Each objMember In objADGroup.Members
' Check if member is a group.
If (UCase(Left(objMember.objectCategory, 8)) = "CN=GROUP") Then
Call EnumGroup(objMember)
Else
strGroup = strGroup & "," & objMember.sAMAccountName
End If
Next
End If

End Sub
================
Both scripts should be run at a command prompt, with the output directed to
a text file. Use the //nologo option to suppress logo info. Note the above
lists all members except groups.

To reverse things, so the groups are in columns, I think you would have to
enumerate all the groups ahead of time and populate an array of arrays, then
enumerate the arrays and output.

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


Re: Enumerate members of all groups within a specific OU
IG 6/6/2007 4:12:03 PM
Hi Richard, thanks for your help. You are a gentleman and a scholar. Can I
ask for more help though?

You mentioned:
"To reverse things, so the groups are in columns, I think you would have to
enumerate all the groups ahead of time and populate an array of arrays, then
enumerate the arrays and output."
Do you have a script that does this?

Incidentally, some of our groups have lots members; putting each group in a
row isn't an option as listing the members in each column would exceed
Excel2003's 256 limit.

Thanks again.

Ian
--
IG


"Richard Mueller [MVP]" wrote:

[Quoted Text]
> IG wrote:
>
> >I can find several scripts to enumerate members of a specific group, but
> > nothing to parse all groups in an OU and output members of each group.
> >
> > Ideally, I would like to output group name, group description and (nested)
> > group members to a .csv file (with each group as a column).
> >
> > My first attempts used dsquery & dsget but I could only get either a list
> > of
> > groups OR a list of members. Using vbscript, I can bind to LDAP
> > successfully
> > but then it falls apart probably because I'm cutting & pasting from
> > different
> > scripts.
>
> Here is a VBScript program that uses a recursive subroutine to enumerate all
> the groups in an OU and any child OU's. For each group, another recursive
> subroutine enumerates all members. If any members are groups, the sub is
> called recursively. A dictionary object is used to prevent enumeration of
> duplicate groups (and prevent an infinite loop if any group nesting is
> circular).
> ============
> Option Explicit
>
> Dim objMemberList, strOU, objOU
>
> ' Dictionary object to track groups.
> Set objMemberList = CreateObject("Scripting.Dictionary")
> objMemberList.CompareMode = vbTextCompare
>
> ' Specify base OU.
> strOU = "ou=TestOU,dc=MyDomain,dc=com"
>
> ' Bind to base OU.
> Set objOU = GetObject("LDAP://" & strOU)
>
> ' Enumerate groups in OU.
> Call EnumOU(objOU, "")
>
> Sub EnumOU(ByVal objADContainer, ByVal strOffset)
> ' Recursive subroutine to enumerate groups in the OU
> ' and all child OU's.
>
> Dim objGroup, objChild
>
> ' Output name of OU.
> Wscript.Echo strOffset & "OU: " & objADContainer.distinguishedName
>
> ' Enumerate groups in OU.
> objADContainer.Filter = Array("group")
> For Each objGroup In objADContainer
> Call EnumGroup(objGroup, strOffset & " ")
> Next
>
> ' Enumerate child OU's.
> objADContainer.Filter = Array("organizationalUnit")
> For Each objChild In objADContainer
> Call EnumOU(objChild, strOffset & " ")
> Next
>
> End Sub
>
> Sub EnumGroup(ByVal objADGroup, ByVal strOffset)
> ' Recursive subroutine to enumerate group membership.
> ' objMemberList is a dictionary object with global scope.
> ' This subroutine outputs group members. Nested group members
> ' are included. objMemberList prevents an infinite loop if
> ' nested groups are circular.
>
> Dim objMember
>
> ' Check if group already enumerated.
> If (objMemberList.Exists(objADGroup.sAMAccountName) = True) Then
> Wscript.Echo strOffset & "Group: " & objADGroup.sAMAccountName & "
> (Duplicate)"
> Else
> ' Add this group to dictionary object.
> objMemberList.Add objADGroup.sAMAccountName, True
> Wscript.Echo strOffset & "Group: " & objADGroup.sAMAccountName
> For Each objMember In objADGroup.Members
> ' Check if member is a group.
> If (UCase(Left(objMember.objectCategory, 8)) = "CN=GROUP") Then
> Wscript.Echo strOffset & " Member: " &
> objMember.sAMAccountName & " (Group)"
> Call EnumGroup(objMember, strOffset & " ")
> Else
> Wscript.Echo strOffset & " Member: " &
> objMember.sAMAccountName
> End If
> Next
> End If
>
> End Sub
> ===========
> I don't see how a script could arrange the groups in columns, with members
> listed below. That would require amazing logic. A better idea would be to
> have one group per row, with members listed in columns. However, this would
> not accomodate nested OU's. If you skip nested OU's, and have the script
> skip any duplicate groups, maybe the script below would work. The comma
> delimited output can be redirected to a text file that can be read into a
> spreadsheet, where you might be able to switch rows and columns:
> =============
> Option Explicit
>
> Dim objMemberList, strOU, objOU
> Dim objGroup, strGroup
>
> ' Dictionary object to track groups.
> Set objMemberList = CreateObject("Scripting.Dictionary")
> objMemberList.CompareMode = vbTextCompare
>
> ' Specify base OU.
> strOU = "ou=TestOU,dc=MyDomain,dc=com"
>
> ' Bind to base OU.
> Set objOU = GetObject("LDAP://" & strOU)
>
> ' Filter on groups directly in OU.
> objOU.Filter = Array("group")
>
> ' Enumerate groups.
> For Each objGroup In objOU
> strGroup = objGroup.sAMAccountName
> Call EnumGroup(objGroup)
> Wscript.Echo strGroup
> Next
>
> Sub EnumGroup(ByVal objADGroup)
> ' Recursive subroutine to enumerate group membership.
> ' objMemberList is a dictionary object with global scope.
> ' This subroutine outputs group members. Nested group members
> ' are included. objMemberList prevents an infinite loop if
> ' nested groups are circular.
> ' Variable strGroup must have global scope.
>
> Dim objMember
>
> ' Check if group already enumerated.
> If (objMemberList.Exists(objADGroup.sAMAccountName) = False) Then
> ' Add this group to dictionary object.
> objMemberList.Add objADGroup.sAMAccountName, True
> For Each objMember In objADGroup.Members
> ' Check if member is a group.
> If (UCase(Left(objMember.objectCategory, 8)) = "CN=GROUP") Then
> Call EnumGroup(objMember)
> Else
> strGroup = strGroup & "," & objMember.sAMAccountName
> End If
> Next
> End If
>
> End Sub
> ================
> Both scripts should be run at a command prompt, with the output directed to
> a text file. Use the //nologo option to suppress logo info. Note the above
> lists all members except groups.
>
> To reverse things, so the groups are in columns, I think you would have to
> enumerate all the groups ahead of time and populate an array of arrays, then
> enumerate the arrays and output.
>
> --
> Richard Mueller
> Microsoft MVP Scripting and ADSI
> Hilltop Lab - http://www.rlmueller.net
> --
>
>
>

Home | Search | Terms | Imprint Contact
Newsgroups Reader - provided by WiredBox.Net
Suche nach Orten, Städten, Postleitzahlen, Vorwahlen, Kfz-Kennzeichen