using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Configuration;
using System.DirectoryServices;
namespace AnnetAD
{
public class OperateAD
{
private static log4net.ILog _log = log4net.LogManager.GetLogger(typeof(OperateAD));
/// <summary>
/// 域名
/// </summary>
private string _domain;
/// <summary>
/// 主机域IP
/// </summary>
private string _domainIp;
/// <summary>
/// 管理员账号
/// </summary>
private string adminUser;
/// <summary>
/// 管理员密码
/// </summary>
private string adminPwd;
/// <summary>
/// 路径的最前端
/// </summary>
private string _ldapIdentity;
/// <summary>
/// 路径的最后端
/// </summary>
private string _suffixPath;
#region 构造函数
/// <summary>
/// 构造函数
/// 从webConfig的AppSettings属性读取值初始化字段
/// </summary>
public OperateAD(string domain, string domainIp, string adUser, string adPwd)
{
//_domain = System.Configuration.ConfigurationManager.AppSettings["Domain"].ToString();
//_domainIp = System.Configuration.ConfigurationManager.AppSettings["DomainIp"].ToString();
//adminUser = System.Configuration.ConfigurationManager.AppSettings["ADAdminUser"].ToString();
//adminPwd = System.Configuration.ConfigurationManager.AppSettings["ADAdminPassword"].ToString();
//_ldapIdentity = "LDAP://" + _domainIp + "/";
//_suffixPath = "DC=" + _domain + ",DC=COM";
//_domain = "bdxy";
//_domainIp = "10.1.209.197";
//adminUser = "administrator";
//adminPwd = "123456";
_domain = domain;
_domainIp = domainIp;
adminUser = adUser;
adminPwd = adPwd;
_ldapIdentity = "LDAP://" + _domainIp + "/";
_suffixPath = "DC=" + _domain + ",DC=" + Setting.Setting.DomainCom;
}
#endregion
#region 组织结构下添加AD账户
/// <summary>
/// 添加AD账户
/// </summary>
/// <param name="organizeName">组织名称</param>
/// <param name="user">域账户</param>
/// <returns>添加是否成功</returns>
public bool AddADAccount(string organizeName, DomainUser user)
{
DirectoryEntry entry = null;
try
{
if (ExitOU(organizeName) && user != null)
{
entry = AddUserToOU(organizeName, user, entry);
return true;
}
else
{
DomainUser._failed = "在域中不存在直属组织单位";
Console.WriteLine("在域中不存在直属组织单位:" + organizeName);
return true;
}
}
catch (System.DirectoryServices.DirectoryServicesCOMException ex)
{
DomainUser._failed = "账户添加失败!"+ex.Message.ToString();
Console.WriteLine("账户添加失败:" + ex.Message.ToString());
return false;
}
finally
{
if (entry != null)
{
entry.Dispose();
}
}
}
private DirectoryEntry AddUserToOU(string organizeName, DomainUser user, DirectoryEntry entry)
{
entry = new DirectoryEntry(GetOrganizeNamePath(organizeName), adminUser, adminPwd, AuthenticationTypes.Secure);
//增加账户到域中
DirectoryEntry NewUser = entry.Children.Add("CN=" + user.UserName, "user");
NewUser.Properties["sAMAccountName"].Add(user.UserName); //account
NewUser.Properties["userPrincipalName"].Value = user.UserPrincipalName; //user logon name,xxx@bdxy.com
NewUser.Properties["givenName"].Value = Setting.Setting.givenName; //名
NewUser.Properties["initials"].Value = Setting.Setting.initials;
NewUser.Properties["name"].Value = Setting.Setting.fullname; //full name
NewUser.Properties["sn"].Value = user.UserId;
NewUser.Properties["displayName"].Value = user.UserName;
NewUser.Properties["company"].Value = Setting.Setting.company;
NewUser.Properties["physicalDeliveryOfficeName"].Value = user.PhysicalDeliveryOfficeName;
NewUser.Properties["Department"].Value = user.Department;
if (user.Telephone != null && user.Telephone != "")
{
NewUser.Properties["telephoneNumber"].Value = user.Telephone;
}
if (user.Email != null && user.Email != "")
{
NewUser.Properties["mail"].Value = user.Email;
}
if (user.Description != null && user.Description != "")
{
NewUser.Properties["description"].Value = user.Description;
}
NewUser.CommitChanges();
//设置密码
//反射调用修改密码的方法(注意端口号的问题 端口号会引起方法调用异常)
NewUser.Invoke("SetPassword", new object[] {user.UserPwd});
//默认设置新增账户启用
NewUser.Properties["userAccountControl"].Value = 0x200;
NewUser.CommitChanges();
DomainUser._success = "账户添加成功!";
Setting.Setting.succCount = Setting.Setting.succCount + 1;
return entry;
}
#endregion
#region 重命名账户
/// <summary>
/// 重命名账户
/// </summary>
/// <param name="adminUser">管理员名称</param>
/// <param name="adminPassword">管理员密码</param>
/// <param name="oldUserName">原用户名</param>
/// <param name="newUserName">新用户名</param>
public bool RenameUser(string oldUserName, string newUserName)
{
try
{
DirectoryEntry userEntry = FindObject("user", oldUserName);
if (userEntry != null)
{
userEntry.Rename("CN="+newUserName);
userEntry.CommitChanges();
DomainUser._success = "重命名成功!";
return true;
}
DomainUser._failed = "没找到用户!" + oldUserName;
return false;
}
catch (Exception ex)
{
DomainUser._failed = "重命名失败!"+ex.Message.ToString();
return false;
}
}
#endregion
#region 设置用户密码
/// <summary>
/// 设置用户密码
/// </summary>
/// <param name="userName">用户名</param>
/// <param name="password">密码</param>
public bool SetUserPassword(string userName, string password)
{
try
{
DirectoryEntry userEntry = FindObject("user", userName);
if (userEntry != null)
{
userEntry.Invoke("SetPassword", new object[] { password });
userEntry.CommitChanges();
DomainUser._success = "密码设置成功!";
return true;
}
DomainUser._failed = "没找到用户!" + userName;
return false;
}
catch (Exception ex)
{
DomainUser._failed = "密码设置失败!"+ex.Message.ToString();
return false;
}
}
#endregion
#region 修改密码
/// <summary>
/// 修改密码
/// </summary>
/// <param name="ude">用户</param>
/// <param name="password">旧密码</param>
/// <param name="password">新密码</param>
public bool ChangePassword(string username, string oldpwd, string newpwd)
{
try
{
DirectoryEntry entry = FindObject("user", username);
if (entry != null)
{
// to-do: 需要解决密码策略问题
entry.Invoke("ChangePassword", new object[] {oldpwd, newpwd });
entry.CommitChanges();
entry.Close();
DomainUser._success = "密码修改成功!";
return true;
}
else
{
DomainUser._failed = "没找到用户!" + username;
return false;
}
}
catch (Exception ex)
{
DomainUser._failed = "密码修改失败!"+ex.Message.ToString();
return false;
}
}
#endregion
#region 删除账户
/// <summary>
/// 删除AD账户,使用当前上下文的安全信息
/// </summary>
/// <param name="userName">用户名称</param>
public bool DeleteADAccount(string userName)
{
try
{
DirectoryEntry user = FindObject("user", userName);
if (user != null)
{
using (DirectoryEntry de = new DirectoryEntry(user.Parent.Path, adminUser, adminPwd))
{
de.Children.Remove(user);
de.CommitChanges();
DomainUser._success = "账户删除成功!";
return true;
}
}
DomainUser._failed = "未找到账户!";
return false;
}
catch (Exception ex)
{
DomainUser._failed = "账户删除失败!" + ex.Message.ToString();
return false;
}
}
#endregion
#region 创建OU
/// <summary>
/// 创建OU
/// </summary>
/// <param name="adminName">管理员名称</param>
/// <param name="adminPassword">管理员密码</param>
/// <param name="name">创建的OU名称</param>
/// <param name="parentOrganizeUnit">父组织单位</param>
/// <returns>目录实体</returns>
public DirectoryEntry CreateOrganizeUnit(string name, string parentOrganizeUnit)
{
DirectoryEntry parentEntry = null;
try
{
//示例顶级"LDAP://10.1.209.197/dc=bdxy,dc=com"
parentEntry = new DirectoryEntry(GetOrganizeNamePath(parentOrganizeUnit), adminUser, adminPwd,
AuthenticationTypes.Secure);
DirectoryEntry organizeEntry = parentEntry.Children.Add("OU=" + name, "organizationalUnit");
organizeEntry.CommitChanges();
DomainUser._success = "组织单位添加成功!";
return organizeEntry;
}
catch (System.DirectoryServices.DirectoryServicesCOMException ex)
{
DomainUser._failed = "添加组织单位失败!"+ex.Message.ToString();
_log.Error("添加组织单位失败!"+ex.Message.ToString());
Console.WriteLine("添加组织单位(" + parentOrganizeUnit + ")失败!");
return new DirectoryEntry();
}
finally
{
if (parentEntry != null)
{
parentEntry.Dispose();
}
}
}
#endregion
#region 删除OU
/// <summary>
/// 删除OU
/// </summary>
/// <param name="name">创建的OU名称</param>
/// <param name="parentOrganizeUnit">父组织单位</param>
/// <returns>目录实体</returns>
public bool DeleteOrganizeUnit(string name, string parentOrganizeUnit)
{
DirectoryEntry parentEntry = null;
try
{
//示例顶级"LDAP://10.1.209.197/dc=bdxy,dc=com"
parentEntry = new DirectoryEntry(GetOrganizeNamePath(parentOrganizeUnit), adminUser, adminPwd,
AuthenticationTypes.Secure);
DirectoryEntry organizeEntry = parentEntry.Children.Find("OU=" + name, "organizationalUnit");
//先删除组织单元下的用户或者组
parentEntry.Children.Remove(organizeEntry);
organizeEntry.CommitChanges();
DomainUser._success = "组织单位删除成功!";
return true;
}
catch (System.DirectoryServices.DirectoryServicesCOMException ex)
{
DomainUser._failed = "组织单位删除失败!"+ex.Message.ToString();
return false;
}
finally
{
if (parentEntry != null)
{
parentEntry.Dispose();
}
}
}
#endregion
#region 创建组
/// <summary>
/// 创建组
/// </summary>
/// <param name="name">组名</param>
/// <param name="OrganizeUnit">组织单位</param>
/// <returns>是否创建成功</returns>
public bool CreateGroup(string name, string OrganizeUnit)
{
DirectoryEntry parentEntry = null;
try
{
parentEntry = new DirectoryEntry(GetOrganizeNamePath(OrganizeUnit), adminUser, adminPwd,
AuthenticationTypes.Secure);
DirectoryEntry groupEntry = parentEntry.Children.Add("CN=" + name, "group");
groupEntry.CommitChanges();
DomainUser._success = "组创建成功!";
return true;
}
catch (System.DirectoryServices.DirectoryServicesCOMException ex)
{
DomainUser._failed = "组创建失败!"+ex.Message.ToString();
return false;
}
finally
{
if (parentEntry != null)
{
parentEntry.Dispose();
}
}
}
#endregion
#region 删除组
/// <summary>
/// 删除组
/// </summary>
/// <param name="name">组名</param>
/// <param name="OrganizeUnit">组织单位</param>
/// <returns>是否创建成功</returns>
public bool DeleteGroup(string name, string OrganizeUnit)
{
DirectoryEntry parentEntry = null;
try
{
parentEntry = new DirectoryEntry(GetOrganizeNamePath(OrganizeUnit), adminUser, adminPwd,
AuthenticationTypes.Secure);
DirectoryEntry groupEntry = parentEntry.Children.Find("CN=" + name, "group");
parentEntry.Children.Remove(groupEntry);
groupEntry.CommitChanges();
DomainUser._success = "组删除成功!";
return true;
}
catch (System.DirectoryServices.DirectoryServicesCOMException ex)
{
DomainUser._failed = "组删除失败!" + ex.Message.ToString();
return false;
}
finally
{
if (parentEntry != null)
{
parentEntry.Dispose();
}
}
}
#endregion
#region 将用户加入到用户组中
/// <summary>
/// 将用户加入到用户组中
/// </summary>
/// <param name="userName">用户名</param>
/// <param name="organizeName">组织名</param>
/// <param name="groupName">组名</param>
/// <param name="groupPath">组所在路径</param>
/// <exception cref="InvalidObjectException">用户名或用户组不存在</exception>
public bool AddUserToGroup(string userName, string groupName, string groupPath)
{
DirectoryEntry group = null;
DirectoryEntry user = null;
try
{
group = ExitGroup(groupName, groupPath);
user = ExitUser(userName);
if ((group != null) && (user != null))
{
//加入用户到用户组中
group.Properties["member"].Add(user.Properties["distinguishedName"].Value);
group.CommitChanges();
DomainUser._success = "用户成功加入组!";
return true;
}
else
{
return false;
}
}
catch (Exception ex)
{
DomainUser._failed = "加入组失败!"+ex.Message.ToString();
return false;
}
}
#endregion
#region 依据类别用户名 查找目录项
/// <summary>
/// 查找目录项
/// </summary>
/// <param name="category">分类 users</param>
/// <param name="name">用户名</param>
/// <returns>目录项实体</returns>
public DirectoryEntry FindObject(string category, string name)
{
DirectoryEntry de = null;
DirectorySearcher ds = null;
DirectoryEntry userEntry = null;
try
{
de = new DirectoryEntry(GetDomainPath(), adminUser, adminPwd, AuthenticationTypes.Secure);
ds = new DirectorySearcher(de);
string queryFilter = string.Format("(&(objectCategory=" + category + ")(sAMAccountName={0}))", name);
ds.Filter = queryFilter;
ds.Sort.PropertyName = "cn";
SearchResult sr = ds.FindOne();
if (sr != null)
{
userEntry = sr.GetDirectoryEntry();
}
return userEntry;
}
catch (Exception ex)
{
DomainUser._failed = ex.Message.ToString();
return new DirectoryEntry();
}
finally
{
if (ds != null)
{
ds.Dispose();
}
if (de != null)
{
de.Dispose();
}
}
}
#endregion
#region 获取组织名称路径
/// <summary>
/// 获取组织名称路径
/// </summary>
/// <param name="organizeUnit">组织</param>
/// <returns></returns>
public string GetOrganizeNamePath(string organizeUnit)
{
StringBuilder sb = new StringBuilder();
sb.Append(_ldapIdentity);
return sb.Append(SplitOrganizeNameToDN(organizeUnit)).ToString();
}
#endregion
#region 分隔组织名称为标准AD的DN名称
/// <summary>
/// 分隔组织名称为标准AD的DN名称,各个组织级别以"/"或"/"分开。如"总部/物业公司/小区",并且当前域为
/// bdxy.com,则返回的AD的DN表示名为"OU=小区,OU=物业公司,OU=总部,DC=bdxy,DC=com"。
/// </summary>
/// <param name="organizeName">组织名称</param>
/// <returns>返回一个级别</returns>
public string SplitOrganizeNameToDN(string organizeName)
{
StringBuilder sb = new StringBuilder();
if (organizeName.Equals("Users") || string.IsNullOrEmpty(organizeName))
{
sb.Append("CN=Users,").Append(_suffixPath);
return sb.ToString();
}
else
{
if (organizeName != null && organizeName.Length > 0)
{
string[] allOu = organizeName.Split(new char[] { '/' });
for (int i = allOu.Length - 1; i >= 0; i--)
{
string ou = allOu[i];
if (sb.Length > 0)
{
sb.Append(",");
}
sb.Append("OU=").Append(ou);
}
}
//如果传入了组织名称,则添加,
if (sb.Length > 0)
{
sb.Append(",");
}
sb.Append(_suffixPath);
return sb.ToString();
}
}
#endregion
#region 获取域路径
/// <summary>
/// 获取域路径
/// </summary>
/// <returns>路径</returns>
public string GetDomainPath()
{
using (DirectoryEntry root = new DirectoryEntry(_ldapIdentity + _suffixPath, adminUser, adminPwd))
{
return root.Path;
}
}
#endregion
#region 获取Users容器的路径
/// <summary>
/// 获取Users容器的下用户的路径
/// </summary>
/// <param name="userName">用户名</param>
/// <returns></returns>
private string GetUserPath(string userName)
{
StringBuilder sb = new StringBuilder();
sb.Append(_ldapIdentity);
if (userName != null && userName.Length > 0)
{
sb.Append("CN=").Append(userName).Append(",");
}
sb.Append("CN=Users,").Append(_suffixPath);
return sb.ToString();
}
#endregion
#region 根据用户所在的组织结构来构造用户在AD中的DN路径
/// <summary>
/// 根据用户所在的组织结构来构造用户在AD中的DN路径
/// </summary>
/// <param name="userName">用户名称</param>
/// <param name="organzieName">组织结构</param>
/// <returns></returns>
public string GetUserPath(string userName, string organzieName)
{
StringBuilder sb = new StringBuilder();
sb.Append(_ldapIdentity);
sb.Append("CN=").Append(userName).Append(",").Append(SplitOrganizeNameToDN(organzieName));
return sb.ToString();
}
#endregion
#region 启用账户
/// <summary>
/// 启用账户
/// </summary>
/// <param name="user"></param>
public bool EnableAccount(string userName)
{
try
{
DirectoryEntry userEntry = FindObject("user", userName);
int val = (int)userEntry.Properties["userAccountControl"].Value;
userEntry.Properties["userAccountControl"].Value = val & ~0x2;
userEntry.CommitChanges();
userEntry.Close();
DomainUser._success = "启用账户成功!";
return true;
}
catch (Exception ex)
{
DomainUser._failed = ex.Message.ToString();
return false;
}
}
#endregion
#region 停用账号
/// <summary>
/// 停用账号
/// </summary>
/// <param name="user"></param>
public bool DisableAccount(string userName)
{
try
{
DirectoryEntry userEntry = FindObject("user", userName);
userEntry.Properties["userAccountControl"].Value = 0x2;
userEntry.CommitChanges();
userEntry.Close();
DomainUser._success = "停用账户成功!";
return true;
}
catch (System.DirectoryServices.DirectoryServicesCOMException ex)
{
DomainUser._failed = ex.Message.ToString();
return false;
}
}
#endregion
#region 判断用户是否已经存在域中
/// <summary>
/// 判断用户是否已经存在域中
/// </summary>
/// <param name="userName">用户名</param>
/// <returns></returns>
private DirectoryEntry ExitUser(string userName)
{
try
{
DirectoryEntry de = null;
de = FindObject("user", userName);
if (de == null)
{
return new DirectoryEntry(); ;
}
else
{
return de;
}
}
catch (Exception ex)
{
DomainUser._failed = ex.Message.ToString();
return new DirectoryEntry();
}
}
#endregion
#region 判断域中是否存在组
/// <summary>
/// 判断域中是否存在组
/// </summary>
/// <param name="groupName">组名</param>
/// <returns></returns>lan
private DirectoryEntry ExitGroup(string groupName, string groupPath)
{
DirectoryEntry rootUser = null;
DirectoryEntry group = null;
DirectoryEntry test = null;
string path = GetOrganizeNamePath(groupPath);
rootUser = new DirectoryEntry(path, adminUser, adminPwd);
test = new DirectoryEntry("WinNT://annet-or2,computer");
try
{
var a = test.Children.Add("Users", "user");
group = rootUser.Children.Find(groupName, "group");
group = rootUser.Children.Find("CN=" + groupName);
if (group != null)
{
return group;
}
return new DirectoryEntry();
}
catch (Exception ex)
{
//CreateGroup(groupName, path);
//group = rootUser.Children.Find("CN=" + groupName);
DomainUser._failed = ex.Message.ToString() + "在域中不存在组“" + groupName + "”或路组织单位不正确";
return new DirectoryEntry();
}
}
#endregion
#region 判断域中是否存在组织单位
/// <summary>
/// 判断域中是否存在组织单位
/// </summary>
/// <param name="organizeName">组织单位名</param>
/// <returns></returns>
public bool ExitOU(string organizeName)
{
DirectoryEntry rootUser = null;
DirectoryEntry ouFind = null;
if (string.IsNullOrEmpty(organizeName))
{
return true;
}
else
{
//分解路径
string[] allOu = organizeName.Split(new char[] { '/' });
//获取直属部门
string OUName = allOu[allOu.Length - 1].ToString();
try
{
string path = GetOrganizeNamePath(organizeName);
rootUser = new DirectoryEntry(path, adminUser, adminPwd, AuthenticationTypes.Secure);
ouFind = rootUser.Parent.Children.Find("OU=" + OUName);
if (ouFind != null)
{
return true;
}
return false;
}
catch (Exception ex)
{
DomainUser._failed = ex.Message.ToString() + "在域中不存在组织单位“" + OUName + "”";
return false;
}
}
}
#endregion
#region 获取域用户信息
/// <summary>
/// 获取域用户信息
/// </summary>
/// <param name="path">目录</param>
/// <param name="username">用户名</param>
/// <returns></returns>
public DomainUser GetAdUserInfo(string userName)
{
DomainUser du = new DomainUser();
DirectoryEntry de = FindObject("user", userName);
if (de != null)
{
if (de.Properties["samAccountName"].Value != null)
{
du.UserId = de.Properties["samAccountName"].Value.ToString();
}
if (de.Properties["displayName"].Value != null)
{
du.UserName = de.Properties["displayName"].Value.ToString();
}
if (de.Properties["userPrincipalName"].Value != null)
{
du.UserPrincipalName = de.Properties["userPrincipalName"].Value.ToString();
}
if (de.Properties["telephoneNumber"].Value != null)
{
du.Telephone = de.Properties["telephoneNumber"].Value.ToString();
}
if (de.Properties["mail"].Value != null)
{
du.Email = de.Properties["mail"].Value.ToString();
}
if (de.Properties["description"].Value != null)
{
du.Description = de.Properties["description"].Value.ToString();
}
if (de.Properties["Department"].Value != null)
{
du.Department = de.Properties["Department"].Value.ToString();
}
}
return du;
}
#endregion
#region 从域中按照用户名查找用户
/// <summary>
/// 从域中按照用户名查找用户
/// </summary>
/// <param name="path">路径</param>
/// <param name="AdUser">管理员账户</param>
/// <param name="AdPwd">管理员密码</param>
/// <param name="username">用户名</param>
/// <returns></returns>
private DirectoryEntry GetUser(string path, string username)
{
DirectoryEntry deuser;
try
{
DirectoryEntry de = new DirectoryEntry(path, adminUser, adminPwd);
DirectorySearcher deSearch = new DirectorySearcher(de);
deSearch.Filter = "(&(objectClass=user)(cn=" + username + "))";
deSearch.SearchScope = SearchScope.Subtree;
SearchResult result = deSearch.FindOne();
if (result != null)
{
deuser = result.GetDirectoryEntry();
return deuser;
}
else
{
return null;
}
}
catch (Exception ex)
{
DomainUser._failed = ex.Message.ToString();
return null;
}
}
#endregion
#region 进入AD域查询
/// <summary>
/// 查寻用户信息
/// </summary>
/// <param name="userName">用户名</param>
private List<string> AccsesADQuery(string userName)
{
//定义de进入AD架构
DirectoryEntry de = new DirectoryEntry(GetDomainPath(), adminUser, adminPwd);
//定义ds查找AD
DirectorySearcher ds = new DirectorySearcher(de);
string value = string.Empty;
List<string> domainList = new List<string>();
try
{
//3.定义查询
ds.Filter = "(SAMAccountName=" + userName + ")";
ds.PropertiesToLoad.Add("SAMAccountName");//account
ds.PropertiesToLoad.Add("Name");//full name
ds.PropertiesToLoad.Add("displayName");
ds.PropertiesToLoad.Add("mail");
ds.PropertiesToLoad.Add("sn");
ds.PropertiesToLoad.Add("description");
ds.PropertiesToLoad.Add("Department");
ds.PropertiesToLoad.Add("userPrincipalName");//user logon name,xxx@bdxy.com
ds.PropertiesToLoad.Add("physicalDeliveryOfficeName");
ds.PropertiesToLoad.Add("telephoneNumber");
//查找一个
SearchResult sr = ds.FindOne();
if (sr != null)
{
//列出值
foreach (string key in sr.Properties.PropertyNames)
{
foreach (object obj in de.Properties[key])
{
value += key + " = " + obj + Environment.NewLine;
domainList.Add(value);
}
}
return domainList;
}
else
{
return domainList;
}
}
catch (Exception ex)
{
DomainUser._failed = ex.Message.ToString();
return domainList;
}
finally
{
if (ds != null)
{
ds.Dispose();
}
if (de != null)
{
de.Dispose();
}
}
}
#endregion
}
}
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Configuration;
using System.DirectoryServices;
namespace AnnetAD
{
public class OperateAD
{
private static log4net.ILog _log = log4net.LogManager.GetLogger(typeof(OperateAD));
/// <summary>
/// 域名
/// </summary>
private string _domain;
/// <summary>
/// 主机域IP
/// </summary>
private string _domainIp;
/// <summary>
/// 管理员账号
/// </summary>
private string adminUser;
/// <summary>
/// 管理员密码
/// </summary>
private string adminPwd;
/// <summary>
/// 路径的最前端
/// </summary>
private string _ldapIdentity;
/// <summary>
/// 路径的最后端
/// </summary>
private string _suffixPath;
#region 构造函数
/// <summary>
/// 构造函数
/// 从webConfig的AppSettings属性读取值初始化字段
/// </summary>
public OperateAD(string domain, string domainIp, string adUser, string adPwd)
{
//_domain = System.Configuration.ConfigurationManager.AppSettings["Domain"].ToString();
//_domainIp = System.Configuration.ConfigurationManager.AppSettings["DomainIp"].ToString();
//adminUser = System.Configuration.ConfigurationManager.AppSettings["ADAdminUser"].ToString();
//adminPwd = System.Configuration.ConfigurationManager.AppSettings["ADAdminPassword"].ToString();
//_ldapIdentity = "LDAP://" + _domainIp + "/";
//_suffixPath = "DC=" + _domain + ",DC=COM";
//_domain = "bdxy";
//_domainIp = "10.1.209.197";
//adminUser = "administrator";
//adminPwd = "123456";
_domain = domain;
_domainIp = domainIp;
adminUser = adUser;
adminPwd = adPwd;
_ldapIdentity = "LDAP://" + _domainIp + "/";
_suffixPath = "DC=" + _domain + ",DC=" + Setting.Setting.DomainCom;
}
#endregion
#region 组织结构下添加AD账户
/// <summary>
/// 添加AD账户
/// </summary>
/// <param name="organizeName">组织名称</param>
/// <param name="user">域账户</param>
/// <returns>添加是否成功</returns>
public bool AddADAccount(string organizeName, DomainUser user)
{
DirectoryEntry entry = null;
try
{
if (ExitOU(organizeName) && user != null)
{
entry = AddUserToOU(organizeName, user, entry);
return true;
}
else
{
DomainUser._failed = "在域中不存在直属组织单位";
Console.WriteLine("在域中不存在直属组织单位:" + organizeName);
return true;
}
}
catch (System.DirectoryServices.DirectoryServicesCOMException ex)
{
DomainUser._failed = "账户添加失败!"+ex.Message.ToString();
Console.WriteLine("账户添加失败:" + ex.Message.ToString());
return false;
}
finally
{
if (entry != null)
{
entry.Dispose();
}
}
}
private DirectoryEntry AddUserToOU(string organizeName, DomainUser user, DirectoryEntry entry)
{
entry = new DirectoryEntry(GetOrganizeNamePath(organizeName), adminUser, adminPwd, AuthenticationTypes.Secure);
//增加账户到域中
DirectoryEntry NewUser = entry.Children.Add("CN=" + user.UserName, "user");
NewUser.Properties["sAMAccountName"].Add(user.UserName); //account
NewUser.Properties["userPrincipalName"].Value = user.UserPrincipalName; //user logon name,xxx@bdxy.com
NewUser.Properties["givenName"].Value = Setting.Setting.givenName; //名
NewUser.Properties["initials"].Value = Setting.Setting.initials;
NewUser.Properties["name"].Value = Setting.Setting.fullname; //full name
NewUser.Properties["sn"].Value = user.UserId;
NewUser.Properties["displayName"].Value = user.UserName;
NewUser.Properties["company"].Value = Setting.Setting.company;
NewUser.Properties["physicalDeliveryOfficeName"].Value = user.PhysicalDeliveryOfficeName;
NewUser.Properties["Department"].Value = user.Department;
if (user.Telephone != null && user.Telephone != "")
{
NewUser.Properties["telephoneNumber"].Value = user.Telephone;
}
if (user.Email != null && user.Email != "")
{
NewUser.Properties["mail"].Value = user.Email;
}
if (user.Description != null && user.Description != "")
{
NewUser.Properties["description"].Value = user.Description;
}
NewUser.CommitChanges();
//设置密码
//反射调用修改密码的方法(注意端口号的问题 端口号会引起方法调用异常)
NewUser.Invoke("SetPassword", new object[] {user.UserPwd});
//默认设置新增账户启用
NewUser.Properties["userAccountControl"].Value = 0x200;
NewUser.CommitChanges();
DomainUser._success = "账户添加成功!";
Setting.Setting.succCount = Setting.Setting.succCount + 1;
return entry;
}
#endregion
#region 重命名账户
/// <summary>
/// 重命名账户
/// </summary>
/// <param name="adminUser">管理员名称</param>
/// <param name="adminPassword">管理员密码</param>
/// <param name="oldUserName">原用户名</param>
/// <param name="newUserName">新用户名</param>
public bool RenameUser(string oldUserName, string newUserName)
{
try
{
DirectoryEntry userEntry = FindObject("user", oldUserName);
if (userEntry != null)
{
userEntry.Rename("CN="+newUserName);
userEntry.CommitChanges();
DomainUser._success = "重命名成功!";
return true;
}
DomainUser._failed = "没找到用户!" + oldUserName;
return false;
}
catch (Exception ex)
{
DomainUser._failed = "重命名失败!"+ex.Message.ToString();
return false;
}
}
#endregion
#region 设置用户密码
/// <summary>
/// 设置用户密码
/// </summary>
/// <param name="userName">用户名</param>
/// <param name="password">密码</param>
public bool SetUserPassword(string userName, string password)
{
try
{
DirectoryEntry userEntry = FindObject("user", userName);
if (userEntry != null)
{
userEntry.Invoke("SetPassword", new object[] { password });
userEntry.CommitChanges();
DomainUser._success = "密码设置成功!";
return true;
}
DomainUser._failed = "没找到用户!" + userName;
return false;
}
catch (Exception ex)
{
DomainUser._failed = "密码设置失败!"+ex.Message.ToString();
return false;
}
}
#endregion
#region 修改密码
/// <summary>
/// 修改密码
/// </summary>
/// <param name="ude">用户</param>
/// <param name="password">旧密码</param>
/// <param name="password">新密码</param>
public bool ChangePassword(string username, string oldpwd, string newpwd)
{
try
{
DirectoryEntry entry = FindObject("user", username);
if (entry != null)
{
// to-do: 需要解决密码策略问题
entry.Invoke("ChangePassword", new object[] {oldpwd, newpwd });
entry.CommitChanges();
entry.Close();
DomainUser._success = "密码修改成功!";
return true;
}
else
{
DomainUser._failed = "没找到用户!" + username;
return false;
}
}
catch (Exception ex)
{
DomainUser._failed = "密码修改失败!"+ex.Message.ToString();
return false;
}
}
#endregion
#region 删除账户
/// <summary>
/// 删除AD账户,使用当前上下文的安全信息
/// </summary>
/// <param name="userName">用户名称</param>
public bool DeleteADAccount(string userName)
{
try
{
DirectoryEntry user = FindObject("user", userName);
if (user != null)
{
using (DirectoryEntry de = new DirectoryEntry(user.Parent.Path, adminUser, adminPwd))
{
de.Children.Remove(user);
de.CommitChanges();
DomainUser._success = "账户删除成功!";
return true;
}
}
DomainUser._failed = "未找到账户!";
return false;
}
catch (Exception ex)
{
DomainUser._failed = "账户删除失败!" + ex.Message.ToString();
return false;
}
}
#endregion
#region 创建OU
/// <summary>
/// 创建OU
/// </summary>
/// <param name="adminName">管理员名称</param>
/// <param name="adminPassword">管理员密码</param>
/// <param name="name">创建的OU名称</param>
/// <param name="parentOrganizeUnit">父组织单位</param>
/// <returns>目录实体</returns>
public DirectoryEntry CreateOrganizeUnit(string name, string parentOrganizeUnit)
{
DirectoryEntry parentEntry = null;
try
{
//示例顶级"LDAP://10.1.209.197/dc=bdxy,dc=com"
parentEntry = new DirectoryEntry(GetOrganizeNamePath(parentOrganizeUnit), adminUser, adminPwd,
AuthenticationTypes.Secure);
DirectoryEntry organizeEntry = parentEntry.Children.Add("OU=" + name, "organizationalUnit");
organizeEntry.CommitChanges();
DomainUser._success = "组织单位添加成功!";
return organizeEntry;
}
catch (System.DirectoryServices.DirectoryServicesCOMException ex)
{
DomainUser._failed = "添加组织单位失败!"+ex.Message.ToString();
_log.Error("添加组织单位失败!"+ex.Message.ToString());
Console.WriteLine("添加组织单位(" + parentOrganizeUnit + ")失败!");
return new DirectoryEntry();
}
finally
{
if (parentEntry != null)
{
parentEntry.Dispose();
}
}
}
#endregion
#region 删除OU
/// <summary>
/// 删除OU
/// </summary>
/// <param name="name">创建的OU名称</param>
/// <param name="parentOrganizeUnit">父组织单位</param>
/// <returns>目录实体</returns>
public bool DeleteOrganizeUnit(string name, string parentOrganizeUnit)
{
DirectoryEntry parentEntry = null;
try
{
//示例顶级"LDAP://10.1.209.197/dc=bdxy,dc=com"
parentEntry = new DirectoryEntry(GetOrganizeNamePath(parentOrganizeUnit), adminUser, adminPwd,
AuthenticationTypes.Secure);
DirectoryEntry organizeEntry = parentEntry.Children.Find("OU=" + name, "organizationalUnit");
//先删除组织单元下的用户或者组
parentEntry.Children.Remove(organizeEntry);
organizeEntry.CommitChanges();
DomainUser._success = "组织单位删除成功!";
return true;
}
catch (System.DirectoryServices.DirectoryServicesCOMException ex)
{
DomainUser._failed = "组织单位删除失败!"+ex.Message.ToString();
return false;
}
finally
{
if (parentEntry != null)
{
parentEntry.Dispose();
}
}
}
#endregion
#region 创建组
/// <summary>
/// 创建组
/// </summary>
/// <param name="name">组名</param>
/// <param name="OrganizeUnit">组织单位</param>
/// <returns>是否创建成功</returns>
public bool CreateGroup(string name, string OrganizeUnit)
{
DirectoryEntry parentEntry = null;
try
{
parentEntry = new DirectoryEntry(GetOrganizeNamePath(OrganizeUnit), adminUser, adminPwd,
AuthenticationTypes.Secure);
DirectoryEntry groupEntry = parentEntry.Children.Add("CN=" + name, "group");
groupEntry.CommitChanges();
DomainUser._success = "组创建成功!";
return true;
}
catch (System.DirectoryServices.DirectoryServicesCOMException ex)
{
DomainUser._failed = "组创建失败!"+ex.Message.ToString();
return false;
}
finally
{
if (parentEntry != null)
{
parentEntry.Dispose();
}
}
}
#endregion
#region 删除组
/// <summary>
/// 删除组
/// </summary>
/// <param name="name">组名</param>
/// <param name="OrganizeUnit">组织单位</param>
/// <returns>是否创建成功</returns>
public bool DeleteGroup(string name, string OrganizeUnit)
{
DirectoryEntry parentEntry = null;
try
{
parentEntry = new DirectoryEntry(GetOrganizeNamePath(OrganizeUnit), adminUser, adminPwd,
AuthenticationTypes.Secure);
DirectoryEntry groupEntry = parentEntry.Children.Find("CN=" + name, "group");
parentEntry.Children.Remove(groupEntry);
groupEntry.CommitChanges();
DomainUser._success = "组删除成功!";
return true;
}
catch (System.DirectoryServices.DirectoryServicesCOMException ex)
{
DomainUser._failed = "组删除失败!" + ex.Message.ToString();
return false;
}
finally
{
if (parentEntry != null)
{
parentEntry.Dispose();
}
}
}
#endregion
#region 将用户加入到用户组中
/// <summary>
/// 将用户加入到用户组中
/// </summary>
/// <param name="userName">用户名</param>
/// <param name="organizeName">组织名</param>
/// <param name="groupName">组名</param>
/// <param name="groupPath">组所在路径</param>
/// <exception cref="InvalidObjectException">用户名或用户组不存在</exception>
public bool AddUserToGroup(string userName, string groupName, string groupPath)
{
DirectoryEntry group = null;
DirectoryEntry user = null;
try
{
group = ExitGroup(groupName, groupPath);
user = ExitUser(userName);
if ((group != null) && (user != null))
{
//加入用户到用户组中
group.Properties["member"].Add(user.Properties["distinguishedName"].Value);
group.CommitChanges();
DomainUser._success = "用户成功加入组!";
return true;
}
else
{
return false;
}
}
catch (Exception ex)
{
DomainUser._failed = "加入组失败!"+ex.Message.ToString();
return false;
}
}
#endregion
#region 依据类别用户名 查找目录项
/// <summary>
/// 查找目录项
/// </summary>
/// <param name="category">分类 users</param>
/// <param name="name">用户名</param>
/// <returns>目录项实体</returns>
public DirectoryEntry FindObject(string category, string name)
{
DirectoryEntry de = null;
DirectorySearcher ds = null;
DirectoryEntry userEntry = null;
try
{
de = new DirectoryEntry(GetDomainPath(), adminUser, adminPwd, AuthenticationTypes.Secure);
ds = new DirectorySearcher(de);
string queryFilter = string.Format("(&(objectCategory=" + category + ")(sAMAccountName={0}))", name);
ds.Filter = queryFilter;
ds.Sort.PropertyName = "cn";
SearchResult sr = ds.FindOne();
if (sr != null)
{
userEntry = sr.GetDirectoryEntry();
}
return userEntry;
}
catch (Exception ex)
{
DomainUser._failed = ex.Message.ToString();
return new DirectoryEntry();
}
finally
{
if (ds != null)
{
ds.Dispose();
}
if (de != null)
{
de.Dispose();
}
}
}
#endregion
#region 获取组织名称路径
/// <summary>
/// 获取组织名称路径
/// </summary>
/// <param name="organizeUnit">组织</param>
/// <returns></returns>
public string GetOrganizeNamePath(string organizeUnit)
{
StringBuilder sb = new StringBuilder();
sb.Append(_ldapIdentity);
return sb.Append(SplitOrganizeNameToDN(organizeUnit)).ToString();
}
#endregion
#region 分隔组织名称为标准AD的DN名称
/// <summary>
/// 分隔组织名称为标准AD的DN名称,各个组织级别以"/"或"/"分开。如"总部/物业公司/小区",并且当前域为
/// bdxy.com,则返回的AD的DN表示名为"OU=小区,OU=物业公司,OU=总部,DC=bdxy,DC=com"。
/// </summary>
/// <param name="organizeName">组织名称</param>
/// <returns>返回一个级别</returns>
public string SplitOrganizeNameToDN(string organizeName)
{
StringBuilder sb = new StringBuilder();
if (organizeName.Equals("Users") || string.IsNullOrEmpty(organizeName))
{
sb.Append("CN=Users,").Append(_suffixPath);
return sb.ToString();
}
else
{
if (organizeName != null && organizeName.Length > 0)
{
string[] allOu = organizeName.Split(new char[] { '/' });
for (int i = allOu.Length - 1; i >= 0; i--)
{
string ou = allOu[i];
if (sb.Length > 0)
{
sb.Append(",");
}
sb.Append("OU=").Append(ou);
}
}
//如果传入了组织名称,则添加,
if (sb.Length > 0)
{
sb.Append(",");
}
sb.Append(_suffixPath);
return sb.ToString();
}
}
#endregion
#region 获取域路径
/// <summary>
/// 获取域路径
/// </summary>
/// <returns>路径</returns>
public string GetDomainPath()
{
using (DirectoryEntry root = new DirectoryEntry(_ldapIdentity + _suffixPath, adminUser, adminPwd))
{
return root.Path;
}
}
#endregion
#region 获取Users容器的路径
/// <summary>
/// 获取Users容器的下用户的路径
/// </summary>
/// <param name="userName">用户名</param>
/// <returns></returns>
private string GetUserPath(string userName)
{
StringBuilder sb = new StringBuilder();
sb.Append(_ldapIdentity);
if (userName != null && userName.Length > 0)
{
sb.Append("CN=").Append(userName).Append(",");
}
sb.Append("CN=Users,").Append(_suffixPath);
return sb.ToString();
}
#endregion
#region 根据用户所在的组织结构来构造用户在AD中的DN路径
/// <summary>
/// 根据用户所在的组织结构来构造用户在AD中的DN路径
/// </summary>
/// <param name="userName">用户名称</param>
/// <param name="organzieName">组织结构</param>
/// <returns></returns>
public string GetUserPath(string userName, string organzieName)
{
StringBuilder sb = new StringBuilder();
sb.Append(_ldapIdentity);
sb.Append("CN=").Append(userName).Append(",").Append(SplitOrganizeNameToDN(organzieName));
return sb.ToString();
}
#endregion
#region 启用账户
/// <summary>
/// 启用账户
/// </summary>
/// <param name="user"></param>
public bool EnableAccount(string userName)
{
try
{
DirectoryEntry userEntry = FindObject("user", userName);
int val = (int)userEntry.Properties["userAccountControl"].Value;
userEntry.Properties["userAccountControl"].Value = val & ~0x2;
userEntry.CommitChanges();
userEntry.Close();
DomainUser._success = "启用账户成功!";
return true;
}
catch (Exception ex)
{
DomainUser._failed = ex.Message.ToString();
return false;
}
}
#endregion
#region 停用账号
/// <summary>
/// 停用账号
/// </summary>
/// <param name="user"></param>
public bool DisableAccount(string userName)
{
try
{
DirectoryEntry userEntry = FindObject("user", userName);
userEntry.Properties["userAccountControl"].Value = 0x2;
userEntry.CommitChanges();
userEntry.Close();
DomainUser._success = "停用账户成功!";
return true;
}
catch (System.DirectoryServices.DirectoryServicesCOMException ex)
{
DomainUser._failed = ex.Message.ToString();
return false;
}
}
#endregion
#region 判断用户是否已经存在域中
/// <summary>
/// 判断用户是否已经存在域中
/// </summary>
/// <param name="userName">用户名</param>
/// <returns></returns>
private DirectoryEntry ExitUser(string userName)
{
try
{
DirectoryEntry de = null;
de = FindObject("user", userName);
if (de == null)
{
return new DirectoryEntry(); ;
}
else
{
return de;
}
}
catch (Exception ex)
{
DomainUser._failed = ex.Message.ToString();
return new DirectoryEntry();
}
}
#endregion
#region 判断域中是否存在组
/// <summary>
/// 判断域中是否存在组
/// </summary>
/// <param name="groupName">组名</param>
/// <returns></returns>lan
private DirectoryEntry ExitGroup(string groupName, string groupPath)
{
DirectoryEntry rootUser = null;
DirectoryEntry group = null;
DirectoryEntry test = null;
string path = GetOrganizeNamePath(groupPath);
rootUser = new DirectoryEntry(path, adminUser, adminPwd);
test = new DirectoryEntry("WinNT://annet-or2,computer");
try
{
var a = test.Children.Add("Users", "user");
group = rootUser.Children.Find(groupName, "group");
group = rootUser.Children.Find("CN=" + groupName);
if (group != null)
{
return group;
}
return new DirectoryEntry();
}
catch (Exception ex)
{
//CreateGroup(groupName, path);
//group = rootUser.Children.Find("CN=" + groupName);
DomainUser._failed = ex.Message.ToString() + "在域中不存在组“" + groupName + "”或路组织单位不正确";
return new DirectoryEntry();
}
}
#endregion
#region 判断域中是否存在组织单位
/// <summary>
/// 判断域中是否存在组织单位
/// </summary>
/// <param name="organizeName">组织单位名</param>
/// <returns></returns>
public bool ExitOU(string organizeName)
{
DirectoryEntry rootUser = null;
DirectoryEntry ouFind = null;
if (string.IsNullOrEmpty(organizeName))
{
return true;
}
else
{
//分解路径
string[] allOu = organizeName.Split(new char[] { '/' });
//获取直属部门
string OUName = allOu[allOu.Length - 1].ToString();
try
{
string path = GetOrganizeNamePath(organizeName);
rootUser = new DirectoryEntry(path, adminUser, adminPwd, AuthenticationTypes.Secure);
ouFind = rootUser.Parent.Children.Find("OU=" + OUName);
if (ouFind != null)
{
return true;
}
return false;
}
catch (Exception ex)
{
DomainUser._failed = ex.Message.ToString() + "在域中不存在组织单位“" + OUName + "”";
return false;
}
}
}
#endregion
#region 获取域用户信息
/// <summary>
/// 获取域用户信息
/// </summary>
/// <param name="path">目录</param>
/// <param name="username">用户名</param>
/// <returns></returns>
public DomainUser GetAdUserInfo(string userName)
{
DomainUser du = new DomainUser();
DirectoryEntry de = FindObject("user", userName);
if (de != null)
{
if (de.Properties["samAccountName"].Value != null)
{
du.UserId = de.Properties["samAccountName"].Value.ToString();
}
if (de.Properties["displayName"].Value != null)
{
du.UserName = de.Properties["displayName"].Value.ToString();
}
if (de.Properties["userPrincipalName"].Value != null)
{
du.UserPrincipalName = de.Properties["userPrincipalName"].Value.ToString();
}
if (de.Properties["telephoneNumber"].Value != null)
{
du.Telephone = de.Properties["telephoneNumber"].Value.ToString();
}
if (de.Properties["mail"].Value != null)
{
du.Email = de.Properties["mail"].Value.ToString();
}
if (de.Properties["description"].Value != null)
{
du.Description = de.Properties["description"].Value.ToString();
}
if (de.Properties["Department"].Value != null)
{
du.Department = de.Properties["Department"].Value.ToString();
}
}
return du;
}
#endregion
#region 从域中按照用户名查找用户
/// <summary>
/// 从域中按照用户名查找用户
/// </summary>
/// <param name="path">路径</param>
/// <param name="AdUser">管理员账户</param>
/// <param name="AdPwd">管理员密码</param>
/// <param name="username">用户名</param>
/// <returns></returns>
private DirectoryEntry GetUser(string path, string username)
{
DirectoryEntry deuser;
try
{
DirectoryEntry de = new DirectoryEntry(path, adminUser, adminPwd);
DirectorySearcher deSearch = new DirectorySearcher(de);
deSearch.Filter = "(&(objectClass=user)(cn=" + username + "))";
deSearch.SearchScope = SearchScope.Subtree;
SearchResult result = deSearch.FindOne();
if (result != null)
{
deuser = result.GetDirectoryEntry();
return deuser;
}
else
{
return null;
}
}
catch (Exception ex)
{
DomainUser._failed = ex.Message.ToString();
return null;
}
}
#endregion
#region 进入AD域查询
/// <summary>
/// 查寻用户信息
/// </summary>
/// <param name="userName">用户名</param>
private List<string> AccsesADQuery(string userName)
{
//定义de进入AD架构
DirectoryEntry de = new DirectoryEntry(GetDomainPath(), adminUser, adminPwd);
//定义ds查找AD
DirectorySearcher ds = new DirectorySearcher(de);
string value = string.Empty;
List<string> domainList = new List<string>();
try
{
//3.定义查询
ds.Filter = "(SAMAccountName=" + userName + ")";
ds.PropertiesToLoad.Add("SAMAccountName");//account
ds.PropertiesToLoad.Add("Name");//full name
ds.PropertiesToLoad.Add("displayName");
ds.PropertiesToLoad.Add("mail");
ds.PropertiesToLoad.Add("sn");
ds.PropertiesToLoad.Add("description");
ds.PropertiesToLoad.Add("Department");
ds.PropertiesToLoad.Add("userPrincipalName");//user logon name,xxx@bdxy.com
ds.PropertiesToLoad.Add("physicalDeliveryOfficeName");
ds.PropertiesToLoad.Add("telephoneNumber");
//查找一个
SearchResult sr = ds.FindOne();
if (sr != null)
{
//列出值
foreach (string key in sr.Properties.PropertyNames)
{
foreach (object obj in de.Properties[key])
{
value += key + " = " + obj + Environment.NewLine;
domainList.Add(value);
}
}
return domainList;
}
else
{
return domainList;
}
}
catch (Exception ex)
{
DomainUser._failed = ex.Message.ToString();
return domainList;
}
finally
{
if (ds != null)
{
ds.Dispose();
}
if (de != null)
{
de.Dispose();
}
}
}
#endregion
}
}