Actiove Directory组织单位(Organization Unit)操作汇总

前言

本章聊Actiove Directory的组织单位(OU)的新增、修改、移动等操作,使用.NET Framework 为我们提供的System.DirectoryServices程序集。

不积跬步无以至千里。Actiove Directory开发系列将在本章开始侧重于代码(有部分人肯定很高兴了,可以COPY嘛),因为个人认为必要的理论知识和基础代码在前面已经记录了很多,这章开始若有不理解的地方请回看以前的文章。

封装基础ADHelper

这段ADHelper 是为了后面组织单位的新增,修改,移动而准备的代码段,在实际项目开发中当然是不够看的,不过讲本章涉及内容已经足够了。

 1     public class ADHelper
 2     {
 3         #region 构造单例
 4         private ADHelper() { }
 5         public static readonly ADHelper Instance = new ADHelper();
 6         #endregion
 7         #region  公共属性
 8         private static string DomainServiceIP = "192.168.241.3";
 9         private static string UserName = @"Domain";
10         private static string Password = "[email protected]";
11         private DirectoryEntry rootEntry = null;
12         #endregion
13         #region 公共方法
14         /// <summary>
15         /// 域节点DirectoryEntry对象
16         /// </summary>
17         public DirectoryEntry DomainRootEntry
18         {
19             get
20             {
21                 if (rootEntry == null)
22                 {
23                     try
24                     {
25                         rootEntry = new DirectoryEntry("LDAP://" + DomainServiceIP, UserName, Password);
26                     }
27                     catch (Exception ex)
28                     {
29
30                         throw ex;
31                     }
32                 }
33                 return rootEntry;
34             }
35         }
36         /// <summary>
37         /// AD查询器公共方法封装
38         /// </summary>
39         /// <typeparam name="T">DirectorySearcher或SearchResultCollection</typeparam>
40         /// <param name="SearchRoot">查询器的查询起点</param>
41         /// <param name="Filter">查询过滤器</param>
42         /// <param name="SearchScope">查询方式</param>
43         /// <returns></returns>
44         public T GetSearchResultOrSearchCollection<T>(DirectoryEntry SearchRoot, string Filter, SearchScope SearchScope) where T : class
45         {
46             DirectorySearcher Searcher = new DirectorySearcher();
47             if (SearchRoot == null)
48                 SearchRoot = DomainRootEntry;
49             using (SearchRoot)
50             {
51                 try
52                 {
53                     Searcher.Filter = Filter;
54                     Searcher.SearchRoot = SearchRoot;
55                     Searcher.SearchScope = SearchScope;
56                     if (typeof(T).Name == "SearchResult")
57                         return Searcher.FindOne() as T;
58                     else
59                         return Searcher.FindAll() as T;
60                 }
61                 catch (Exception ex)
62                 {
63
64                     throw ex;
65                 }
66             }
67         }
68         /// <summary>
69         /// 获取DirectoryEntry对象
70         /// </summary>
71         /// <param name="proterEntry">查询起点</param>
72         /// <param name="filter">查询条件</param>
73         /// <returns></returns>
74         public DirectoryEntry GetEntry(DirectoryEntry proterEntry, string filter)
75         {
76             SearchResult SearchResult = GetSearchResultOrSearchCollection<SearchResult>(proterEntry, filter, SearchScope.Subtree);
77             if (SearchResult != null)
78                 return SearchResult.GetDirectoryEntry();
79             else
80                 return DomainRootEntry;
81         }
82         #endregion
83     }

这段ADHelper代码顾名思义其实和SQLHelper一样,是对AD操作的最基础层的一段代码,如果前面的文章有仔细了解过,那么这段代码我相信应该不成问题,只不过是做了封装而已,我们将主要精力放在后面实际的操作OU上吧。

我们还要再封装一个组织单位的实体类方便我们使用。

 1     public class ADOrgUnit
 2     {
 3         #region 属性
 4         /// <summary>
 5         /// GUID
 6         /// </summary>
 7         public string ObjectGuid { get; set; }
 8         /// <summary>
 9         /// 标示名
10         /// </summary>
11         public string DistinguishedName { get; set; }
12         /// <summary>
13         /// OU
14         /// </summary>
15         public string Ou { get; set; }
16         /// <summary>
17         /// 描述
18         /// </summary>
19         public string Description { get; set; }
20         #endregion
21     }

我的测试域控服务器如下:

如果之前的文章有做过了解,看到图片上的数据排列,我们完全可以推算出某AD对象的DN。

新增组织单位(OU)

