示例准备
  • 打开上一篇文章配置好的AD域控制器
  • 开始菜单-->管理工具-->Active Directory 用户和计算机
  • 新建组织单位和用户

   

  • 新建层次关系如下:

  

知识了解

  我们要用C#访问Active Directory非常容易,主要用到

  轻量目录访问协议 (LDAP)

  System.DirectoryServices命名空间下的两个组件类

  DirectoryEntryDirectorySeacher

读取AD域信息示例

  示例在Framework 3.5下用Winform程序编写

   主要结合常见需求读取组织单位(OU)及用户(User)信息,以及同步组织单位和用户的层次关系;

比较着重的还是用户的信息,特别是帐号、邮箱、SID等信息;

  

  • 下面我们开始连接域,并读取出示例准备中键好的组织单位和用户  

  首先编写代码用LDAP尝试对域进行访问

  形式:LDAP://Domain

  #region## 是否连接到域
/// <summary>
/// 功能:是否连接到域
/// 作者:Wilson
/// 时间:2012-12-15
/// http://msdn.microsoft.com/zh-cn/library/system.directoryservices.directoryentry.path(v=vs.90).aspx
/// </summary>
/// <param name="domainName">域名或IP</param>
/// <param name="userName">用户名</param>
/// <param name="userPwd">密码</param>
/// <param name="entry">域</param>
/// <returns></returns>
private bool IsConnected(string domainName, string userName, string userPwd, out DirectoryEntry domain)
{
domain = new DirectoryEntry();
try
{
domain.Path = string.Format("LDAP://{0}", domainName);
domain.Username = userName;
domain.Password = userPwd;
domain.AuthenticationType = AuthenticationTypes.Secure; domain.RefreshCache(); return true;
}
catch(Exception ex)
{
LogRecord.WriteLog("[IsConnected方法]错误信息:" + ex.Message);
return false;
}
}
#endregion

  传用参数,调IsConnected方法,结果如下

  

  • 连接上AD域后,接着我们找到根OU
  #region## 域中是否存在组织单位
/// <summary>
/// 功能:域中是否存在组织单位
/// 作者:Wilson
/// 时间:2012-12-15
/// </summary>
/// <param name="entry"></param>
/// <param name="ou"></param>
/// <returns></returns>
private bool IsExistOU(DirectoryEntry entry, out DirectoryEntry ou)
{
ou = new DirectoryEntry();
try
{
ou = entry.Children.Find("OU=" + txtRootOU.Text.Trim()); return (ou != null);
}
catch(Exception ex)
{
LogRecord.WriteLog("[IsExistOU方法]错误信息:" + ex.Message);
return false;
}
}
#endregion

  传入以数,调用IsExistOU方法,结果如下

  

  • 下面来开始读取组织单位及用户的信息。

   示例为了看出层次关系及导出信息是类型区分,给OU和User新建了一个实体类和一个类型的枚举 

    #region## 类型
/// <summary>
/// 类型
/// </summary>
public enum TypeEnum : int
{
/// <summary>
/// 组织单位
/// </summary>
OU = 1, /// <summary>
/// 用户
/// </summary>
USER = 2
}
#endregion #region## Ad域信息实体
/// <summary>
/// Ad域信息实体
/// </summary>
public class AdModel
{
public AdModel(string id, string name, int typeId, string parentId)
{
Id = id;
Name = name;
TypeId = typeId;
ParentId = parentId;
} public string Id { get; set; } public string Name { get; set; } public int TypeId { get; set; } public string ParentId { get; set; }
}
#endregion

   下面读取信息

        private List<AdModel> list = new List<AdModel>();

     #region## 同步
