如何使用C#获取Windows系统所有本地及域用户账户列表
你当前使用的WinNT://协议绑定了本地计算机账户存储,仅能读取本地SAM数据库中的本地用户,域用户存储在域控制器的*活动目录(AD)*中,需要通过LDAP协议查询域目录服务获取。
方案1:推荐使用AccountManagement API(更简洁,支持.NET Framework 3.5+ / .NET 5+)
需要先在项目中引用程序集System.DirectoryServices.AccountManagement,示例代码如下:
using System.DirectoryServices.AccountManagement; // 先判断设备是否已加入域 if (Domain.GetComputerDomain() != null) { // 绑定当前域的上下文 using (PrincipalContext domainContext = new PrincipalContext(ContextType.Domain)) { // 设置用户筛选条件 UserPrincipal userFilter = new UserPrincipal(domainContext); using (PrincipalSearcher searcher = new PrincipalSearcher(userFilter)) { foreach (var foundUser in searcher.FindAll()) { // 可根据需要获取SamAccountName、DisplayName、EmailAddress等其他属性 MessageBox.Show(foundUser.Name); foundUser.Dispose(); } } } } else { MessageBox.Show("当前设备未加入域,无法获取域用户列表"); }
该方案的优势:
- 官方原生封装AD查询逻辑,无需手动拼接LDAP路径
- 可直接获取标准化的用户属性,无需处理DirectoryEntry的原生属性集合
- 自动适配当前设备加入的域,无需手动指定域名
- 原生支持大数量用户分页查询,避免查询超时
方案2:传统DirectoryEntry + LDAP 实现(适配老版本.NET)
如果项目使用低于3.5版本的.NET Framework,可使用该方案:
using System.DirectoryServices; // 获取当前设备加入的域名 string domainName = Domain.GetComputerDomain().Name; string ldapPath = $"LDAP://{domainName}"; using (DirectoryEntry domainEntry = new DirectoryEntry(ldapPath)) using (DirectorySearcher searcher = new DirectorySearcher(domainEntry)) { // 筛选所有用户对象,排除计算机账户等其他对象 searcher.Filter = "(&(objectClass=user)(objectCategory=person))"; // 可选:指定返回属性,减少不必要的查询开销 searcher.PropertiesToLoad.Add("name"); searcher.PropertiesToLoad.Add("samaccountname"); // 域用户超过1000时需设置分页大小,避免结果被截断 searcher.PageSize = 1000; foreach (SearchResult user in searcher.FindAll()) { string userName = user.Properties["name"][0].ToString(); MessageBox.Show(userName); } }
注意事项
- 运行代码的进程持有普通域用户权限即可完成查询,无需域管理员权限
- 如果需要查询指定域而非当前设备加入的域,直接替换LDAP路径中的域名为目标域即可
内容的提问来源于stack exchange,提问作者Ammar Ahmad Khan
相关产品推荐
相关产品推荐

