C# 操作 AD

AD对查询进行了优化,所以查询起来还是比较快的。

1、LDAP查询语法

LDAP中操作符有&(逻辑与),|(逻辑或), !(逻辑非),=(等于),*(通配符)。LDAP操作符的使用有点不同。

l  &符号,查找类型为user,cn为oo的用户

示例: (&(objectClass=user)(cn=oo)))。

l  !符号,查找cn不是oo的用户、组等其他类型

示例:(!cn=oo)。

l  |符号,查找类型为user,cn为oo或者为xi的用户

示例:(&(obectClass=user)(|(cn=oo)(cn=xi)))。

l  *符号,查找cn以oo开始的用户

示例:(&(objectClass=user)(cn=oo*))

 

C#读取AD数据

l  Web.config配置如下:

test1:AD所在的计算机名称

          contoso:域名

  1. <add key="LDAPPath" value="LDAP://test1/DC=contoso,DC=com" />  
  2. <add key="LDAPUser" value="contoso/bot" />  
  3. <add key="LDAPPassword" value="123456" />  
  4. <add key="OUName" value="天机集团有限公司"/>  

<add key="LDAPPath" value="LDAP://test1/DC=contoso,DC=com" /> <add key="LDAPUser" value="contoso/bot" /> <add key="LDAPPassword" value="123456" /> <add key="OUName" value="天机集团有限公司"/>

l  连接AD

  1. DirectoryEntry  searchRoot = new DirectoryEntry(LDAPPath, LDAPUser, LDAPPassword, AuthenticationTypes.Secure);  

DirectoryEntry searchRoot = new DirectoryEntry(LDAPPath, LDAPUser, LDAPPassword, AuthenticationTypes.Secure);

l  查询指定的用户

  1. DirectorySearcher directorySearch = new DirectorySearcher(SearchRoot);  
  2. directorySearch.Filter = "(&(objectClass=user)(cn=" + userName + "))";  
  3. SearchResult results = directorySearch.FindOne();   
  4. if (results != null)  
  5. {  
  6.           DirectoryEntry user = results.GetDirectoryEntry();  
  7.  }  

DirectorySearcher directorySearch = new DirectorySearcher(SearchRoot); directorySearch.Filter = "(&(objectClass=user)(cn=" + userName + "))"; SearchResult results = directorySearch.FindOne(); if (results != null) { DirectoryEntry user = results.GetDirectoryEntry(); }

objectClass:指定查找的类型,user(代表查找用户),AD中的类型有很多。比如user , organizationalUnit,group等。很多软件还会对AD的类型进行扩展, Exchange就会对AD的schema进行扩展。

cn: 是user类型的一个属性,即CommonName。也就是说我们查找的是类型为user,cn为userName的用户。

那AD中到底有多少类型以及多少属性呢,我们可以打开开始->管理工具->ADSI编辑器。然后在ADSI编辑器上点击右键->连接。弹出连接设置对话框,在选择一个已知命名上下文的下拉框中选择架构,然后点击确定,我们就可以看到所有的类型和属性。在一个类型上进行双击,会弹出类型的属性编辑器,可以看到类型所有的属性,并可以进行编辑。

l  使用代码查看类型的属性

当然我们也可以使用代码来查看类型的属性,但是只能查看设定了值的属性,没有设定值的属性还不知道怎么查看。比如以下代码,可以输出user类型的一些属性。知道属性的名称和属性的值之后就可以更好的设定一些查询条件。

  1.  DirectoryEntry m_DirectoryEntry = new DirectoryEntry(LDAPPath, LDAPUser, LDAPPassword, AuthenticationTypes.Secure);  
  2.  DirectorySearcher directorySearch = new DirectorySearcher(searchRoot);  
  3.  directorySearch.Filter = "(&(objectClass=user)(cn=test))";  
  4.         SearchResult results = directorySearch.FindOne();  
  5.  DirectoryEntry entry = results.GetDirectoryEntry();  
  6.  foreach (string pro in entry.Properties.PropertyNames)  
  7. {  
  8.   Console.WriteLine(entry.Properties[pro].PropertyName + ".........." + entry.Properties[pro].Value.ToString());  
  9. }  

DirectoryEntry m_DirectoryEntry = new DirectoryEntry(LDAPPath, LDAPUser, LDAPPassword, AuthenticationTypes.Secure); DirectorySearcher directorySearch = new DirectorySearcher(searchRoot); directorySearch.Filter = "(&(objectClass=user)(cn=test))"; SearchResult results = directorySearch.FindOne(); DirectoryEntry entry = results.GetDirectoryEntry(); foreach (string pro in entry.Properties.PropertyNames) { Console.WriteLine(entry.Properties[pro].PropertyName + ".........." + entry.Properties[pro].Value.ToString()); }

