如何通过LDAP C++快速获取AD用户的全部终端服务属性?
使用LDAP C++快速获取AD用户终端服务属性的方案
最快实现路径:LDAP批量读取+系统API解析userParameters
WTSQueryUserConfig处理数百用户时效率低下,核心原因是逐个用户发起请求带来的网络往返开销。最快的解决方式是通过LDAP一次性批量获取所有目标用户的userParameters属性,再本地解析编码内容:
LDAP批量查询
- 用LDAP原生C++ API(
ldap_init、ldap_bind_s、ldap_search_s)构造批量查询,一次性拉取所有目标用户的distinguishedName和userParameters二进制属性。例如过滤条件可写为:(&(objectCategory=person)(objectClass=user)(your-additional-filters)) - 批量查询将网络请求次数从数百次压缩到1次,是提升效率的关键。
- 用LDAP原生C++ API(
解析
userParameters二进制数据- Windows系统提供
WdsUnserializeUserParams函数(需包含wdsutil.h并链接wdsutil.lib),可直接将userParameters的二进制内容反序列化为USER_PARAMS结构体,该结构体包含所有你需要的终端服务属性:InitialProgram→tsInitialProgramWorkingDirectory→tsWorkingDirInheritInitialProgram→tsInheritInitialProgramAllowLogon→tsAllowLogon
- 示例代码片段:
#include <wdsutil.h> #pragma comment(lib, "wdsutil.lib") USER_PARAMS* pUserParams = nullptr; DWORD dwStatus = WdsUnserializeUserParams(pBinaryBlob, dwBlobSize, &pUserParams); if (dwStatus == ERROR_SUCCESS) { // 读取所需属性,例如pUserParams->InitialProgram WdsFreeUserParams(pUserParams); // 使用后必须释放内存 } - 不建议手动解析二进制格式,避免因微软内部格式变更导致兼容性问题。
- Windows系统提供
其他可用的C++ API
1. NetUserGetInfo(适合少量用户场景)
- 指定信息级别
102(对应USER_INFO_102结构体),可直接获取终端服务相关属性,但该API需逐个用户调用,批量处理数百用户时效率不如LDAP批量方案。 - 示例代码:
#include <lmaccess.h> #pragma comment(lib, "netapi32.lib") USER_INFO_102* pUserInfo = nullptr; DWORD dwStatus = NetUserGetInfo(L"your-domain", L"username", 102, (LPBYTE*)&pUserInfo); if (dwStatus == NERR_Success) { // 访问属性如pUserInfo->usri102_initial_program NetApiBufferFree(pUserInfo); }
2. ADSI C++ API(封装性更强)
- 通过
IADsUser接口访问AD用户属性,读取userParameters二进制值后仍需用WdsUnserializeUserParams解析。ADSI封装了LDAP底层细节,代码更简洁,批量处理效率与LDAP原生API相当。 - 示例代码:
#include <activeds.h> #pragma comment(lib, "activeds.lib") IADsUser* pUser = nullptr; HRESULT hr = ADsGetObject(L"LDAP://CN=TargetUser,OU=Users,DC=domain,DC=com", IID_IADsUser, (void**)&pUser); if (SUCCEEDED(hr)) { VARIANT varParams; VariantInit(&varParams); hr = pUser->Get(CComBSTR("userParameters"), &varParams); if (SUCCEEDED(hr) && varParams.vt == VT_BINARY) { // 用WdsUnserializeUserParams解析varParams.binaryVal } VariantClear(&varParams); pUser->Release(); }
效率总结
- 最优方案:LDAP原生API批量查询+
WdsUnserializeUserParams本地解析,能最大化减少网络开销,处理数百用户的速度远优于逐个调用WTSQueryUserConfig。 - 备选方案:ADSI适合追求代码简洁的场景;
NetUserGetInfo仅推荐用于少量用户的查询需求。
内容的提问来源于stack exchange,提问作者Praveen Kumar
相关产品推荐
相关产品推荐

