Active Directory组织单位(Organizational Unit)操作汇总
前言
本章聊Active Directory的组织单位(OU)的新增、修改、移动等操作,使用.NET Framework 为我们提供的System.DirectoryServices程序集。
不积跬步无以至千里。Active Directory开发系列将在本章开始侧重于代码(有部分人肯定很高兴了,可以COPY嘛),因为个人认为必要的理论知识和基础代码在前面已经记录了很多,这章开始若有不理解的地方请回看以前的文章。
封装基础ADHelper
这段ADHelper 是为了后面组织单位的新增,修改,移动而准备的代码段,在实际项目开发中当然是不够看的,不过讲本章涉及内容已经足够了。
public class ADHelper
{
#region 构造单例
private ADHelper() { }
public static readonly ADHelper Instance = new ADHelper();
#endregion
#region 公共属性
private static string DomainServiceIP = "192.168.241.3";
private static string UserName = @"Domain";
private static string Password = "p@ssw0rd";
private DirectoryEntry rootEntry = null;
#endregion
#region 公共方法
/// <summary>
/// 域节点DirectoryEntry对象
/// </summary>
public DirectoryEntry DomainRootEntry
{
get
{
if (rootEntry == null)
{
try
{
rootEntry = new DirectoryEntry("LDAP://" + DomainServiceIP, UserName, Password);
}
catch (Exception ex)
{ throw ex;
}
}
return rootEntry;
}
}
/// <summary>
/// AD查询器公共方法封装
/// </summary>
/// <typeparam name="T">DirectorySearcher或SearchResultCollection</typeparam>
/// <param name="SearchRoot">查询器的查询起点</param>
/// <param name="Filter">查询过滤器</param>
/// <param name="SearchScope">查询方式</param>
/// <returns></returns>
public T GetSearchResultOrSearchCollection<T>(DirectoryEntry SearchRoot, string Filter, SearchScope SearchScope) where T : class
{
DirectorySearcher Searcher = new DirectorySearcher();
if (SearchRoot == null)
SearchRoot = DomainRootEntry;
using (SearchRoot)
{
try
{
Searcher.Filter = Filter;
Searcher.SearchRoot = SearchRoot;
Searcher.SearchScope = SearchScope;
if (typeof(T).Name == "SearchResult")
return Searcher.FindOne() as T;
else
return Searcher.FindAll() as T;
}
catch (Exception ex)
{ throw ex;
}
}
}
/// <summary>
/// 获取DirectoryEntry对象
/// </summary>
/// <param name="proterEntry">查询起点</param>
/// <param name="filter">查询条件</param>
/// <returns></returns>
public DirectoryEntry GetEntry(DirectoryEntry proterEntry, string filter)
{
SearchResult SearchResult = GetSearchResultOrSearchCollection<SearchResult>(proterEntry, filter, SearchScope.Subtree);
if (SearchResult != null)
return SearchResult.GetDirectoryEntry();
else
return DomainRootEntry;
}
#endregion
}
这段ADHelper代码顾名思义其实和SQLHelper一样,是对AD操作的最基础层的一段代码,如果前面的文章有仔细了解过,那么这段代码我相信应该不成问题,只不过是做了封装而已,我们将主要精力放在后面实际的操作OU上吧。
我们还要再封装一个组织单位的实体类方便我们使用。
public class ADOrgUnit
{
#region 属性
/// <summary>
/// GUID
/// </summary>
public string ObjectGuid { get; set; }
/// <summary>
/// 标示名
/// </summary>
public string DistinguishedName { get; set; }
/// <summary>
/// OU
/// </summary>
public string Ou { get; set; }
/// <summary>
/// 描述
/// </summary>
public string Description { get; set; }
#endregion
}
我的测试域控服务器如下:
如果之前的文章有做过了解,看到图片上的数据排列,我们完全可以推算出某AD对象的DN。
新增组织单位(OU)
我们目标是在域节点创建新的OU,如果之前的文章有理解,那么我们可以直接判断出DomainDNS的DN为:DC=IFire47,DC=com
static void Main(string[] args)
{
ADOrgUnit adOrgUnit = new ADOrgUnit();
//新增OU的名称
adOrgUnit.Ou = "IFire47";
//新增OU的描述
adOrgUnit.Description = "IFire47测试组织单位";
try
{
//我们在域节点创建新的组织单位,所以根据封装的ADHelper调用此方法。
using (DirectoryEntry parentEntry = ADHelper.Instance.DomainRootEntry)
{
//创建新OU,并接受新OU的DiectoryEntry对象
DirectoryEntry ouEntry = parentEntry.Children.Add("ou=" + adOrgUnit.Ou, "organizationalUnit");
//为创建的新OU赋值属性
if (!String.IsNullOrEmpty(adOrgUnit.Description))
ouEntry.Properties["description"].Value = adOrgUnit.Description;
//保存
ouEntry.CommitChanges();
}
}
catch (Exception ex)
{
throw ex;
}
}
因为我们是在域节点创建的新OU我们看下新OU的DN属性
这跟之前文章讲解不谋而合,所以在这里我们将从实际代码测试中对LDAP和DN的概念有更进一步的认识与理解。对于这块代码的理解,这是我根据.NET的提示及个人理解做的整理:
// 摘要:获取 Active Directory 域服务层次结构中此节点的子项。
// 返回结果:一个 System.DirectoryServices.DirectoryEntries 对象,其中包含 Active Directory 域服务层次结构中此节点的子项。
[Browsable(false)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
[DSDescription("DSChildren")]
public DirectoryEntries Children { get; }
// 摘要: 在容器中创建一个新项。
// name:新项名称。
// schemaClassName:用于此新项的架构名称。即新创建的对象类别,详细查看上章
// 返回结果:新项的 System.DirectoryServices.DirectoryEntry 对象。
public DirectoryEntry Add(string name, string schemaClassName);
// 摘要:获取此 System.DirectoryServices.DirectoryEntry 对象的 Active Directory 域服务属性。
// 返回结果:一个 System.DirectoryServices.PropertyCollection 对象,包含此项所设属性。
[Browsable(false)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
[DSDescription("DSProperties")]
public PropertyCollection Properties { get; }
//摘要: 将目录项所作更改保存到基础目录存储中。
public void CommitChanges();
修改组织单位(OU)
我们修改刚才新添加的OU的名称及描述属性
static void Main(string[] args)
{
ADOrgUnit adOrgUnit = new ADOrgUnit();
//修改OU的新名称
adOrgUnit.Ou = "IceFire47";
//修改OU的新描述
adOrgUnit.Description = "IceFire47测试组织单位";
//所要修改的OU的DN属性
adOrgUnit.DistinguishedName = "OU=IceFire47,DC=IFire47,DC=com";
try
{
DirectoryEntry ouEntry = GetEntryByOrgDN(adOrgUnit.DistinguishedName);
if (!string.IsNullOrEmpty(adOrgUnit.Ou))
{
ouEntry.Rename("ou=" + adOrgUnit.Ou);
ouEntry.CommitChanges();
}
//修改描述属性,属性是数组类型的,要做一系列容错判断
if (ouEntry.Properties.Contains("description"))//判断是否存在这个属性
{
if (adOrgUnit.Description != null && !string.IsNullOrEmpty(adOrgUnit.Description))//描述是否为空
ouEntry.Properties["description"][] = adOrgUnit.Description;//不空修改属性
else//
ouEntry.Properties["description"].RemoveAt();//为空移除描述属性
}
else
{
if (adOrgUnit.Description != null && !string.IsNullOrEmpty(adOrgUnit.Description))//不为空添加属性
ouEntry.Properties["description"].Add(adOrgUnit.Description);
}
//保存
ouEntry.CommitChanges();
}
catch (Exception ex)
{
throw ex;
}
}
/// <summary>
/// 根据OU的DN属性值查询OU对象
/// </summary>
/// <param name="distinguishedName">DN属性值</param>
/// <returns></returns>
public static DirectoryEntry GetEntryByOrgDN(string distinguishedName)
{
string filter = "(&(objectClass=organizationalUnit)(distinguishedName=" + distinguishedName + "))";
return ADHelper.Instance.GetEntry(null, filter);
}
这的逻辑根据自身的业务场景可以做调整,并不一定要根据DN去查询然后修改,也可以根据name等属性查询,只不过要修改Filter并修改传值。而且我们修改了这个OU对象后,它的DN也将自动修改,因为我们定义了新的OU名称。
这里的赋值做了一系列的判断,是因为AD对象的属性并不一定是String还有可能是String[],从属性编辑器中看下描述属性如下,所以直接赋值保存或做判断后赋值或修改时直接追加根据自身业务场景而定。
移动组织单位(OU)
我们将刚才修改的OU,移动到北京分公司的OU当中
static void Main(string[] args)
{
//需要移动的OU的DN
string OrgUnitDN = "OU=IceFire47,DC=IFire47,DC=com";
//要移动到的容器的DN,这里不一定是OU也可以是域节点
string targetOrgDN = "OU=北京分公司,DC=IFire47,DC=com";
using (DirectoryEntry ouEntry = GetEntryByOrgDN(OrgUnitDN))
{
using (DirectoryEntry targetOU = GetEntryByOrgDN(targetOrgDN))
{
try
{
ouEntry.MoveTo(targetOU);
ouEntry.CommitChanges();
}
catch (Exception ex)
{
throw ex;
}
}
}
}
/// <summary>
/// 根据OU的DN查询OU对象
/// </summary>
/// <param name="distinguishedName">DN属性</param>
/// <returns></returns>
public static DirectoryEntry GetEntryByOrgDN(string distinguishedName)
{
string filter = "(&(objectClass=organizationalUnit)(distinguishedName=" + distinguishedName + "))";
return ADHelper.Instance.GetEntry(null, filter);
}
在移动OU时,新OU的DN也将自动改变。同理,这里的一部分逻辑也并不是固定的,我们也可以根据自身业务场景做调整,关键还是在获取DirectoryEntry对象根据项目需求而定。而且OU的移动智能在域节点或者另一个OU中,不能将组织单位移动到某个组或者用户或者计算机中,而且需要注意的是,当OU移动时,移动的OU内的所有对象将一起被移动。
结语
本章主要是讲解AD中组织单位的一系列操作,删除操作调用DirectoryEntry.DeleteTree();DirectoryEntry.CommitChanges();即可,但是实际项目中删除操作要慎重,删除OU此容器内的所有对象将一并删除。
这里的所有示例都没有做容错处理,比如说新建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/
Active Directory组织单位(Organizational Unit)操作汇总的更多相关文章
- Active Directory的基本概念
前言 本文是面对准备加入Active Directory编程的初学者的一份文章,主要是讲解Active Directory(活动目录)的一些概念和相关知识.这篇文章本来是不想写下来的,因为概念性内容的 ...
- Active Directory的DirectoryEntry与DirectorySearcher初识及Filter语法
前言 增删改查,我想查询是最先要说的一个了.本章主要记录使用.NET Framework进行对域控服务器对象的查询操作,介绍DirectoryEntry与DirectorySearcher(搜索器)及 ...
- DNS笔记 DNS区域集成到 Active Directory
可以将 DNS 区域集成到 Active Directory 中以提供增强的容错功能和安全性.OpenDNS Google Public DNS往返时间 (RTT) 远程访问服务 (RAS)域名与 ...
- C# AD(Active Directory)域信息同步,组织单位、用户等信息查询
示例准备 打开上一篇文章配置好的AD域控制器 开始菜单-->管理工具-->Active Directory 用户和计算机 新建组织单位和用户 新建层次关系如下: 知识了解 我们要用C# ...
- C#操作Active Directory(AD)详解
1. LDAP简介 LDAP(轻量级目录访问协议,Lightweight Directory Access Protocol)是实现提供被称为目录服务的信息服务.目录服务是一种特殊的数据库系统,其专门 ...
- Windows Server 2016-OU组织单位日常操作
技术无所谓贵贱,既然曾经做过就总该是要留下点什么,毕竟做技术这些年给我们留下太多太多的成长经历,总有人问这些已经很皮毛了为什么还要写,其实没那么多花哨理由,就是想着做或者不做这一块总是要对过往做个简单 ...
- 操作Active Directory C#
.Net平台操作活动目录Active Directory,使用System.DirectoryServices.ActiveDirectory,主要是User OU 和Group的操作. 代码运行了一 ...
- PHP 通过LDAP协议,操作Windows Active Directory
原文地址:http://hi.baidu.com/lllangxx/item/3ccb7cdfa13b56eb3dc2cb39 一.学习如何管理Active Directory Active Dire ...
- Active Directory的LDAP协议与DN(Distinguished Name)详解
前言 光copy几段代码的文章没什么意思,本章上最基础的代码,主要是为了从编程方面聊LDAP和DN,其它的后面聊,一步步慢慢来吧. Active Directory编程须知 1.域控服务器: Wind ...
随机推荐
- NOJ——1649Find Sum(二分查找)
[1649] Find Sum 时间限制: 1000 ms 内存限制: 65535 K 问题描述 This problem is really boring. You are given a numb ...
- bzoj 2437[Noi2011]兔兔与蛋蛋 黑白染色二分图+博弈+匈牙利新姿势
noi2011 兔兔与蛋蛋 题目大意 直接看原题吧 就是\(n*m\)的格子上有一些白棋和一些黑棋和唯一一个空格 兔兔先手,蛋蛋后手 兔兔要把与空格相邻的其中一个白棋移到空格里 蛋蛋要把与空格相邻的其 ...
- [LeetCode] Minimum Window Substring 散列映射问题
题目: Given a string S and a string T, find the minimum window in S which will contain all the charact ...
- Linux用户空间与内核空间(理解高端内存)【转】
转自:http://www.cnblogs.com/wuchanming/p/4360277.html Linux 操作系统和驱动程序运行在内核空间,应用程序运行在用户空间,两者不能简单地使用指针传递 ...
- 14深入理解C指针之---指针与内存分配
一.内存的含义 1.定义:物理内存是固定,逻辑内存是非常灵活的 2.特征: 1).逻辑内存最终必须映射到物理内存才能作用 2).逻辑内存每次映射可能到不同的物理内存 3).逻辑内存与物理内存的链接通过 ...
- linux内核设计与实现第一章
1.1 unix的历史 Thompson实现unix 伯克利大学对其进一步开发推出了著名的BSD 其他各大厂商相继推出自己的unix 1.1.2 unix的特性 unix系统是一个强大,健壮,稳定的操 ...
- Codeforces 558E A Simple Task(权值线段树)
题目链接 A Simple Task 题意 给出一个小写字母序列和若干操作.每个操作为对给定区间进行升序排序或降序排序. 考虑权值线段树. 建立26棵权值线段树.每次操作的时候先把26棵线段树上的 ...
- 初级Springboot(一)
初级Springboot(一) 作者 : Stanley 罗昊 [转载请注明出处和署名,谢谢!] 一.了解Springboot 做Java开发的小伙伴都知道,我们在做项目的时候,需要去写大量的配置文件 ...
- Xamarin XAML语言教程基础语法篇大学霸
Xamarin XAML语言教程基础语法篇大学霸 前 言 Xamarin是一个跨平台开发框架.它可以用来开发iOS.Android.Windows Phone和Mac的应用程序.使用Xamarin框 ...
- FZU 2224 An exciting GCD problem(GCD种类预处理+树状数组维护)同hdu5869
题目链接:http://acm.fzu.edu.cn/problem.php?pid=2224 同hdu5869 //#pragma comment(linker, "/STACK:1024 ...