l  查询指定OU的代码。

  1. DirectorySearcher directorySearch = new DirectorySearcher(SearchRoot);  
  2. directorySearch.Filter = "(&(objectClass=organizationalUnit)(ou=" + ouName + "))";  
  3. SearchResult results = directorySearch.FindOne();  
  4. if (results != null)  
  5. {  
  6.     DirectoryEntry entry = results.GetDirectoryEntry();  
  7. }  

DirectorySearcher directorySearch = new DirectorySearcher(SearchRoot); directorySearch.Filter = "(&(objectClass=organizationalUnit)(ou=" + ouName + "))"; SearchResult results = directorySearch.FindOne(); if (results != null) { DirectoryEntry entry = results.GetDirectoryEntry(); }

l  查询指定OU的下的子OU。

  1. foreach (DirectoryEntry entry in root.Children)  
  2. {  
  3.     if (entry.SchemaClassName.Equals("organizationalUnit"))  
  4.     {  
  5.         // 自己的代码   
  6.     }  
  7. }  

foreach (DirectoryEntry entry in root.Children) { if (entry.SchemaClassName.Equals("organizationalUnit")) { // 自己的代码 } }

Root的类型为DirectoryEntry,所以首先需要查询出指定的OU,获取DirectoryEntry实例。DirectoryEntry实例有一个Children属性,包含所有的子元素。通过遍历所有的子元素,并判断ShcemaClassName是不是"organizationalUnit",如果是就代表该子元素为OU。

当然查询的OU可能不止一个,我们可以使用FindAll()方法进行查询。

SearchResultCollection userCollection = directorySearch.FindAll();

            foreach (SearchResult users in userCollection)

查询之后我们获得一个SearchResult集合,对SearchResult集合进行遍历,就可以获得所有的OU了。

那如果想获取OU下的子user或者group怎么办呢,只需要修改代码如下

entry.SchemaClassName.Equals("user") //类型为user

entry.SchemaClassName.Equals("group") //类型为group

l  获取指定OU下的指定用户呢,

a)         可以把查询条件些的更精确一点。以下代码,我们可以获取cn为test的用户了。

 

DirectoryEntry  searchRoot = new DirectoryEntry("LDAP://test1/CN=test,CN=Users,DC=contoso,DC=com", LDAPUser, LDAPPassword);

 

b)         首先获取指定OU的DirectoryEntry实例,再把获取的实例作为参数,传入到DirectorySearcher得构造函数中,进行查询。

DirectorySearcher directorySearch = new DirectorySearcher(entry);

l  获取指定的group。

DirectorySearcher directorySearch = new DirectorySearcher(SearchRoot);

                directorySearch.Filter = "(&(objectClass=group)(SAMAccountName=" + groupName + "))";

                SearchResult results = directorySearch.FindOne();

SAMAccountName:是group类型的一个属性。

 

获取group下的所有用户

  1. DirectorySearcher directorySearch = new DirectorySearcher(SearchRoot);  
  2. directorySearch.Filter = "(&(objectClass=group)(SAMAccountName=" + groupName + "))";  
  3. SearchResult results = directorySearch.FindOne();   
  4. if (results != null)  
  5. {  
  6.     DirectoryEntry dirEntry = new DirectoryEntry(results.Path, LDAPUser, LDAPPassword);  
  7.     PropertyCollection propertyCollection = dirEntry.Properties;   
  8.     int count = propertyCollection ["member"].Count;   
  9.     for (int i = 0; i < count; i++)  
  10.     {  
  11.         string respath = results.Path;   
  12.         string[] pathnavigate = respath.Split("CN".ToCharArray());  
  13.         respath = pathnavigate[0];   
  14.         string objpath = propertyCollection["member"][i].ToString();   
  15.         string path = respath + objpath;  
  16.         DirectoryEntry user = new DirectoryEntry(path, LDAPUser, LDAPPassword);  
  17.     }  
  18. }  

DirectorySearcher directorySearch = new DirectorySearcher(SearchRoot); directorySearch.Filter = "(&(objectClass=group)(SAMAccountName=" + groupName + "))"; SearchResult results = directorySearch.FindOne(); if (results != null) { DirectoryEntry dirEntry = new DirectoryEntry(results.Path, LDAPUser, LDAPPassword); PropertyCollection propertyCollection = dirEntry.Properties; int count = propertyCollection ["member"].Count; for (int i = 0; i < count; i++) { string respath = results.Path; string[] pathnavigate = respath.Split("CN".ToCharArray()); respath = pathnavigate[0]; string objpath = propertyCollection["member"][i].ToString(); string path = respath + objpath; DirectoryEntry user = new DirectoryEntry(path, LDAPUser, LDAPPassword); } }     

 

用户是是不能通过group的Children属性来进行获取。组有一个属性就是member,member中存储了所有用户的路径,比如CN=test,CN=Users,DC=contoso,DC=com。

想获取group隶属于哪个组,只需要把member修改为memberOf就可以了。当然我们也可以通过这种方式,查找一个用户所属的组

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值