/// <summary>
/// 功能:同步
/// 创建人:Wilson
/// 创建时间:2012-12-15
/// </summary>
/// <param name="entryOU"></param>
public void SyncAll(DirectoryEntry entryOU)
{
DirectorySearcher mySearcher = new DirectorySearcher(entryOU, "(objectclass=organizationalUnit)"); //查询组织单位 DirectoryEntry root = mySearcher.SearchRoot; //查找根OU SyncRootOU(root); StringBuilder sb = new StringBuilder(); sb.Append("\r\nID\t帐号\t类型\t父ID\r\n"); foreach (var item in list)
{
sb.AppendFormat("{0}\t{1}\t{2}\t{3}\r\n", item.Id, item.Name, item.TypeId, item.ParentId);
} LogRecord.WriteLog(sb.ToString()); MessageBox.Show("同步成功", this.Text, MessageBoxButtons.OK, MessageBoxIcon.Information); Application.Exit();
}
#endregion #region## 同步根组织单位
/// <summary>
/// 功能: 同步根组织单位
/// 创建人:Wilson
/// 创建时间:2012-12-15
/// </summary>
/// <param name="entry"></param>
private void SyncRootOU(DirectoryEntry entry)
{
if (entry.Properties.Contains("ou") && entry.Properties.Contains("objectGUID"))
{
string rootOuName = entry.Properties["ou"][0].ToString(); byte[] bGUID = entry.Properties["objectGUID"][0] as byte[]; string id = BitConverter.ToString(bGUID); list.Add(new AdModel(id, rootOuName, (int)TypeEnum.OU, "0")); SyncSubOU(entry, id);
}
}
#endregion #region## 同步下属组织单位及下属用户
/// <summary>
/// 功能: 同步下属组织单位及下属用户
/// 创建人:Wilson
/// 创建时间:2012-12-15
/// </summary>
/// <param name="entry"></param>
/// <param name="parentId"></param>
private void SyncSubOU(DirectoryEntry entry, string parentId)
{
foreach (DirectoryEntry subEntry in entry.Children)
{
string entrySchemaClsName = subEntry.SchemaClassName; string[] arr = subEntry.Name.Split('=');
string categoryStr = arr[0];
string nameStr = arr[1];
string id = string.Empty; if (subEntry.Properties.Contains("objectGUID")) //SID
{
byte[] bGUID = subEntry.Properties["objectGUID"][0] as byte[]; id = BitConverter.ToString(bGUID);
} bool isExist = list.Exists(d => d.Id == id); switch (entrySchemaClsName)
{
case "organizationalUnit": if (!isExist)
{
list.Add(new AdModel(id, nameStr, (int)TypeEnum.OU, parentId));
} SyncSubOU(subEntry, id);
break;
case "user":
string accountName = string.Empty; if (subEntry.Properties.Contains("samaccountName"))
{
accountName = subEntry.Properties["samaccountName"][0].ToString();
} if (!isExist)
{
list.Add(new AdModel(id, accountName, (int)TypeEnum.USER, parentId));
}
break;
}
}
}
#endregion

  调用SyncAll方法循环输出list,结果如下,很清楚的可以看出层次关系

        //ID                                                 帐号             类型    父ID
//58-D6-C4-32-6A-A1-99-48-A4-8B-C8-5D-BC-C9-3E-17 acompany 1 0
//FB-44-91-AE-AC-73-2B-4D-9F-01-B1-E2-16-D3-CB-1B department01 1 58-D6-C4-32-6A-A1-99-48-A4-8B-C8-5D-BC-C9-3E-17
//47-9D-5B-91-60-22-D1-46-B0-CD-C7-B2-C7-D3-00-31 department03 1 FB-44-91-AE-AC-73-2B-4D-9F-01-B1-E2-16-D3-CB-1B
//E3-AD-47-45-38-64-02-4D-B9-83-2C-50-67-50-4F-92 zw 2 47-9D-5B-91-60-22-D1-46-B0-CD-C7-B2-C7-D3-00-31
//8A-D4-23-18-F3-6F-E1-47-93-7A-CC-07-76-4B-E7-86 zhongw 2 FB-44-91-AE-AC-73-2B-4D-9F-01-B1-E2-16-D3-CB-1B
//BC-D0-34-85-67-2F-05-4D-B5-77-E3-F4-AD-51-45-02 department02 1 58-D6-C4-32-6A-A1-99-48-A4-8B-C8-5D-BC-C9-3E-17
//1C-13-FA-66-E4-51-65-49-8B-DC-22-60-32-34-8F-22 wilson 2 BC-D0-34-85-67-2F-05-4D-B5-77-E3-F4-AD-51-45-02
//84-E8-E5-9A-6B-56-E2-45-9A-87-54-D1-78-6B-D3-56 porschev 2 58-D6-C4-32-6A-A1-99-48-A4-8B-C8-5D-BC-C9-3E-17
DirectorySearcher.Filter属性扩充说明

