Example Code for Searching for Groups in a Domain
The following C/C++ code example searches the subtree of the specified container for all group objects that have the specified group type.
/***************************************************************************
PrintGroupsInContainer()
Searches the entire subtree for all groups objects that contain the
specified group type bits from the ADS_GROUP_TYPE_ENUM enumeration.
***************************************************************************/
HRESULT PrintGroupsInContainer(LPCWSTR pwszContainerDN, DWORD type)
{
HRESULT hr = E_FAIL;
// Construct the ADsPath to bind to the search root.
CComBSTR sbstrADsPath = "LDAP://";
sbstrADsPath += pwszContainerDN;
// Bind to the container.
CComPtr<IDirectorySearch> spSearch;
hr = ADsGetObject(sbstrADsPath, IID_IDirectorySearch, (LPVOID*)&spSearch);
if(SUCCEEDED(hr))
{
ADS_SEARCHPREF_INFO SearchPref[1];
// Set the scope of the search to be all of the subtree.
SearchPref[0].dwSearchPref = ADS_SEARCHPREF_SEARCH_SCOPE;
SearchPref[0].vValue.dwType = ADSTYPE_INTEGER;
SearchPref[0].vValue.Integer = ADS_SCOPE_SUBTREE;
hr = spSearch->SetSearchPreference(SearchPref, sizeof(SearchPref)/sizeof(ADS_SEARCHPREF_INFO));
if(FAILED(hr))
{
return hr;
}
ADS_SEARCH_HANDLE hSearch = NULL;
LPWSTR pwszDN = L"distinguishedName";
LPWSTR pwszAttributes[1] = {pwszDN};
// Convert the group type to search for into a string.
WCHAR wszGroupType[30]; // Plenty large enough to handle the biggest 32-bit number.
swprintf_s(wszGroupType, L"%d", type);
// Construct the search filter.
CComBSTR sbstrSearchFilter;
sbstrSearchFilter = "(&(objectClass=group)(groupType:";
sbstrSearchFilter += LDAP_MATCHING_RULE_BIT_AND;
sbstrSearchFilter += ":=";
sbstrSearchFilter += wszGroupType;
sbstrSearchFilter += "))";
// Execute the search.
hr = spSearch->ExecuteSearch(sbstrSearchFilter,
pwszAttributes,
sizeof(pwszAttributes)/sizeof(LPWSTR),
&hSearch);
if(FAILED(hr))
{
return hr;
}
// Get the first result row. There should never be more than one result.
hr = spSearch->GetFirstRow(hSearch);
while(S_OK == hr)
{
ADS_SEARCH_COLUMN col;
// Get the distinguished name for the current result.
hr = spSearch->GetColumn(hSearch, pwszDN, &col);
if(SUCCEEDED(hr))
{
if(ADSTYPE_DN_STRING == col.dwADsType)
{
wprintf(col.pADsValues[0].DNString);
wprintf(L"\n\n");
}
// Free the column.
spSearch->FreeColumn(&col);
}
hr = spSearch->GetNextRow(hSearch);
}
// Close the search handle to cleanup.
hr = spSearch->CloseSearchHandle(hSearch);
}
return hr;
}
The following Visual Basic code example searches the subtree of the specified container for all group objects that have the specified group type.
''''''''''''''''''''''''''''''''''''''''
' PrintGroupsInContainer()
'
' Searches the entire subtree for all groups objects that contain the
' specified group type bits from the ADS_GROUP_TYPE_ENUM enumeration.
'
''''''''''''''''''''''''''''''''''''''''
Public Sub PrintGroupsInContainer(ContainerDN As String, GroupType As Long)
Const ADS_GROUP_TYPE_GLOBAL_GROUP = 2
Const ADS_GROUP_TYPE_DOMAIN_LOCAL_GROUP = 4
Const ADS_GROUP_TYPE_LOCAL_GROUP = 4
Const ADS_GROUP_TYPE_UNIVERSAL_GROUP = 8
Const ADS_GROUP_TYPE_SECURITY_ENABLED = &H80000000
Const ADS_SECURE_AUTHENTICATION = 1
Const LDAP_MATCHING_RULE_BIT_AND = "1.2.840.113556.1.4.803"
Const LDAP_MATCHING_RULE_BIT_OR = "1.2.840.113556.1.4.804"
Set oConn = CreateObject("ADODB.Connection")
Set oComm = CreateObject("ADODB.Command")
oConn.Provider = "ADsDSOObject"
oConn.Properties("ADSI Flag") = ADS_SECURE_AUTHENTICATION
oConn.Open
oComm.ActiveConnection = oConn
oComm.CommandText = "<LDAP://" + ContainerDN + ">;(&(objectClass=group)(groupType:" + LDAP_MATCHING_RULE_BIT_AND + ":=" + str(GroupType) + "));distinguishedName;subtree"
' Execute the query.
Set oRS = oComm.Execute
' Print the results.
oRS.MoveFirst
While Not oRS.EOF
List.AddItem oRS.Fields(0)
oRS.MoveNext
Wend
End Sub