[Okta Webinar] Learn how to a build a cloud-first strategyRegister Now

x
?
Solved

Circular Nested Groups AD Login Script

Posted on 2010-09-07
3
Medium Priority
?
1,445 Views
Last Modified: 2013-12-04
I have an Active Directory login script which is working great for some people but which i believe is looping when run due to circular nested groups for others. I know i could just get rid of the circular nested groups but i would prefer to manage these during the login script instead as they make my life easier.

My question is; how would i adjust the nested group enumeration function below to ignore circular nested groups? (i believe the basis for the script originally came from http://www.rlmueller.net)


 
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
' FUNCTION: Enumerate Groups Start
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''

Function EnumGroupsStart()
	'On Error Resume Next
	
WScript.Echo "Started startenum"	

	Set objSysInfo = CreateObject("ADSystemInfo")
	strLDAPUser = objSysInfo.UserName
	Set objUser = GetObject("LDAP://" & strLDAPUser)
	EnumGroupsStart = EnumGroups(objUser, strGroups)

End Function

''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
' FUNCTION: Enumerate Groups
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''

Function EnumGroups(objADObject, strGroups)
	'On Error Resume Next
	
WScript.Echo "Started enum"	
	
	' Setup dictionary object to track groups and prevent infinite loop.
	Set objList = CreateObject("Scripting.Dictionary")
	objList.CompareMode = vbTextCompare	

	Set objGroupList = CreateObject("Scripting.Dictionary")
    objGroupList.CompareMode = vbTextCompare
    	
    ' Recursive subroutine to enumerate user group memberships.
    ' Includes nested group memberships.
    Dim colstrGroups, objGroup, j
    colstrGroups = objADObject.memberOf
    
    If (IsEmpty(colstrGroups) = True) Then
       Exit Function
    End If
    If (TypeName(colstrGroups) = "String") Then
        ' Escape any forward slash characters, "/", with the backslash
        ' escape character. All other characters that should be escaped are.
        colstrGroups = Replace(colstrGroups, "/", "\/")   
        Set objGroup = GetObject("LDAP://" & colstrGroups)
	        If (objGroupList.Exists(objGroup.sAMAccountName) = False) Then
	            objGroupList.Add objGroup.sAMAccountName, True
	            strGroups = strGroups & ucase(objGroup.sAMAccountName) & ";"
	            Call EnumGroups(objGroup, strGroups)
	        End If  
        Set objGroup = Nothing
       Exit Function
    End If
    For j = 0 To UBound(colstrGroups)
        ' Escape any forward slash characters, "/", with the backslash
        ' escape character. All other characters that should be escaped are.
        colstrGroups(j) = Replace(colstrGroups(j), "/", "\/")
        Set objGroup = GetObject("LDAP://" & colstrGroups(j))
	        If (objGroupList.Exists(objGroup.sAMAccountName) = False) Then
	            objGroupList.Add objGroup.sAMAccountName, True          
	            strGroups = strGroups & ucase(objGroup.sAMAccountName) & ";"
	            Call EnumGroups(objGroup, strGroups)
	        End If       
    Next
    Set objGroup = Nothing
    EnumGroups = strGroups

End Function

Open in new window

0
Comment
Question by:MoogControls
  • 2
3 Comments
 
LVL 4

Expert Comment

by:gozoliet
ID: 33616988
It looks to me like you need to make use of your objGroupList as part of your recursive function.   You test to see if a group is already listed in lines 46/59, but every time you iterate through a group you start over again.  I think the easiest fix would be to add create your objGroupList in EnumGroupsStart, and then pass it in on every function call.

0
 
LVL 4

Accepted Solution

by:
gozoliet earned 2000 total points
ID: 33617017
Making the above change, this seems to work in a case where I had two groups nested in each other.
EnumGroupsStart()

''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
' FUNCTION: Enumerate Groups Start
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''

Function EnumGroupsStart()
	'On Error Resume Next
	
WScript.Echo "Started startenum"	

	Set objSysInfo = CreateObject("ADSystemInfo")
	strLDAPUser = objSysInfo.UserName
	Set objUser = GetObject("LDAP://" & strLDAPUser)

	Set objGroupList = CreateObject("Scripting.Dictionary")
       objGroupList.CompareMode = vbTextCompare

	EnumGroupsStart = EnumGroups(objUser, strGroups, objGroupList)

End Function

''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
' FUNCTION: Enumerate Groups
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''

Function EnumGroups(objADObject, strGroups, objGroupList)
	'On Error Resume Next
	
	' Setup dictionary object to track groups and prevent infinite loop.
	Set objList = CreateObject("Scripting.Dictionary")
	objList.CompareMode = vbTextCompare	

    ' Recursive subroutine to enumerate user group memberships.
    ' Includes nested group memberships.
    Dim colstrGroups, objGroup, j
    colstrGroups = objADObject.memberOf
    
    If (IsEmpty(colstrGroups) = True) Then
       Exit Function
    End If
    If (TypeName(colstrGroups) = "String") Then
        ' Escape any forward slash characters, "/", with the backslash
        ' escape character. All other characters that should be escaped are.
        colstrGroups = Replace(colstrGroups, "/", "\/")   
        Set objGroup = GetObject("LDAP://" & colstrGroups)
	        If (objGroupList.Exists(objGroup.sAMAccountName) = False) Then
	            objGroupList.Add objGroup.sAMAccountName, True
	            strGroups = strGroups & ucase(objGroup.sAMAccountName) & ";"
  
	            Call EnumGroups(objGroup, strGroups, objGroupList)
	        End If  
        Set objGroup = Nothing
       Exit Function
    End If
    For j = 0 To UBound(colstrGroups)
        ' Escape any forward slash characters, "/", with the backslash
        ' escape character. All other characters that should be escaped are.
        colstrGroups(j) = Replace(colstrGroups(j), "/", "\/")
        Set objGroup = GetObject("LDAP://" & colstrGroups(j))
	        If (objGroupList.Exists(objGroup.sAMAccountName) = False) Then
	            objGroupList.Add objGroup.sAMAccountName, True          
	            strGroups = strGroups & ucase(objGroup.sAMAccountName) & ";"
	            Call EnumGroups(objGroup, strGroups, objGroupList)
	        End If       
    Next
    Set objGroup = Nothing
    EnumGroups = strGroups

End Function

Open in new window

0
 

Author Closing Comment

by:MoogControls
ID: 33617205
Awesome! Works a treat. Thank you very very much for your quick response.
0

Featured Post

Concerto's Cloud Advisory Services

Want to avoid the missteps to gaining all the benefits of the cloud? Learn more about the different assessment options from our Cloud Advisory team.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

A hard and fast method for reducing Active Directory Administrators members.
Had a business requirement to store the mobile number in an environmental variable. This is just a quick article on how this was done.
This tutorial will walk an individual through the process of configuring their Windows Server 2012 domain controller to synchronize its time with a trusted, external resource. Use Google, Bing, or other preferred search engine to locate trusted NTP …
This video shows how to use Hyena, from SystemTools Software, to bulk import 100 user accounts from an external text file. View in 1080p for best video quality.
Suggested Courses

873 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question