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 strongm on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

VBS for enumerating ACL permissions recursively

Status
Not open for further replies.
Jul 21, 2004
11
CA
I found a lovely piece of code that will recursively get the group membership from the DN of a initial group. I 'thought' I would be able to stick some of the code into a loop so that I could open a txt file of group DN's and have the program fetch all members for all the groups.... I just can't figure out why it isn't doing it properly.

When I execute a cmd: cscript enumgroup.vbs "cn=xxx,dc=aaa,dc=com" it works wonderfully. As soon as I put this into a loop it claims it can't find the group but it does outputs the group name to the output and it has a valid name.

[bigsmile] Please have mercy on my butchering of the script as I don't claim to be proficient but kinda know where I want to get to but not exactly how to get there.

My thanks to the author for the script.

' EnumGroup.vbs
' VBScript program to document members of a group.
' Reveals nested group and primary group membership.
'
' ----------------------------------------------------------------------
' Copyright (c) 2002 Richard L. Mueller
' Hilltop Lab web site - ' Version 1.0 - December 10, 2002
' Version 1.1 - January 24, 2003 - Include users whose Primary Group is
' any nested group.
' Version 1.2 - February 19, 2003 - Standardize Hungarian notation.
' Version 1.3 - March 11, 2003 - Remove SearchScope property.
' Version 1.4 - April 30, 2003 - Use GetInfoEx to retrieve group
' primaryGroupToken.
' Version 1.5 - January 25, 2004 - Modify error trapping.
'
' You have a royalty-free right to use, modify, reproduce, and
' distribute this script file in any way you find useful, provided that
' you agree that the copyright owner above has no warranty, obligations,
' or liability for such use.

Option Explicit

Const ForReading = 1

Dim objGroup, strDN, objMemberList, objFSO, objTextFile
Dim adoConnection, adoCommand, objRootDSE, strDNSDomain

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

' Check for required argument.
If (Wscript.Arguments.Count < 1) Then
Wscript.Echo "Required argument <Distinguished Name> " _
& "of group missing."
Wscript.Echo "For example:" & vbCrLf _
& "cscript //nologo EnumGroup.vbs " _
& """cn=Test Group,ou=Sales,dc=MyDomain,dc=com"""
Wscript.Quit(0)
End If


' Retrieve DNS domain name from RootDSE.
Set objRootDSE = GetObject("LDAP://RootDSE")
strDNSDomain = objRootDSE.Get("defaultNamingContext")

' Setup ADO.
Set adoConnection = CreateObject("ADODB.Connection")
Set adoCommand = CreateObject("ADODB.Command")
adoConnection.Provider = "ADsDSOObject"
adoConnection.Open "Active Directory Provider"
Set adoCommand.ActiveConnection = adoConnection
adoCommand.Properties("Page Size") = 100
adoCommand.Properties("Timeout") = 30
adoCommand.Properties("Cache Results") = False



Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objTextFile = objFSO.OpenTextFile _
(WScript.Arguments.Item(0), ForReading)

'******Start with Group Names
Do Until objTextFile.AtEndOfStream
strDN = objTextFile.Readline

' Bind to the group object with the LDAP provider.
' strDN = Wscript.Arguments(0)
On Error Resume Next
Set objGroup = GetObject("LDAP://" & strDN)
If (Err.Number <> 0) Then
On Error GoTo 0
Wscript.Echo "Group not found" & vbCrLf & strDN
Wscript.Quit(1)
End If
On Error GoTo 0

' Enumerate group membership.
Wscript.Echo "Members of group " & objGroup.sAMAccountName
Call EnumGroup(objGroup, " ")



'*****End of Groups
Loop




' Clean Up.
adoConnection.Close
Set objGroup = Nothing
Set objRootDSE = Nothing
Set adoCommand = Nothing
Set adoConnection = Nothing

Sub EnumGroup(ByVal objADGroup, ByVal strOffset)
' Recursive subroutine to enumerate group membership.
' objMemberList is a dictionary object with global scope.
' objADGroup is a group object bound with the LDAP provider.
' This subroutine outputs a list of group members, one member
' per line. Nested group members are included. Users are also
' included if their primary group is objADGroup. objMemberList
' prevents an infinite loop if nested groups are circular.

Dim strFilter, strAttributes, adoRecordset, intGroupToken
Dim objMember, strQuery, strNTName

' Retrieve "primaryGroupToken" of group.
objADGroup.GetInfoEx Array("primaryGroupToken"), 0
intGroupToken = objADGroup.Get("primaryGroupToken")

' Use ADO to search for users whose "primaryGroupID" matches the
' group "primaryGroupToken".
strFilter = "(primaryGroupID=" & intGroupToken & ")"
strAttributes = "sAMAccountName"
strQuery = "<LDAP://" & strDNSDomain & ">;" & strFilter & ";" _
& strAttributes & ";subtree"
adoCommand.CommandText = strQuery
Set adoRecordset = adoCommand.Execute
Do Until adoRecordset.EOF
strNTName = adoRecordset.Fields("sAMAccountName").Value
If (objMemberList.Exists(strNTName) = False) Then
objMemberList.Add strNTName, True
Wscript.Echo strOffset & strNTName & " (Primary)"
Else
Wscript.Echo strOffset & strNTName & " (Primary, Duplicate)"
End If
adoRecordset.MoveNext
Loop
adoRecordset.Close

For Each objMember In objADGroup.Members
If (objMemberList.Exists(objMember.sAMAccountName) = False) Then
objMemberList.Add objMember.sAMAccountName, True
If (UCase(Left(objMember.objectCategory, 8)) = "CN=GROUP") Then
Wscript.Echo strOffset & objMember.sAMAccountName & " (Group)"
Call EnumGroup(objMember, strOffset & " ")
Else
Wscript.Echo strOffset & objMember.sAMAccountName
End If
Else
Wscript.Echo strOffset & objMember.sAMAccountName & " (Duplicate)"
End If
Next
Set objMember = Nothing
Set adoRecordset = Nothing
End Sub
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top