我们目标是在域节点创建新的OU,如果之前的文章有理解,那么我们可以直接判断出DomainDNS的DN为:DC=IFire47,DC=com

 1         static void Main(string[] args)
 2         {
 3             ADOrgUnit adOrgUnit = new ADOrgUnit();
 4             //新增OU的名称
 5             adOrgUnit.Ou = "IFire47";
 6             //新增OU的描述
 7             adOrgUnit.Description = "IFire47测试组织单位";
 8             try
 9             {
10                 //我们在域节点创建新的组织单位,所以根据封装的ADHelper调用此方法。
11                 using (DirectoryEntry parentEntry = ADHelper.Instance.DomainRootEntry)
12                 {
13                     //创建新OU,并接受新OU的DiectoryEntry对象
14                     DirectoryEntry ouEntry = parentEntry.Children.Add("ou=" + adOrgUnit.Ou, "organizationalUnit");
15                     //为创建的新OU赋值属性
16                     if (!String.IsNullOrEmpty(adOrgUnit.Description))
17                         ouEntry.Properties["description"].Value = adOrgUnit.Description;
18                     //保存
19                     ouEntry.CommitChanges();
20                 }
21             }
22             catch (Exception ex)
23             {
24                 throw ex;
25             }
26         }

因为我们是在域节点创建的新OU我们看下新OU的DN属性