DirectorySearcher mySearcher = new DirectorySearcher(entryOU, "(objectclass=organizationalUnit)"); //查询组织单位

  第二个参数是一个filter,也可以根据需求输入其它筛选条件,下面列出几个常用的

筛选条件
用户 (&(objectCategory=person)(objectClass=user))
计算机 (objectCategory=computer)
(objectCategory=group)
联系人 (objectCategory=contact)
共享文件夹 (objectCategory=volume)
打印机 (objectCategory=printQueue)

更多高级筛选请查看:http://msdn.microsoft.com/zh-cn/library/system.directoryservices.directorysearcher.filter(v=vs.80).aspx

用户属性扩充说明(含图文属性对照)

  示例中只对用户进行了读取了几个属性,用过AD域的应该都知道,用户的属性较多也比较常用。

  下面通过AD域的用户详细信来对照一下相应的属性名

  • 常项选项卡

  

对应编号 选项卡对应项名 属性名
姓(L) sn                                     
名(F) givenName                              
显示名称(S) displayName                            
描述(D) description                            
办公室(C) physicalDeliveryOfficeName             
英文缩写(I) initials                               
电话号码(T) telephoneNumber                        
电子邮件(M) mail                                   
网页(W) wWWHomePage                            
电话号码-其它(O)... otherTelephone                         
网页-其它(R)... url                                    

  

  • 地址选项卡

  

对应编号 选项卡对应项名 属性名
国家/地区(O) co                                      
省/自治区(V) st                                      
市/县(C) l
街道(S) streetAddress
邮政信箱(B) postOfficeBox
邮政编码(Z) postalCode

  

  • 帐户选项卡

  

对应编号 选项卡对应项名 属性名
用户登录名(U) userPrincipalName
用户登录名(Windows 2000 以前版本)(W) sAMAccountName

  

  • 电话选项卡

  

对应编号 选项卡对应项名 属性名
 家庭电话(M) homePhone                               
寻呼机(P) pager
移动电话(B) mobile
传真(F) facsimileTelephoneNumber
IP电话(I) ipPhone
注释 info
家庭电话-其它(O)  otherHomePhone                          
寻呼机-其它(T) otherPager                              
移动电话-其它(B) otherMobile                             
传真-其它(E) otherFacsimileTelephoneNumber           
IP电话-其它(R) otherIpPhone                            
  • 组织选项卡

  

对应编号 选项卡对应项名 属性名
公司(C)                               company                                  
部门(D)    department            
职务(J)                         title
经理-姓名(N)        manager                   
直接下属(E) directReports

  

  还有一些属性没有列出来,可以循环输出DirectoryEntry.Properties.PropertyNames来找

  比如用objectsid这也是个用户比较重要的属性,在设置Windows共享时会用到!

