Unlike Windows NT® 4.0 domains, Windows® 2000 groups can be placed in any container or organizational unit (OU) in a domain as well as the root of the domain. This means that groups can be in numerous locations in the directory hierarchy. Therefore, you have two choices for enumerating groups:
Explicitly bind to the container object that contains the groups to enumerate, set a filter that contains "groups" as the class using the IADsContainer::put_Filter property method, and use the IADsContainer::get__NewEnum method to enumerate the group objects.
This technique enumerates groups contained directly in a container or OU object. If the container contains other containers that can potentially contain other groups, you must bind to those containers and recursively enumerate the groups on those containers. To manipulate the group objects and read only specific properties, use the deep search described in Option 2.
Because enumeration returns pointers to ADSI COM objects representing each group object, you can call QueryInterface to get IADs, IADsGroup, and IADsPropertyList interface pointers to the group object; that is, you can get interface pointers to each enumerated group object in a container without having to explicitly bind to each group object. To perform operations on all the groups directly within a container, enumeration does not require binding to each group in order to call IADs or IADsGroup methods. To retrieve specific properties from groups, use IDirectorySearch as described in Option 3.
An exception to this occurs when you attempt to enumerate a group that contains members that are wellKnown security principals, such as Everyone, Authenticated users, BATCH, and so on. Because you cannot bind to these types of objects, they are not listed when you enumerate groups in the WinNT scope, even though it may appear to bind, because certain IADs methods such as Class, ADsPath, and Name return correct results when invoked on enumerated members.
First, bind to the container object where to begin the search. For example, to find all groups in a domain, bind to root of the domain; to find all groups in the forest, bind to global catalog and search from the root of the GC.
Then use IDirectorySearch to query using a search filter that contains (objectCategory=group) and search preference of ADS_SCOPE_SUBTREE.
Note You can perform a search with a search preference of ADS_SCOPE_ONELEVEL to limit the search to the direct contents of the container object that you bound to.
IDirectorySearch retrieves only the values of specific properties from groups. To retrieve values, use IDirectorySearch. To manipulate the group objects returned from a search, that is, to use IADs or IADsGroup methods, explicitly bind to them. To do this, specify distinguishedName as one of the properties to return from the search and use the returned distinguished names to bind to each group returned in the search.
Only specific properties are retrieved. You cannot retrieve all attributes without explicitly specifying every possible attribute of the group class.