Actiove Directory的DirectoryEntry与DirectorySearcher初识及Filter语法
Posted IFire47
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Actiove Directory的DirectoryEntry与DirectorySearcher初识及Filter语法相关的知识,希望对你有一定的参考价值。
前言
增删改查,我想查询是最先要说的一个了。本章主要记录使用.NET Framework进行对域控服务器对象的查询操作,介绍DirectoryEntry与DirectorySearcher(搜索器)及Filter(搜索过滤器)语法,并对AD对象常用属性做记录。
DirectoryEntry与DirectorySearcher
使用C#语言对域控服务器的AD对象进行查询操作,DirectoryEntry和DirectorySearcher是必须要了解的两个类。System.DirectoryServices 命名空间用以从托管代码简便地访问 Active Directory。该命名空间包含了两个组件类,即DirectoryEntry和DirectorySearcher,它们使用AD服务接口(ADSI)技术。
DirectoryEntry:我们知道Active Directory中的数据是树状的,并且是层次型存储。而DirectoryEntry类就是为了封装 Active Directory 层次结构中的节点或对象。使用此类绑定到对象、读取属性和更新特性。DirectoryEntry 与帮助器类一起为生存期管理和导航方法提供支持,包括创建、删除、重命名、移动子节点和枚举子级。
https://msdn.microsoft.com/zh-cn/library/system.directoryservices.directoryentry_members(v=vs.80).aspx
DirectorySearcher:顾名思义这个对象是主要执行针对Active Directory域服务的查询。
https://msdn.microsoft.com/zh-cn/library/system.directoryservices.directorysearcher(v=vs.110).aspx
目前我的域控服务器在域上AD对象结构如下:
一段示例代码,目的是查询用户李四
1 static void Main(string[] args) 2 { 3 //声明一个AD对象搜索器 4 DirectorySearcher searcher = new DirectorySearcher(); 5 //设置此搜索器的搜索起点 6 searcher.SearchRoot = DomainRootEntry(); 7 //设置此搜索器的搜索语句 8 searcher.Filter = "(&(objectClass=user)(name=李四))"; 9 //设置此搜索器的查询范围 10 searcher.SearchScope = SearchScope.Subtree; 11 //执行查询,有FindOne与FindAll之别 12 SearchResult result = searcher.FindOne(); 13 if (result != null) 14 { 15 //转换为李四对象 16 DirectoryEntry userEntry = result.GetDirectoryEntry(); 17 } 18 } 19 /// <summary> 20 /// 域控服务器IP 21 /// </summary> 22 private static string DomainServiceIP = "192.168.241.3"; 23 /// <summary> 24 /// 域控服务器用户名 25 /// </summary> 26 private static string UserName = @"Domain"; 27 /// <summary> 28 /// 域控服务器密码 29 /// </summary> 30 private static string Password = "p@ssw0rd"; 31 32 /// <summary> 33 /// 获取域控服务器中域节点对象 34 /// </summary> 35 public static DirectoryEntry DomainRootEntry() 36 { 37 DirectoryEntry rootEntry = null; 38 try 39 { 40 rootEntry = new DirectoryEntry("LDAP://" + DomainServiceIP, UserName, Password); 41 return rootEntry; 42 } 43 catch (Exception ex) 44 { 45 throw ex; 46 } 47 }
这里的DirectoryEntry对象封装 Active Directory 域层次结构中的节点对象。通过DirectorySearcher搜索器来查询用户李四。如代码所示DirectorySearcher对象使用有几个地方要了解。
SearchRoot:获取或设置一个值(DirectoryEntry对象,一般为DC或者OU),该值指示 Active Directory 域服务层次结构中的节点,从该节点处开始搜索。说白了就是说我这个查询器查询从这个节点开始向下查询包括这个节点。
SearchScope:获取或设置指示服务器遵循的搜索范围的值。为SearchScope的enmu类型。
1 //指定使用 System.DirectoryServices.DirectorySearcher 对象执行的目录搜索的可能范围。 2 public enum SearchScope 3 { 4 // 将搜索限于基对象。结果最多包含一个对象。当 System.DirectoryServices.DirectorySearcher.AttributeScopeQuery 5 // 属性指定用于某一搜索时,搜索范围必须设置为 System.DirectoryServices.SearchScope.Base。 6 Base = 0, 7 // 搜索基对象的直接子对象,但不搜索基对象。 8 OneLevel = 1, 9 // 搜索整个子树,包括基对象及其所有子对象。如果未指定目录搜索的范围,则执行 System.DirectoryServices.SearchScope.Subtree 10 // 类型的搜索。 11 Subtree = 2 12 }
FindOne();与FindAll();的区别:FindOne执行搜索返回搜索过程中找到的第一项,返回结果为一个System.DirectoryServices.SearchResult对象。而FindAll执行搜索并返回找到的项的集合,返回结果是System.DirectoryServices.SearchResultCollection对象。
剩下的就是这个Filter比较复杂了,我们继续往下看。
Filter语法详解及属性扩充
Filter:(官方解读为:搜索过滤器)它为DirectorySearcher(搜索器)定义一个搜索条件,为的是使我们的搜索器更有效的搜索。有点像ADO中的T-SQL语句。Filter属性值以 LDAP 格式表示的筛选条件,用Unicode字符串表示。下表列出了一些例子。
Search filter(搜索过滤器) | Description(描述) |
"(objectClass=*)" | 所有的对象。 |
"(&(objectCategory=person)(objectClass=user)(!cn=andy))" | 所有的用户对象,但“andy”除外 |
"(sn=sm*)" | 所有对象的满足姓氏从“SM”开头。 |
"(&(objectClass=user)(name=李四))" | 所有名称为李四的用户对象 |
Filter语法详解:
表达式:属性名=Value
通配符:“*”,该字符出现在表达式Value中,匹配该字符位置后的内容,类似于SQL中的“%”;例子如下:
|
Description(描述) | |
”(objectClass=*)“ | 得到所有对象 | |
“(cn=*bob*)” | 得到的对象,名称含有“bob”: | |
”(&(objectClass=user)(email=*))“ | 得到包含电子邮件属性的所有用户: |
逻辑运算符:
Logical operator(逻辑运算符) | Description(描述) |
= | 等于 |
& | 和 |
| | 或 |
! | 非 |
~= | 约等于 |
<= | 字典序小于或者等于 |
>= | 字典序大于或者等于 |
语法类型:(Key=Value)为一个表达式,两个表达式满足某些条件(|或、&且、!非)则放在两个表达前面并用括号括起来。如:(&(objectClass=user)(mobile=132*)) ,电话为132开头的所有用户。(&(表达式1=value)(表达式2=value)),该filter结果为取表达式1和表达式2同时匹配的内容。
特殊字符:如果以下任何特殊字符必须出现在搜索过滤的文字中,他们必须通过的转义替换。
ASCII字符 | 转义替代 |
* | \\2a |
( | \\28 |
) | \\29 |
\\ | \\5c |
NULL | \\00 |
/ | \\2f |
DirectorySearcher.Filter类型属性扩充说明(不区分大小写):
筛选条件 | 值 |
域 | (objectClass=domainDNS) |
组织单位 | (objectClass=organizationalUnit) |
用户 | (&(objectCategory=person)(objectClass=user))或者(&(objectClass=User)(!objectClass=computer)) |
计算机 | (objectCategory=computer) |
组 | (objectCategory=group) |
联系人 | (objectCategory=contact) |
共享文件夹 | (objectCategory=volume) |
打印机 | (objectCategory=printQueue) |
以上是一些常用类型检索条件,值得注意的是(objectClass=user)并不只是检索用户还包括计算机。所以要要做处理。当然检索的条件不知以上这些。AD中对象的属性都可以做检索条件,我们最后看看AD中的对象属性有哪些是我们常用的。
Active Directory常用属性
用户(User)常用选项卡中的属性
选项卡项名 | 属性名 | 备注 |
名称 | name | 在同一节点下唯一,string |
姓(L) | sn | string |
名(F) | givenName | string |
英文缩写(I) | initials | string |
显示名称(S) | displayName | 域内不唯一,但是在同一个组织单位内唯一 |
描述(D) | description | string[] |
办公室(C) | physicalDeliveryOfficeName | string |
电话号码(T) | telephoneNumber | string |
电子邮件(M) | string | |
网页(W) | wWWHomePage | string |
选项卡项名 | 属性名 | 备注 |
用户登录名(U) | userPrincipalName | 全域内唯一,string |
用户登录名(Windows 2000 以前版本)(W) | sAMAccountName | 全域内唯一,string |
选项卡项名 | 属性名 | 备注 |
国家/地区(O) | co | string |
省/自治区(V) | st | string |
市/县(C) | l | string |
街道(S) | streetAddress | string |
邮政信箱(B) | postOfficeBox | string[] |
邮政编码(Z) | postalCode | string |
选项卡项名 | 属性名 | 备注 |
家庭电话(M) | homePhone | string |
寻呼机(P) | pager | string |
移动电话(B) | mobile | string |
传真(F) | facsimileTelephoneNumber | string |
IP电话(I) | ipPhone | string |
注释 | info | string |
选项卡项名 | 属性名 | 备注 |
公司(C) | company | string |
部门(D) | department | string |
职务(J) | title | string |
经理-姓名(N) | manager | string |
直接下属(E) | directReports | string[] |
组织单位(Organizational Unit)常用选项卡中的属性
选项卡项名 | 属性名 | 备注 |
名称 | name | 在同一节点下唯一,string |
描述(D) | description | string[] |
国家/地区(O) | co | string |
邮政编码(Z) | postalCode | string |
省/自治区(V) | st | string |
市/县(C) | l | string |
街道(S) | street | string |
Active Directory的隐藏通用属性
这一部分属性,在选项卡上是看不到的,必须在【属性编辑器】中才能查看到:
属性 | 备注 |
objectGUID | 全域内唯一,对象创建时自动生成的,16进制所以在DirecotryEntry中接受时要做数据处理。 |
distinguishedName | 全域内唯一,对象创建或者移动时自动生成。详细请看上章。 |
objectClass | 对象创建时自动创建 |
cn | 常用于User或者Computer,与name相同。 |
ou | 常用于Ou,与name同属性。 |
大约整理出这些常用属性,若想查看更多有两种方式:第一种查看属性的属性编辑器,第二种遍历DirectoryEntry.Properties.PropertyNames;
结语
这些属性根据业务场景不同用的多少也会不同。有时候可能会使用一些不常用的属性存储与业务处理有关的数据,因为AD中的数据存储不想关系型数据库,所以在AD中一些不常用的属性我们会根据不同业务场景去为逻辑变成做铺垫。Filter语法的话其实和LDAP协议有着很密切的关系但这里就不说了。主要是DirectoryEntry和DirectorySearcher这两个类对象,在后面DirectoryEntry做AD编程时将无处不在,它是一个入口。鉴于目前.NET Core 没有更新System.DirectoryServices;。所以以后若使用PowerShell那就另外再说了。
本章最后更新时间:2017年4月23日18:10:13
作者:IFire47 出处:http://www.cnblogs.com/IFire47/
以上是关于Actiove Directory的DirectoryEntry与DirectorySearcher初识及Filter语法的主要内容,如果未能解决你的问题,请参考以下文章
为啥有时 Directory.CreateDirectory 会失败?