C# AD(Active Directory)域信息同步,组织单位、用户等信息查询的更多相关文章

  1. cmd 执行Dcpromo错误:在该 SKU 上不支持 Active Directory 域服务安装向导,Windows Server 2008 R2 Enterprise 配置AD(Active Directory)域控制器

    今天,要安装AD域控制器,运行dcpromo结果提示:在该 SKU 上不支持 Active Directory 域服务安装向导. 以前弄的时候直接就通过了,这次咋回事?终于搞了大半天搞定了. 主要原因 ...

  2. Windows Server 2008 R2 配置AD(Active Directory)域控制器

    实施过程: 一.安装Windows Server2008 R2操作系统 (过程略) 二.安装域控制器 1. 修改电脑名称 2.修改电脑DNS 三.配置AD 1.在"服务器管理器"- ...

  3. Windows Server 2008 R2 配置AD(Active Directory)域控制器 -zhai zi wangluo

    http://files.cnblogs.com/zhongweiv/Windows_Server_2008_R2_%E9%85%8D%E7%BD%AEActive_Directory%E5%9F%9 ...

  4. Active Directory 域服务 (AD DS) 虚拟化

    TechNet 库 Windows Server Windows Server 2012 R2 和 Windows Server 2012 服务器角色和技术 Active Directory Acti ...

  5. 介绍 Active Directory 域服务 (AD DS) 虚拟化

    TechNet 库 Windows Server Windows Server 2012 R2 和 Windows Server 2012 服务器角色和技术 Active Directory Acti ...

  6. Active Directory 域服务(AD DS)

    本文内容 概述 工作组架构与域架构 名称空间(Namespace) 对象(Object).容器(Container)与组织单位(Organization Units,OU) 域树(Domain Tre ...

  7. 域知识深入学习一:Active Directory 域服务

      AD DS用来组织,管理,控制网络资源 1.1 Active Directory 域服务概述 AD内的directorydatabase(目录数据库)用来存储用户账户,计算机账户,打印机与共享文件 ...

  8. 建立 Active Directory域 ----学习笔记

    第五章 建立 Active Directory域 1.工作组和域的理解 ​ a.工作组是一种平等身份环境,各个计算机之间各个为一个独立体,不方便管理和资源共享. ​ b.域环境一般情况下满足两类需求, ...

  9. install Active Directory域控制器

    设置Active Directory域控制器 正如我们在网络与系统配置专题文章中所提到的那样,我们已将两部服务器设置为对应于内部域“intdomain.com”的Active Directory域控制 ...

随机推荐

  1. js模版引擎handlebars.js实用教程——如何引入Handlebars.js

    返回目录 Jquery插件,第一步当然要引用Jquery啦,然后引用Handlebars.js即可,仅仅需要这两个js文件. <script type="text/javascript ...

  2. Java序列化格式详解

    RPC的世界,由于涉及到进程间网络远程通信,不可避免的需要将信息序列化后在网络间传送,序列化有两大流派: 文本和二进制. 文本序列化 序列化的实现有很多方式,在异构系统中最常用的就是定义成人类可读的文 ...

  3. java.sql.SQLException: JZ00L

    出现, java.sql.SQLException: JZ00L: 登录失败.检查与此异常现象有关的 SQL 警告以获得失败原因. at com.sybase.jdbc3.jdbc.ErrorMess ...

  4. EF架构~为导航属性赋值时ToList()的替换方案

    回到目录 今天在进行EF开发时,遇到一个问题,在进行join查询时,类中的一个集合类型的导航属性,在给它赋值时,将查询出来的结果ToList()后,出错了,linq to entity不支持这种操作, ...

  5. Atitit 函数式编程与命令式编程的区别attilax总结  qbf

    Atitit 函数式编程与命令式编程的区别attilax总结  qbf 1.1. 函数式程序就是一个表达式.命令式程序就是一个冯诺依曼机的指令序列. 命令式编程是面向计算机硬件的抽象,有变量(对应着存 ...

  6. gulp/grunt和browserify/webpack的区别

    Gulp应该和Grunt比较,他们的区别我就不说了,说说用处吧.Gulp / Grunt 是一种工具,能够优化前端工作流程.比如自动刷新页面.combo.压缩css.js.编译less等等.简单来说, ...

  7. LigerUI学习使用

    LigerUI有如下主要特点: 使用简单,轻量级 控件实用性强,功能覆盖面大,可以解决大部分企业信息应用的设计场景 快速开发,使用LigerUI可以比传统开发减少极大的代码量 易扩展,包括默认参数.表 ...

  8. python--基础学习(二)判断 、循环、定义函数、继承、调用

    1.判断 if.elif 代码示范 # coding=utf-8 score = 90 if (score>=90): print("完美") print("优秀& ...

  9. 后端码农谈前端(CSS篇)第七课:定位与浮动

    一.定位: 1.定位的理解 (1)相对定位 相对定位是一个非常容易掌握的概念.如果对一个元素进行相对定位,它将出现在它所在的位置上.然后,可以通过设置垂直或水平位置,让这个元素"相对于&qu ...

  10. Anliven - 解决问题的一些方法

    How to resolve the problem? 获取基本的相关信息(后续处理问题的基础)  在怎样的背景环境下?发生了怎样的问题? 如果无法清楚地辨别或陈述问题的基本信息,那么,此时要面对的将 ...