Richard
Sat Oct 14 11:49:13 CDT 2006
donny wrote:
>I want a script which scans the structure of the AD and outputs the tree of
> the AD groups with the users and nested groups within him.
> Something like:
>
> HR Group -
> A Subgroup - user1, user2, user3
> B Subgroup - user4, user5, user6
>
This would only be practical in an AD with a small number of users per
group. I have a sample VBScript program that document containers, OU's and
groups linked here:
http://www.rlmueller.net/DocumentForest.htm
It shows the hierarchy by indenting the containers, OU's, and groups. For
each group it documents the group type and the number of members (user,
computer, and group members), but not their names. It also documents the
number of "primary" members of each group. As written, it needs to be
modified to prevent an infinite loop if you have circular nested groups.
A similar program that documents only user group membership is below. It
outputs the members names. It handles circular nested groups, but does not
consider group members that are computers. It also ignores "Primary" group
membership. The output will be unwieldy if you have groups with many
members:
====================
Option Explicit
Dim objRootDSE, strForest, objForest
Dim objList
' Setup dictionary object for groups.
Set objList = CreateObject("Scripting.Dictionary")
objList.CompareMode = vbTextCompare
' Retrieve forest root domain name.
Set objRootDSE = GetObject("LDAP://RootDSE")
strForest = objRootDSE.Get("rootDomainNamingContext")
' Bind to Global Catalog in root domain.
Set objForest = GetObject("GC://" & strForest)
' Enumerate domains in the forest.
Call EnumDomains(objForest, "")
' Clean up.
Set objRootDSE = Nothing
Set objForest = Nothing
Set objList = Nothing
Sub EnumDomains(objParent, strOffset)
' Recursive subroutine to enumerate domains.
Dim objGroup, objContainer, objChild
' Output domain name.
Wscript.Echo strOffset & "Domain: " & objParent.name
' Enumerate groups in root of domain.
objParent.Filter = Array("group")
For Each objGroup In objParent
Call EnumGroups(objGroup, "--" & strOffset)
Next
' Enumerate containers in root of domain.
objParent.Filter = Array("container","organizationalUnit","builtinDomain")
For Each objContainer In objParent
Call EnumContainers(objContainer, "--" & strOffset)
Next
' Enumerate child domains.
objParent.Filter = Array("domainDNS")
For Each objChild In objParent
Call EnumDomains(objChild, "--" & strOffset)
Next
Set objGroup = Nothing
Set objContainer = Nothing
Set objChild = Nothing
End Sub
Sub EnumContainers(objParent, strOffset)
' Recursive subroutine to enumerate containers.
Dim objGroup, objChild
' Output container name
Wscript.Echo strOffset & "Container/OU: " & objParent.name
' Enumerate groups in container.
objParent.Filter = Array("group")
For Each objGroup In objParent
Call EnumGroups(objGroup, "--" & strOffset)
Next
' Enumerate child containers.
objParent.Filter = Array("container","organizationalUnit","builtinDomain")
For Each objChild In objParent
Call EnumContainers(objChild, "--" & strOffset)
Next
Set objGroup = Nothing
Set objChild = Nothing
End Sub
Sub EnumGroups(objParent, strOffset)
' Recursive subroutine to enumerate groups.
Dim strUserMembers, objMember
Dim strNTName, strCategory
' Check if we have seen this group before.
If objList.Exists(objParent.sAMAccountName) Then
' Output group sAMAccountName and type.
Wscript.Echo strOffset & "Group: " & objParent.sAMAccountName _
& " - Duplicate"
Exit Sub
End If
' Add group to the dictionary object.
objList(objParent.sAMAccountName) = True
' Output group sAMAccountName and type.
' Enumerate group members.
strUserMembers = ""
For Each objMember In objParent.Members
If LCase(objMember.Class) = "user" Then
If (strUserMembers = "") Then
strUserMembers = objMember.sAMAccountName
Else
strUserMembers = strUserMembers & "," & objMember.sAMAccountName
End If
End If
Next
Wscript.Echo strOffset & "Group: " & objParent.sAMAccountName _
& " - User Members: " & strUserMembers
' Enumerate child groups.
For Each objMember In objParent.Members
If LCase(objMember.Class) = "group" Then
Call EnumGroups(objMember, "--" & strOffset)
End If
Next
Set objMember = Nothing
End Sub
--
Richard
Microsoft MVP Scripting and ADSI
Hilltop Lab -
http://www.rlmueller.net