这跟之前文章讲解不谋而合,所以在这里我们将从实际代码测试中对LDAP和DN的概念有更进一步的认识与理解。对于这块代码的理解,这是我根据.NET的提示及个人理解做的整理:

 1         // 摘要:获取 Active Directory 域服务层次结构中此节点的子项。
 2         // 返回结果:一个 System.DirectoryServices.DirectoryEntries 对象,其中包含 Active Directory 域服务层次结构中此节点的子项。
 3         [Browsable(false)]
 4         [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
 5         [DSDescription("DSChildren")]
 6         public DirectoryEntries Children { get; }
 7         // 摘要: 在容器中创建一个新项。
 8         // name:新项名称。
 9         // schemaClassName:用于此新项的架构名称。即新创建的对象类别,详细查看上章
10         // 返回结果:新项的 System.DirectoryServices.DirectoryEntry 对象。
11         public DirectoryEntry Add(string name, string schemaClassName);
12         // 摘要:获取此 System.DirectoryServices.DirectoryEntry 对象的 Active Directory 域服务属性。
13         // 返回结果:一个 System.DirectoryServices.PropertyCollection 对象,包含此项所设属性。
14         [Browsable(false)]
15         [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
16         [DSDescription("DSProperties")]
17         public PropertyCollection Properties { get; }
18         //摘要: 将目录项所作更改保存到基础目录存储中。
19         public void CommitChanges();

修改组织单位(OU)

我们修改刚才新添加的OU的名称及描述属性

 1       static void Main(string[] args)
 2         {
 3             ADOrgUnit adOrgUnit = new ADOrgUnit();
 4             //修改OU的新名称
 5             adOrgUnit.Ou = "IceFire47";
 6             //修改OU的新描述
 7             adOrgUnit.Description = "IceFire47测试组织单位";
 8             //所要修改的OU的DN属性
 9             adOrgUnit.DistinguishedName = "OU=IceFire47,DC=IFire47,DC=com";
10             try
11             {
12                 DirectoryEntry ouEntry = GetEntryByOrgDN(adOrgUnit.DistinguishedName);
13                 if (!string.IsNullOrEmpty(adOrgUnit.Ou))
14                 {
15                     ouEntry.Rename("ou=" + adOrgUnit.Ou);
16                     ouEntry.CommitChanges();
17                 }
18                 //修改描述属性,属性是数组类型的,要做一系列容错判断
19                 if (ouEntry.Properties.Contains("description"))//判断是否存在这个属性
20                 {
21                     if (adOrgUnit.Description != null && !string.IsNullOrEmpty(adOrgUnit.Description))//描述是否为空
22                         ouEntry.Properties["description"][0] = adOrgUnit.Description;//不空修改属性
23                     else//
24                         ouEntry.Properties["description"].RemoveAt(0);//为空移除描述属性
25                 }
26                 else
27                 {
28                     if (adOrgUnit.Description != null && !string.IsNullOrEmpty(adOrgUnit.Description))//不为空添加属性
29                         ouEntry.Properties["description"].Add(adOrgUnit.Description);
30                 }
31                 //保存
32                 ouEntry.CommitChanges();
33             }
34             catch (Exception ex)
35             {
36                 throw ex;
37             }
38         }
39         /// <summary>
40         /// 根据OU的DN属性值查询OU对象
41         /// </summary>
42         /// <param name="distinguishedName">DN属性值</param>
43         /// <returns></returns>
44         public static DirectoryEntry GetEntryByOrgDN(string distinguishedName)
45         {
46             string filter = "(&(objectClass=organizationalUnit)(distinguishedName=" + distinguishedName + "))";
47             return ADHelper.Instance.GetEntry(null, filter);
48         }

这的逻辑根据自身的业务场景可以做调整,并不一定要根据DN去查询然后修改,也可以根据name等属性查询,只不过要修改Filter并修改传值。而且我们修改了这个OU对象后,它的DN也将自动修改,因为我们定义了新的OU名称。

这里的赋值做了一系列的判断,是因为AD对象的属性并不一定是String还有可能是String[],从属性编辑器中看下描述属性如下,所以直接赋值保存做判断后赋值修改时直接追加根据自身业务场景而定。

移动组织单位(OU)

我们将刚才修改的OU移动北京分公司的OU当中

 1       static void Main(string[] args)
 2         {
 3             //需要移动的OU的DN
 4             string OrgUnitDN = "OU=IceFire47,DC=IFire47,DC=com";
 5             //要移动到的容器的DN,这里不一定是OU也可以是域节点
 6             string targetOrgDN = "OU=北京分公司,DC=IFire47,DC=com";
 7             using (DirectoryEntry ouEntry = GetEntryByOrgDN(OrgUnitDN))
 8             {
 9                 using (DirectoryEntry targetOU = GetEntryByOrgDN(targetOrgDN))
10                 {
11                     try
12                     {
13                         ouEntry.MoveTo(targetOU);
14                         ouEntry.CommitChanges();
15                     }
16                     catch (Exception ex)
17                     {
18                         throw ex;
19                     }
20                 }
21             }
22         }
23         /// <summary>
24         /// 根据OU的DN查询OU对象
25         /// </summary>
26         /// <param name="distinguishedName">DN属性</param>
27         /// <returns></returns>
28         public static DirectoryEntry GetEntryByOrgDN(string distinguishedName)
29         {
30             string filter = "(&(objectClass=organizationalUnit)(distinguishedName=" + distinguishedName + "))";
31             return ADHelper.Instance.GetEntry(null, filter);
32         }

在移动OU时,新OU的DN也将自动改变。同理,这里的一部分逻辑也并不是固定的,我们也可以根据自身业务场景做调整,关键还是在获取DirectoryEntry对象根据项目需求而定。而且OU的移动智能在域节点或者另一个OU中,不能将组织单位移动到某个组或者用户或者计算机中,而且需要注意的是,当OU移动时,移动的OU内的所有对象将一起被移动。

结语

本章主要是讲解AD中组织单位的一系列操作,有一个删除没说是因为在.NET Framework 并没有对我们提供删除操作。这里的所有实例都没有做判断处理,比如说新建OU时要判断当前节点下是否存在同名的OU存在若存在则不能创建等等,因为从之前的文章中已经讲解过DN在全局是唯一的,这就意味着在同一节点中不可能存在同名的OU,在不同OU中可以存在同名OU,因为就算同名但是他们的DN是不一样的。在这对属性赋值的判断和什么样的属性做判断什么样的属性不需要可以直接赋值,取决于Windowsd对具体AD对象的定义,我将会抽空在上一篇的常用属性注释中做标注。而OU对象转换成.NET中的实体对象则在User具体操作章节一起讲解,因为都是操作DirectoryEntry对象,所以都是一样的。只不过可能加载的DirectoryEntry属性集会根据OU或User等有一些区别,但是整体的转换过程都是一样的。以上是本章全部内容,明天还要上班睡觉。

本章最后更新时间:2017年4月24日00:25:45



作者:IFire47 出处:http://www.cnblogs.com/IFire47/

本文版权作者博客园共有,欢迎转载。未经作者同意下,必须在文章页面明显标出原文链接及作者,否则保留追究法律责任的权利。

个人原创,若有错误或补充请联系修改。本文会根据作者的一步步成长做一定程度的更新和补充。


时间: 2024-10-14 22:59:56

Actiove Directory组织单位(Organization Unit)操作汇总的相关文章

Actiove Directory的DirectoryEntry与DirectorySearcher初识及Filter语法

前言 增删改查,我想查询是最先要说的一个了.本章主要记录使用.NET Framework进行对域控服务器对象的查询操作,介绍DirectoryEntry与DirectorySearcher(搜索器)及Filter(搜索过滤器)语法,并对AD对象常用属性做记录. DirectoryEntry与DirectorySearcher 使用C#语言对域控服务器的AD对象进行查询操作,DirectoryEntry和DirectorySearcher是必须要了解的两个类.System.DirectorySer

Windows Server 笔记(六):Active Directory域服务:组织单位

组织单位(Organization Unit,OU)是Active Directory中的一个容器,把域中的对象组成一个逻辑组,可以包含:用户.组.计算机和其他OU等,如下图所示,但不限于下图所示:OU只能包含自己域中的对象,并且OU的嵌套(OU下面包含OU)建议不要超过十层: OU通常是基于管理需求,将具有"相同属性(同一部门.同一小组等等)"的对象集中在一起管理.默认的容器中,除了Domain Controllers之外其他的容器都不属于OU: 一.创建组织单位: 1.打开Acti

C# AD(Active Directory)域信息同步,组织单位、用户等信息查询

Windows Server 2008 R2 配置AD(Active Directory)域控制器 目录 配置环境 配置DNS服务器 配置Active Directory 域服务 C# AD(Active Directory)域同步 组织单位.用户等信息查询 PDF下载 配置环境 Windows版本:Windows Server 2008 R2 Enterprise Service Pack 1 系统类型:       64 位操作系统 配置DNS服务器 这一步不是必须的,在安装Active D

Windows Server 2016-OU组织单位日常操作

技术无所谓贵贱,既然曾经做过就总该是要留下点什么,毕竟做技术这些年给我们留下太多太多的成长经历,总有人问这些已经很皮毛了为什么还要写,其实没那么多花哨理由,就是想着做或者不做这一块总是要对过往做个简单归总,习惯已成自然,虽然因为种种原因频繁隔断更新,但一有时间就想着写点什么,希望N年后还可以帮到更多有需要的人.本章节对Active Directory的日常OU组织单位新建.移动.删除等内容进行简单介绍,方便日常管理.具体如下: 新建OU: 1.打开Active Directory用户和计算机,右

企业云桌面-13-为企业新建组织单位

作者:学 无 止 境 QQ交流群:454544014 注意: <企业云桌面>系列博文是<企业云桌面规划.部署与运维实践指南>的基础部分,因为书中内容涉及非常多,非常全面,所以基础部分将以博文的形式给读者展现,将在书中引用. <企业云桌面规划.部署与运维实践指南>将以某社保中心云桌面为中心,采用VMware Workstation Pro 12.5.2在1台物理机上模拟.读者按书中的步骤一步一步去做,就可以实现.     组织单位的目的是为了简化管理,在企业中一般有组织架

SAP CRM 为用户创建业务合作伙伴并分配到组织单位

想要在SAP CRM的前台完成一些操作,需要登录的用户在系统中存在对应的业务合作伙伴才可以,某些情况下,还需要被分配到公司.部门.职位.下面是相关的操作步骤. 本文假定读者已经拥有一个开发帐号. 本文地址:http://www.cnblogs.com/hhelibeb/p/6268387.html 原创内容,转载请注明 创建BP 前往事务代码BP,点击新建人员按钮 类型选择 员工 在新屏幕中填入姓名.国家等必输项 关键步骤:切换到“标识”(Identification)标签,输入用户名,保存 点

Scala中List、Map、Set各类型操作汇总

1.Scala中List.Map.Set等各类型函数操作汇总 package com.scala.study import scala.collection.immutable.{Queue, TreeMap}import scala.collection.mutable /**  * Created by HP-PC on 2016/5/26.  */ object ScalaCaseDemo {  def main(args: Array[String]): Unit = {    prin

【转】C#路径/文件/目录/I/O常见操作汇总

文件操作是程序中非常基础和重要的内容,而路径.文件.目录以及I/O都是在进行文件操作时的常见主题,这里想把这些常见的问题作个总结,对于每个问题,尽量提供一些解决方案,即使没有你想要的答案,也希望能提供给你一点有益的思路,如果你有好的建议,恳请能够留言,使这些内容更加完善. 主要内容: 一.路径的相关操作, 如判断路径是否合法,路径类型,路径的特定部分,合并路径,系统文件夹路径等内容: 二.相关通用文件对话框,这些对话框可以帮助我们操作文件系统中的文件和目录: 三.文件.目录.驱动器的操作,如获取

C4C和CRM里获取当前登录用户分配的Organization Unit信息

C4C 如何查看某个用户分配的组织单元ID: 在Employee的Organization Data区域内看到分配的组织名称,如下图红色下划线所示: 现在的需求就是使用ABSL获取当前登录用户分配的Organization Unit信息,例如用WANGJERRY37登录,则取出下图显示的Department name PMLS: 具体实现:新建一个custom BO,使用字段DepartmentName存储这个待取的值: 然后创建AfterLoading script file,使用如下代码: