Solved

Circular Nested Groups AD Login Script

Posted on 2010-09-07
3
1,368 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 500 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

Use Case: Protecting a Hybrid Cloud Infrastructure

Microsoft Azure is rapidly becoming the norm in dynamic IT environments. This document describes the challenges that organizations face when protecting data in a hybrid cloud IT environment and presents a use case to demonstrate how Acronis Backup protects all data.

Question has a verified solution.

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

Our Group Policy work started with Small Business Server in 2000. Microsoft gave us an excellent OU and GPO model in subsequent SBS editions that utilized WMI filters, OU linking, and VBS scripts. These are some of experiences plus our spending a lo…
OfficeMate Freezes on login or does not load after login credentials are input.
This tutorial will walk an individual through the steps necessary to join and promote the first Windows Server 2012 domain controller into an Active Directory environment running on Windows Server 2008. Determine the location of the FSMO roles by lo…
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 …

770 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