Platform SDK: Active Directory, ADSI, and Directory Services |
The following code fragment contains a function that creates a query string that uses type or scope for enumerating or searching for groups:
//////////////////// // Enum Definitions //This first enum should be defined for Beta 3 and later. enum { ADS_GROUP_TYPE_GLOBAL_GROUP = 0x2, ADS_GROUP_TYPE_DOMAIN_LOCAL_GROUP = 0x4, ADS_GROUP_TYPE_UNIVERSAL_GROUP = 0x8, ADS_GROUP_TYPE_SECURITY_ENABLED = 0x80000000 }; // (used for telling BuildGroupTypeQueryString() how to build the string) enum ELDAPMatchingRule { lmrAND, lmrOR }; //////////////////////////////////////////////////////////////////////////////////////////////////// /* BuildGroupTypeQueryString() - Builds a Query String for searching on groupType Parameters ELDAPMatchingRule elmrRule - Specifies whether the passed bitmask is ANDed or ORed DWORD dwGroupTypeBits - Bitflags for groupType */ WCHAR * BuildGroupTypeQueryString(ELDAPMatchingRule elmrRule, DWORD dwGroupTypeBits) { static WCHAR wszRet [255]; wszRet[0] = 0l; /* The LDAP_MATCHING RULE is defined as follows: LDAP_MATCHING_RULE_BIT_OR 1.2.840.113556.1.4.804 LDAP_MATCHING_RULE_BIT_AND 1.2.840.113556.1.4.803 These strings are used to describe the bits in dwGroupTypeBits. Specifying an "and" (using LDAP_MATCHING_RULE_BIT_AND) causes the query to mean a bit-wise "and" for the bits in dwGroupTypeBits. Alternatively, specifying LDAP_MATCHING_RULE_BIT_OR denotes a bit-wise "or" of the flags present in dwGroupTypeBits */ switch (elmrRule) { case lmrAND: wsprintf(wszRet,L"(groupType:1.2.840.113556.1.4.803:=%d)",dwGroupTypeBits); break; case lmrOR: wsprintf(wszRet,L"(groupType:1.2.840.113556.1.4.804:=%d)",dwGroupTypeBits); break; } OutputDebugStringW(wszRet); OutputDebugStringW(L"\r\n"); return wszRet; }
When using Visual Basic®, use the ADO SQL syntax for specifying Group Type.
Definitions for bit values:
Public Const ADS_GROUP_TYPE_GLOBAL_GROUP = &H2 Public Const ADS_GROUP_TYPE_DOMAIN_LOCAL_GROUP = &H4 Public Const ADS_GROUP_TYPE_UNIVERSAL_GROUP = &H8 Public Const ADS_GROUP_TYPE_SECURITY_ENABLED = &H80000000
Query Strings:
ALL GLOBAL GROUPS
"GroupType=" & Str(ADS_GROUP_TYPE_GLOBAL_GROUP) & " or " & "GroupType=" & Str(ADS_GROUP_TYPE_GLOBAL_GROUP Or ADS_GROUP_TYPE_SECURITY_ENABLED)
ALL DOMAIN LOCAL GROUPS (With and without Security)
"GroupType=" & Str(ADS_GROUP_TYPE_DOMAIN_LOCAL_GROUP) & " or " & "GroupType=" & Str(ADS_GROUP_TYPE_DOMAIN_LOCAL_GROUP Or ADS_GROUP_TYPE_SECURITY_ENABLED)
ALL SECURITY ENABLED GROUPS
"GroupType=" & Str(ADS_GROUP_TYPE_SECURITY_ENABLED)
The following code fragment searches for groups based on type using the BuildGroupTypeQueryString subroutine:
'************************************ ' QueryAndOutputGroups() - Performs several sample searches using ADO ' ' ' Parameters ' ' oDirObjectRoot As IDirectoryObject - The root from where searches will be performed ' Sub QueryAndOutputGroups(oDirObjectRoot As IDirectoryObject) '******************************* ' Search for all the groups DisplayMessage " " DisplayMessage "<<<<<<<<<<<<<<<<<<<<<ALL GROUPS>>>>>>>>>>>>>>>>>" 'cn = 'UG*' objectCategory SimpleDirectorySearch oDirObjectRoot, "objectCategory = 'group'", ADS_SCOPE_SUBTREE '***************************************** ' Search for all the GLOBAL groups DisplayMessage " " DisplayMsgWaitForInput "Hit OK to perform a subtree search of all the GLOBAL groups" DisplayMessage " " DisplayMessage "<<<<<<<<<<<<<<<<<<<<<ALL GLOBAL Groups>>>>>>>>>>>>>>>>>" SimpleDirectorySearch oDirObjectRoot, "GroupType=" & Str(ADS_GROUP_TYPE_GLOBAL_GROUP) & " or " & _ "GroupType=" & Str(ADS_GROUP_TYPE_GLOBAL_GROUP Or ADS_GROUP_TYPE_SECURITY_ENABLED), _ ADS_SCOPE_SUBTREE '***************************************** ' Search for all the DOMAIN LOCAL groups DisplayMessage " " DisplayMsgWaitForInput "Hit OK to perform a subtree search of all the DOMAIN LOCAL groups" DisplayMessage " " DisplayMessage "<<<<<<<<<<<<<<<<<<<<<ALL Domain Local Groups>>>>>>>>>>>>>>>>>" SimpleDirectorySearch oDirObjectRoot, "GroupType=" & Str(ADS_GROUP_TYPE_DOMAIN_LOCAL_GROUP) & " or " & _ "GroupType=" & Str(ADS_GROUP_TYPE_DOMAIN_LOCAL_GROUP Or ADS_GROUP_TYPE_SECURITY_ENABLED), _ ADS_SCOPE_SUBTREE ' #ifdef USE_UNIVERSAL_GROUPS '***************************************** ' Search for all the UNIVERSAL groups DisplayMessage " " DisplayMsgWaitForInput "Hit OK to perform a subtree search of all the UNIVERSAL groups" DisplayMessage " " DisplayMessage "<<<<<<<<<<<<<<<<<<<<<ALL Universal Groups>>>>>>>>>>>>>>>>>" SimpleDirectorySearch oDirObjectRoot, "GroupType=" & Str(ADS_GROUP_TYPE_UNIVERSAL_GROUP) & " or " & _ "GroupType=" & Str(ADS_GROUP_TYPE_UNIVERSAL_GROUP Or ADS_GROUP_TYPE_SECURITY_ENABLED), _ ADS_SCOPE_SUBTREE ' #End If '***************************************** ' Search for all the Security Enabled groups DisplayMessage " " DisplayMsgWaitForInput "Hit OK to perform a subtree search of all Security Enabled groups" DisplayMessage " " DisplayMessage "<<<<<<<<<<<<<<<<<<<<<ALL Security Enabled Groups>>>>>>>>>>>>>>>>>" SimpleDirectorySearch oDirObjectRoot, "GroupType=" & Str(ADS_GROUP_TYPE_SECURITY_ENABLED) & " or " & _ "GroupType=" & Str(ADS_GROUP_TYPE_SECURITY_ENABLED Or ADS_GROUP_TYPE_SECURITY_ENABLED), _ ADS_SCOPE_SUBTREE '***************************************** ' Search for all the Security Enabled LOCAL groups DisplayMessage " " DisplayMsgWaitForInput "Hit OK to perform a subtree search of all Security Enabled LOCAL groups" DisplayMessage " " DisplayMessage "<<<<<<<<<<<<<<<<<<<<<ALL Security Enabled Domain Local Groups>>>>>>>>>>>>>>>>>" SimpleDirectorySearch oDirObjectRoot, "GroupType=" & Str(ADS_GROUP_TYPE_DOMAIN_LOCAL_GROUP Or _ ADS_GROUP_TYPE_SECURITY_ENABLED), _ ADS_SCOPE_SUBTREE '***************************************** ' Search for all the DOMAIN LOCAL groups whose ' name begins with 'UGExercise' DisplayMessage " " DisplayMsgWaitForInput "Hit OK to perform a subtree search of all DOMAIN LOCAL groups that begin with the text 'UGExercise'" DisplayMessage " " DisplayMessage "<<<<<<<<<<<<<<<<<<<<<ALL Domain Local Groups Beginnig with 'UGExercise' >>>>>>>>>>>>>>>>>" SimpleDirectorySearch oDirObjectRoot, "cn='UGExercise*' and (GroupType=" & _ Str(ADS_GROUP_TYPE_DOMAIN_LOCAL_GROUP) & " or GroupType=" & _ Str(ADS_GROUP_TYPE_DOMAIN_LOCAL_GROUP Or ADS_GROUP_TYPE_SECURITY_ENABLED) & _ ")", ADS_SCOPE_SUBTREE '***************************************** ' Search for ALL the groups whose ' name begins with 'UGExercise' DisplayMessage " " DisplayMsgWaitForInput "Hit OK to perform a subtree search of ALL groups that begin with the text 'UGExercise '" DisplayMessage " " DisplayMessage "<<<<<<<<<<<<<<<<<<<<<ALL Groups Beginning with 'UGExercise' >>>>>>>>>>>>>>>>>" SimpleDirectorySearch oDirObjectRoot, " cn='UGExercise*' and objectCategory='group'", ADS_SCOPE_SUBTREE End Sub '//////////////////////////////////////////////////////////////////////////////////////////////////// ' SimpleDirectorySearch() - Uses ADO to search the directory ' Results are displayed in the list box ' Parameters ' ' oDirObjectRoot As IDirectoryObject - Root of the search ' ByVal sSearchFilter As String - LDAP Search filter ' ByVal lScope As Integer - Scope for Searching possible values are: ' ADS_SCOPE_BASE ' ADS_SCOPE_ONELEVEL ' ADS_SCOPE_SUBTREE ' ' (See IDirectorySearch and ADS_SCOPEENUM in the docs for more info) ' Sub SimpleDirectorySearch(oDirObjectRoot As IDirectoryObject, ByVal sSearchFilter As String, ByVal lScope As Integer) Dim iIndex As Integer iIndex = 0 Dim v, j, i Dim con As New Connection, rs As New Recordset Dim Com As New Command Dim oIADs As IADs Dim sAdsPathRoot As String ' Get the LDAP path to the passed in object sAdsPathRoot = GetAdsPath(oDirObjectRoot) 'Open a Connection object con.Provider = "ADsDSOObject" '--------------------------------------------------------------------- ' To be authenticated using alternate credentials ' use connection properties of User ID and Password '--------------------------------------------------------------------- ' con.Properties("User ID") = "Administrator" ' con.Properties("Password") = "" ' Open the connection con.Open "Active Directory Provider" ' Create a command object on this connection Set Com.ActiveConnection = con ' set the query string using SQL Dialect Com.CommandText = "select name,AdsPath from '" & sAdsPathRoot & "' where " & sSearchFilter & " ORDER BY NAME" ' Tell the user what the search filter is DisplayMessage "Search Filter = " & Com.CommandText '--------------------------------------------------- ' Or you can use LDAP Dialect, for example, '--------------------------------------------------- ' Ex Com.CommandText = "<LDAP://Microsoftsvr1/dc=Microsoft,DC=com>;(objectClass=*);name" ' For LDAP Dialect, the valid search scope are base, oneLevel and subtree ' Com.CommandText = "<" & adDomainPath & ">;(objectClass=*);name;subtree" ' For LDAP Dialect (<LDAP:...>), there is no way to specify sort order in the string, ' However, you can use this SORT ON property to specify sort order. ' for SQL Dialect you can use ORDER BY in the SQL Statement ' Ex. Com.Properties("Sort On") = "Name" 'Set the preferences for Search Com.Properties("Page Size") = 1000 Com.Properties("Timeout") = 30 'seconds Com.Properties("searchscope") = lScope Com.Properties("Chase referrals") = ADS_CHASE_REFERRALS_EXTERNAL Com.Properties("Cache Results") = False ' do not cache the result, it results in less memory requirements 'Execute the query Set rs = Com.Execute ' Tell the user how many rows DisplayMessage "Returned " & Str(rs.RecordCount) & " rows" ' Navigate the record set If Not rs.EOF Then rs.MoveFirst End If On Error Resume Next While Not rs.EOF ' Display the LDAP path for the row DisplayMessage rs.Fields("AdsPath") rs.MoveNext Wend End Sub