解决AD账号超过1000个获取问题
由于默认AD设置了1000限制,虽然可以通过调整AD服务器来解决,但是一些金融行业AD的调整相对比较困难,所以直接从代码上进行解决,具体如下:
// DoDirSyncSearch
HRESULT DoDirSyncSearch(LPWSTR pszSearchFilter, // Search filter.
LPWSTR *pAttributeNames, // Attributes to retrieve.
DWORD dwAttributes, // Number of attributes.
LPWSTR szDCFullPath, // Name of DC to bind to.
LPWSTR strUserForQuery,
LPWSTR strPwdForQuery,
Json::Value &jvMembers)
{
IDirectorySearch *pSearch = NULL;
ADS_SEARCH_HANDLE hSearch = NULL;
ADS_SEARCHPREF_INFO arSearchPrefs[2];
ADS_SEARCH_COLUMN col;
HRESULT hr = S_OK;
VARIANT var;
int dwCount = 0;
LPOLESTR szDSPath = new OLECHAR[MAX_PATH];
TCHAR** ppszAttributeArray = new TCHAR*[MAX_PATH];
wstring wszAttributeTmp;
string szAttributeName[MAX_PATH] = { "" };
string szValueTmp;
Json::Value jvMember;
// Validate input parameters.
if (!szDCFullPath)
{
wprintf(L"Invalid parameter.\n");
return E_FAIL;
}
for (int i = 0; i < dwAttributes; ++i)
{
ppszAttributeArray[i] = new TCHAR[MAX_PATH];
memset(ppszAttributeArray[i], 0, sizeof(TCHAR)*MAX_PATH);
_tcscpy_s(ppszAttributeArray[i], MAX_PATH, pAttributeNames[i]);
wszAttributeTmp.clear();
wszAttributeTmp = ppszAttributeArray[i];
Unicode2ASCII(wszAttributeTmp, szAttributeName[i]);
}
VariantInit(&var);
CoInitialize(NULL);
hr = ADsOpenObject(szDCFullPath,
strUserForQuery,
strPwdForQuery,
ADS_SECURE_AUTHENTICATION,
IID_IDirectorySearch,
(void **)&pSearch);
if (FAILED(hr))
{
wprintf(L"failed to bind to rootDSE: 0x%x\n", hr);
goto cleanup;
}
arSearchPrefs[0].dwSearchPref = ADS_SEARCHPREF_SEARCH_SCOPE;
arSearchPrefs[0].vValue.dwType = ADSTYPE_INTEGER;
arSearchPrefs[0].vValue.Integer = ADS_SCOPE_SUBTREE;
//以下是重点,即设置分页获取方式
arSearchPrefs[1].dwSearchPref = ADS_SEARCHPREF_PAGESIZE;arSearchPrefs[1].vValue.dwType = ADSTYPE_INTEGER;
arSearchPrefs[1].vValue.Integer = 500;
hr = pSearch->SetSearchPreference(arSearchPrefs, 2);
if (FAILED(hr))
{
wprintf(L"failed to set search prefs: 0x%x\n", hr);
goto cleanup;
}
// Search for the objects indicated by the search filter.
hr = pSearch->ExecuteSearch(pszSearchFilter,
pAttributeNames,
dwAttributes,
&hSearch);
if (FAILED(hr))
{
wprintf(L"failed to set execute search: 0x%x\n", hr);
goto cleanup;
}
// Loop through the rows of the search result
// Each row is an object that has changed since the previous call.
hr = pSearch->GetNextRow(hSearch);
while (SUCCEEDED(hr) && hr != S_ADS_NOMORE_ROWS)
{
wprintf(L"----------------------------:\n");
//属性值填充
for (size_t i = 0; i < dwAttributes; i++)
{
wprintf(L"GetColumn : %s\n", ppszAttributeArray[i]);
hr = pSearch->GetColumn(hSearch, ppszAttributeArray[i], &col);
if (SUCCEEDED(hr))
{
szValueTmp.clear();
//当前仅处理三种数据类型
if (col.dwADsType == ADSTYPE_CASE_IGNORE_STRING && col.pADsValues)
{
Unicode2ASCII(col.pADsValues->CaseIgnoreString, szValueTmp);
jvMember[szAttributeName[i]] = szValueTmp;
wprintf(L"%S = %S\n", szAttributeName[i].c_str(), szValueTmp.c_str());
}
//暂时没有处理整型
else if(col.dwADsType == ADSTYPE_INTEGER && col.pADsValues)
{
jvMember[szAttributeName[i]] = col.pADsValues;
wprintf(L"%S = %d\n", szAttributeName[i].c_str(), col.pADsValues);
}
else if (col.dwADsType == ADSTYPE_BOOLEAN && col.pADsValues)
{
jvMember[szAttributeName[i]] = col.pADsValues;
wprintf(L"%S = %d\n", szAttributeName[i].c_str(), col.pADsValues);
}
pSearch->FreeColumn(&col);
}
else
{
//取不到列时就填充为空
jvMember[szAttributeName[i]] = "";
}
}
jvMembers[dwCount] = jvMember;
dwCount++;
hr = pSearch->GetNextRow(hSearch);
}
wprintf(L"dwCount: %d\n", dwCount);
cleanup:
if (ppszAttributeArray)
{
delete[] ppszAttributeArray;
ppszAttributeArray = NULL;
}
if (hSearch)
pSearch->CloseSearchHandle(hSearch);
if (pSearch)
pSearch->Release();
VariantClear(&var);
CoUninitialize();
delete[] szDSPath;
return hr;
}
// Entry point for application
int main(int argc, char* argv[])
{
DWORD dwStat = 0;
ULONG ulLength = 0;
UCHAR *pCookie = NULL;
WCHAR szDCName[MAX_PATH] = {NULL};
HRESULT hr = S_OK;
LPOLESTR pszNonVerboseList[] = { L"name",L"sAMAccountName",L"mail" }; //按需设置条件
DWORD dwAttributes = sizeof(pszNonVerboseList) / sizeof(LPOLESTR);
WCHAR szUser[MAX_PATH] = { NULL };
WCHAR szPassword[MAX_PATH] = { NULL };
Json::Value jvMembers;
wprintf(L"Performing a full sync.\n");
_tcscpy_s(szDCName,
MAX_PATH,
_T("test.com:389/OU=abc,OU=Accounts,DC=lab,DC=com"));
_tcscpy_s(szUser, MAX_PATH, _T("admin"));
_tcscpy_s(szPassword, MAX_PATH, _T("123456"));
// Perform the search and update the synchronization parameters.
hr = DoDirSyncSearch(L"(&(objectClass=user)(objectCategory=person))",
pszNonVerboseList,
dwAttributes,
szDCName,
szUser,
szPassword,
jvMembers);
if (FAILED(hr))
{
wprintf(L"DoDirSyncSearch failed: 0x%x\n", hr);
goto cleanup;
}
else
{
Json::FastWriter writer;
std::string strWrite;
strWrite = writer.write(jvMembers);
wprintf(L" strWrite = %S\n", strWrite.c_str());
}
cleanup:
if (pCookie)
GlobalFree(pCookie);
return 1;
}
以上是基于
https://msdn.microsoft.com/zh-cn/ms676896进行修改,原文不支持超过1000个账号或者1000个组。
另也可通过设置服务器进行1000限制的解决,
http://www.360doc.com/content/11/0921/10/706976_150034047.shtml