Program to find any instances of Circular Nested Groups in the domain. Finds and reports on all
groups involved in circular nesting.
A very useful feature of Active Directory is that groups can be nested. See this link for a description of "nested group" membership. However, it is possible for the group nesting to be circular. For example, if group "Grade 1" is a member of group "Students", and group "Students" is a member of group "School", and group "School" is made a member of group "Grade 1", the group nesting is circular. The group "Grade 1" is a member of itself.
Many programs that enumerate group membership use a recursive routine to reveal membership due to nesting. Unless these programs specifically check for instances of circular group nesting, they can get caught in an infinite loop. There have been instances reported where third party tools crash when they encounter circular nested groups.
Manually searching for instances of circular nesting could be very time consuming. This program efficiently finds all circular nested groups. It uses ADO to retrieve all group names and direct memberships. The member attribute of group objects is a collection of the Distinguished Names of all direct members of the group. The member attribute does not reveal membership in the "Primary Group" or membership due to group nesting. The program evaluates each group using a recursive subroutine to track down members that are groups. As soon as a nested member is found that is identical to any parent group, the program has found an instance of circular nesting.
The program reports all groups that are involved in circular nesting. If GroupA is a member of GroupB, and GroupB is a member of GroupC, and GroupC is a member of GroupA, the program will report all three group names. The program does not report on how the groups are nested. For example, if the program lists 5 groups that are involved in circular nesting, there are several ways these groups could be nested. There could be one instance involving 5 groups, or 1 instance involving 2 groups and one instance involving 3 groups. Given the group names you will need to track down how they are nested.
The program has been revised to fix a bug. The original program checked if any nested member was identical to the original parent group being evaluated. However, this resulted in an infinite loop if the member was not identical to the original parent, but was identical to some other group in the nesting. For example, if group School has group Grade1 as a member, and group Grade1 has group Teachers as a member, and group Teachers has group Grade1 as a member, then the groups Grade1 and Teachers are in a circular nesting arrangement. However, when the members of group School are evaluated, no member ever matches the original parent name. Instead, the program has been revised so that each member name is checked against all of its parent groups in the hierarchy of groups. In this case, group Grade1 is compared not just to group School (the original group being evaluated at this stage), but also to group Grade1 (another parent of this group). The circular nesting is found and the enumeration is aborted without getting stuck in an infinite loop.
CircularNestedGroups.txt <<-- Click here to view or download the program
A PowerShell script has also been developed
to find all instances of circular nested groups in the domain. Similar logic
is used, but the System.DirectoryServices.DirectorySearcher class is used
instead of ADO. The PowerShell hash table is equivalent to the VBScript
PSCircularNestedGroups.txt <<-- Click here to view or download the PowerShell script