| 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