项目需求:
同步人事系统的组织架构-对应AD的OU树
同步人事系统的员工-对应AD的用户

创建OU 名字不能重复,需要父级路径(parentOrganizeUnit)以及新ou的名字(name),如果最父级则上级路径为域节点
DirectoryEntry CreateOrganizeUnit(string OrgId,string name, string parentOrganizeUnit,int Id,ADInfo ad)

更改OU名称 需要旧的OU路径(oldUnit)以及“OU=新OUName”(newUnit)
DirectoryEntry UpdateOrganizeUnit(string newUnit, string OUName, string oldUnit, int Id,ADInfo ad) 使用Renname

更改OU上级 需要新的上级路径(newparentOrganizeUnit)旧OU的路径(oldUnit)
DirectoryEntry MoveOrganizeUnit(string oldUnit, string newparentOrganizeUnit, int Id,ADInfo ad)

创建ou用户需要ou路径(orgPath) 以及用户信息(user)
AddADAccount(string orgPath, EmpInfo user, int Id,ADInfo ad)
注意ou树下的名字是cn字段(不能重复),cn需要重新赋值时用rename
sAMAccountName 用户(不能重复)
userPrincipalName 有域名的用户名 (不能重复)
邮箱为空不能赋值(mail)

移动用户 需要用户路径(user_path)以及OU路径(target_path)
MoveUser(string user_path, string target_path,string OuName, int Id,ADInfo ad)

设置密码

NewUser.Invoke("SetPassword", new object[] { accountPwd });

设置用户下次登录必须修改密码

NewUser.Properties["pwdLastSet"].Value = 0;

对应TXT 代码

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Quartz;
using vxTalent.Schedule.DALBase;
using System.Data;
using System.DirectoryServices;
using vxTalent.Schedule.DALBase.AD;
using System.Configuration;
using System.Reflection;
using Microsoft.International.Converters.PinYinConverter;
namespace vxTalent.User.ModuleJob.AD
{
public class ADSynData : IJob
{
private static readonly log4net.ILog logger = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
private static bool IsSendSMSLocked = false;
private static readonly object lynLock = new object();
ADSynDataAccess asy = new ADSynDataAccess();
/// <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>
string accountPwd = ObjConvert.ObjString(ConfigurationManager.AppSettings["AdInitPwd"]) == "" ? "abc12345!" : ObjConvert.ObjString(ConfigurationManager.AppSettings["AdInitPwd"]);
int i = ; //重复变量
private string sAMAccountName = "";
protected int AdRepeatNum = ObjConvert.ObjInt(ConfigurationManager.AppSettings["AdRepeatNum"]) == ? : ObjConvert.ObjInt(ConfigurationManager.AppSettings["AdRepeatNum"]);
string cnName = ""; public void Test() { string domain_ = row["ADName"].ToString();
string domainIp_ = row["ADUrl"].ToString();
string adminUser_ = row["ADName"].ToString() + "\\" + row["UserName"].ToString();
string adminPwd_ = row["Pwd"].ToString();
string ldapIdentity_ = "LDAP://" + domainIp_ + "/";
string houzhui_ = row["ADSur"].ToString() != "" ? row["ADSur"].ToString() : "com";
string suffixPath_ = "DC=" + domain_ + ",DC=" + houzhui_;
ADInfo ad = new ADInfo
{
adsur = houzhui_,
domain = domain_,
domainIp = domainIp_,
ldapIdentity = ldapIdentity_,
suffixPath = suffixPath_,
adminPwd = adminPwd_,
adminUser = adminUser_,
houzhui=houzhui_,
dbCon = dbString
}; RunData(dbString, ad);
} /// <summary>
/// 遍历每个 库的待同步数据
/// </summary>
/// <param name="conn"></param>
protected void RunData(string conn,ADInfo ad ) {
DataTable waitingData = asy.GetWaitingData(conn);
if (waitingData != null && waitingData.Rows.Count > ) {
string operation = "";
foreach (DataRow item in waitingData.Rows)
{
try
{
int synId = ObjConvert.ObjInt(item["Id"]);
operation = ObjConvert.ObjString(item["Operation"]);
//部门操作
if (ObjConvert.ObjString(item["SynType"]) == "")
{
string path = "", orgName = "", relateId = ObjConvert.ObjString(item["RelateID"]);
DataTable orgDatatable = asy.GetOrgById(conn, relateId); string parentOrgId = ""; string name = "";
if (orgDatatable != null && orgDatatable.Rows.Count > )
{
name = ObjConvert.ObjString(orgDatatable.Rows[]["organizationalname"]); parentOrgId = ObjConvert.ObjString(orgDatatable.Rows[]["ParentOrganizationalID"]);
}
else
{
DataTable hisTable = asy.GetHistoryOrg(conn, relateId);
if (hisTable != null && hisTable.Rows.Count > )
{
name = ObjConvert.ObjString(hisTable.Rows[]["organizationalname"]);
parentOrgId = ObjConvert.ObjString(hisTable.Rows[]["ParentOrganizationalID"]);
} } switch (operation)
{
case "Add":
//parentPath = asy.GetPathOrgId(conn, ObjConvert.ObjString(orgDatatable.Rows[0]["ParentOrganizationalID"]));
CreateOrganizeUnit(relateId, name, parentOrgId, synId, ad); break;
case "ParentChange":
//MovePath = asy.GetPathOrgId(conn, ObjConvert.ObjString(item["MergeDeleteId"]));
MoveOrganizeUnit(relateId, ObjConvert.ObjString(item["MergeDeleteId"]), synId, ad); break;
case "Update":
// string repl= oldOrgName.Split('/')[0];
orgName = "OU=" + name;
UpdateOrganizeUnit(orgName, name, relateId, synId, ad); break;
case "Merge":
string[] arrDeleteId = ObjConvert.ObjString(item["MergeDeleteId"]).Split(',');
MergeOu(arrDeleteId, ObjConvert.ObjString(item["RelateID"]), name, synId, ad);
break;
case "Disable": //禁用加+封存
orgName = "OU=" + name + "(封存)";
UpdateOrganizeUnit(orgName, name + "(封存)", relateId, synId, ad); break; } }
else
{ //人员操作
DataTable empTable = asy.GetEmpById(conn, ObjConvert.ObjInt(item["RelateID"]));
EmpInfo empDetail = new EmpInfo(); if (empTable != null && empTable.Rows.Count > )
{ string CNName = ObjConvert.ObjString(empTable.Rows[]["CNName"]);
string piyin = ObjConvert.ObjString(empTable.Rows[]["Pinyin"]);
if (string.IsNullOrEmpty(piyin))
{
piyin = ObjConvert.ObjStringToLower(PingYinHelper.ConvertToAllSpell(CNName));
}
string ADName = ObjConvert.ObjString(empTable.Rows[]["CN_ADName"]);
empDetail.emloyeeID = ObjConvert.ObjString(empTable.Rows[]["EmpCode"]);
empDetail.sAMAccountName = string.IsNullOrEmpty(ADName) ? ObjConvert.ObjStringToLower(piyin) : ObjConvert.ObjStringToLower(ADName);
empDetail.userPrincipalName = empDetail.sAMAccountName + "@" + ad.domain + "." + ad.adsur;
empDetail.employeeType = ObjConvert.ObjString(empTable.Rows[]["empTypeText"]);
empDetail.DepartmentName = ObjConvert.ObjString(empTable.Rows[]["OrganizationalName"]);
empDetail.Mail = ObjConvert.ObjString(empTable.Rows[]["Email"]);
empDetail.DisplayName = CNName;
if (CNName.Length > )
{
empDetail.Surname = CNName.Substring(, );//姓
empDetail.GivenName = CNName.Substring(, CNName.Length - );//名
}
else
{
empDetail.Surname = CNName;
}
empDetail.Department = ObjConvert.ObjString(empTable.Rows[]["OrganizationalID"]); empDetail.Oupath = GetOuDirectory(empDetail.Department, ad).Path;
//string newouName = asy.GetOrgName(conn, ObjConvert.ObjString(empTable.Rows[0]["OrganizationalID"]));
string newouName = "";
string newPath = "";
switch (operation)
{
case "Add":
i = ;
cnName = empDetail.DisplayName;
sAMAccountName = empDetail.sAMAccountName;
AddADAccount(empDetail.Oupath, empDetail, synId, ad); break;
case "Dimission":
DisableUser(empDetail.sAMAccountName, synId, ad); break;
case "Mobilize":
if (ObjConvert.ObjString(item["MergeDeleteId"]) != "")
{
newouName = asy.GetOrgName(conn, ObjConvert.ObjString(item["MergeDeleteId"]));
newPath = GetOuDirectory(ObjConvert.ObjString(item["MergeDeleteId"]), ad).Path;
}
else {
newouName = asy.GetOrgName(conn, empDetail.Department);
newPath = GetOuDirectory(empDetail.Department, ad).Path;
}
MoveUser(GetDirectoryEntryByAccount(empDetail.sAMAccountName, ad).Path, newPath, newouName, synId, ad);
break;
case "Update": UpdateUser(empDetail, synId, ad); break;
case "Rehab":
EnableUser(empDetail.sAMAccountName, synId, ad);
UpdateUser(empDetail, synId, ad);
newouName = asy.GetOrgName(conn, ObjConvert.ObjString(empTable.Rows[]["OrganizationalID"]));
MoveUser(GetDirectoryEntryByAccount(empDetail.sAMAccountName, ad).Path, empDetail.Oupath, newouName, synId, ad);
break; //重聘启用 用户 更新 并且可能移动部门
}
}
}
}
catch (Exception e) { logger.Error(e.Message); }
}
} } #region 创建OU
/// <summary>
/// 创建OUl
/// </summary>
/// <param name="adminName">管理员名称</param>
/// <param name="adminPassword">管理员密码</param>
/// <param name="name">创建的OU名称</param>
/// <param name="parentOrganizeUnit">父组织单位</param>
/// <returns>目录实体</returns>
public DirectoryEntry CreateOrganizeUnit(string OrgId,string name, string parentOrganizeUnit,int Id,ADInfo ad)
{ DirectoryEntry parentEntry = null;
try
{
string parentPath = "";
DirectoryEntry de = GetOuDirectory(parentOrganizeUnit,ad);
if (de == null)
{
parentPath = GetOrganizeNamePath("",ad);
}
else {
parentPath = de.Path;
} //示例顶级""
parentEntry = new DirectoryEntry(parentPath, ad.adminUser, ad.adminPwd,
AuthenticationTypes.Secure);
DirectoryEntry organizeEntry = parentEntry.Children.Add("OU=" + name, "organizationalUnit");
organizeEntry.Properties["postalCode"].Value = OrgId;
organizeEntry.CommitChanges();
//DomainUser._success = "组织单位添加成功!";
logger.Info("创建OU成功" + name);
asy.UpdateStatus(ad.dbCon,Id,"Success");
return organizeEntry;
}
catch (System.DirectoryServices.DirectoryServicesCOMException ex)
{
//DomainUser._failed = "添加组织单位失败!"+ex.Message.ToString();
logger.Error("创建OU失败"+name+":"+ex.Message);
asy.UpdateStatus(ad.dbCon, Id, "Error", ex.Message);
return new DirectoryEntry();
}
finally
{
if (parentEntry != null)
{
parentEntry.Dispose();
}
}
}
#endregion #region 更改OU名称
public DirectoryEntry UpdateOrganizeUnit(string newUnit, string OUName, string oldUnit, int Id,ADInfo ad)
{
DirectoryEntry parentEntry = null;
try
{
List<DirectoryEntry> list = GetListDirectory(GetOuDirectory(oldUnit,ad).Path,ad);
if (list != null && list.Count > ) {
foreach (DirectoryEntry item in list)
{
item.Properties["department"][] = OUName;
item.CommitChanges();
item.Dispose();
}
} //示例顶级""
parentEntry = new DirectoryEntry(GetOuDirectory(oldUnit,ad).Path, ad.adminUser, ad.adminPwd,
AuthenticationTypes.Secure); parentEntry.Rename(newUnit);
parentEntry.CommitChanges();
logger.Info("更新OU成功" + OUName);
asy.UpdateStatus(ad.dbCon, Id, "Success");
return parentEntry;
}
catch (System.DirectoryServices.DirectoryServicesCOMException ex)
{
logger.Error("更改OU失败" + OUName + ":" + ex.Message);
asy.UpdateStatus(ad.dbCon, Id, "Error", ex.Message);
return new DirectoryEntry();
}
finally
{
if (parentEntry != null)
{
parentEntry.Dispose();
}
}
}
#endregion #region 移动OU
public DirectoryEntry MoveOrganizeUnit(string oldUnit, string newparentOrganizeUnit, int Id,ADInfo ad)
{
DirectoryEntry Entry = null;
try
{
//示例顶级""
Entry = new DirectoryEntry(GetOuDirectory(oldUnit, ad).Path, ad.adminUser, ad.adminPwd,
AuthenticationTypes.Secure);
DirectoryEntry parentEntry = new DirectoryEntry(GetOuDirectory(newparentOrganizeUnit, ad).Path, ad.adminUser, ad.adminPwd,
AuthenticationTypes.Secure);
Entry.MoveTo(parentEntry);
Entry.CommitChanges();
logger.Info("更改OU父节点成功" + oldUnit);
asy.UpdateStatus(ad.dbCon, Id, "Success");
return Entry;
}
catch (System.DirectoryServices.DirectoryServicesCOMException ex)
{
logger.Error("更改OU父节点:" + oldUnit + ":" + ex.Message);
asy.UpdateStatus(ad.dbCon, Id, "Error", ex.Message);
return new DirectoryEntry();
}
finally
{
if (Entry != null)
{
Entry.Dispose();
}
}
}
#endregion #region 合并OU
public void MergeOu(string[] deleteArr, string newUnit, string OUName,int Id,ADInfo ad)
{ //DataTable mergeEmpTable = asy.GetMergeListBySynId(ad.dbCon, Id);
try
{
if (deleteArr.Length > )
{
DirectoryEntry t = new DirectoryEntry(GetOuDirectory(newUnit, ad).Path, ad.adminUser, ad.adminPwd);
for (int i = ; i < deleteArr.Length; i++)
{ List<DirectoryEntry> list = GetListDirectory(GetOuDirectory(deleteArr[i],ad).Path,ad);
if (list != null && list.Count > )
{
//if (mergeEmpTable != null && mergeEmpTable.Rows.Count > 0)
//{
foreach (DirectoryEntry item in list)
{ string saName = ObjConvert.ObjString(item.Properties["sAMAccountName"][]);
//DataRow[] dtrows= mergeEmpTable.Select("CN_ADName='" + saName + "'");
//if (dtrows != null && dtrows.Count() > 0) { //服务逻辑是先同步部门操作,合并的时候
//可能发生 已经从这个部门调转出去了,但是服务先合并到别的部门了,所有没法后续的人员调岗操作了
//同时更改部门用户名字
item.Properties["department"][] = OUName; item.CommitChanges();
//更改OU
item.MoveTo(t); item.Dispose();
//} }
//}
} }
logger.Info("合并OU成功" + OUName);
asy.UpdateStatus(ad.dbCon, Id, "Success");
}
}
catch (Exception t)
{
logger.Error("合并异常:" + OUName + t.Message);
asy.UpdateStatus(ad.dbCon, Id, "Error", t.Message);
} }
#endregion #region 组织结构下添加AD账户
/// <summary>
/// 添加AD账户
/// </summary>
/// <param name="organizeName">组织名称</param>
/// <param name="user">域账户</param>
/// <returns>添加是否成功</returns>
public void AddADAccount(string orgPath, EmpInfo user, int Id,ADInfo ad)
{ DirectoryEntry entry = null;
try
{
if (IsExistOuPath(orgPath,ad) && user != null)
{
if (!IsAccExists(user.sAMAccountName, ad))
{
string cn = GetCnName(user.DisplayName, ad);
entry = new DirectoryEntry(orgPath, ad.adminUser, ad.adminPwd, AuthenticationTypes.Secure);
//增加账户到域中
DirectoryEntry NewUser = entry.Children.Add("CN=" + cn, "user");
NewUser.Properties["sAMAccountName"].Add(user.sAMAccountName); //account
NewUser.Properties["userPrincipalName"].Value = user.userPrincipalName; //user logon name,xxx@bdxy.com NewUser.Properties["employeeID"].Value = user.emloyeeID;
NewUser.Properties["employeeType"].Value = user.employeeType;
NewUser.Properties["Department"].Value = user.DepartmentName;
NewUser.Properties["displayName"].Value = user.DisplayName;
// NewUser.Properties["name"].Value = user.DisplayName;
//NewUser.Properties["Surname"].Value = user.Surname;
NewUser.Properties["givenName"].Value = user.GivenName;
NewUser.Properties["Sn"].Value = user.Surname;
if (user.Mail != null && user.Mail != "")
{
NewUser.Properties["mail"].Value = user.Mail;
}
NewUser.CommitChanges();
//设置密码
//反射调用修改密码的方法(注意端口号的问题 端口号会引起方法调用异常)
NewUser.Invoke("SetPassword", new object[] { accountPwd });
//默认设置新增账户启用
NewUser.Properties["userAccountControl"].Value = 0x200;
NewUser.CommitChanges();
//DomainUser._success = "账户添加成功!";
logger.Info("账户添加成功" + user.sAMAccountName);
asy.UpdateADPinyin(ad.dbCon, Id, user.sAMAccountName);
asy.UpdateStatus(ad.dbCon, Id, "Success"); }
else {
if (i <= AdRepeatNum)
{
i++;
user.sAMAccountName = sAMAccountName + "" + i.ToString();
user.userPrincipalName = sAMAccountName + "" + i + "@" + ad.domain + "." + ad.houzhui;
AddADAccount(orgPath, user, Id, ad);
}
logger.Error("创建OU重复:" + sAMAccountName + i.ToString() + "次");
} }
else
{
logger.Error("创建OU失败:在域中不存在直属组织单位" + user.sAMAccountName);
asy.UpdateStatus(ad.dbCon, Id, "Error", "在域中不存在直属组织单位"); } }
catch (Exception ex)
{
logger.Error("创建OU失败:" + sAMAccountName + ex.Message);
asy.UpdateStatus(ad.dbCon, Id, "Error", ex.Message); }
finally
{
if (entry != null)
{
entry.Dispose();
}
}
}
#endregion public string GetCnName(string cn, ADInfo ad)
{ if (i < AdRepeatNum)
{
if (IsAccExistsCN(cn, ad))
{
cn = cnName + "" + i.ToString();
i++;
GetCnName(cn, ad); } }
return cn; } /// <summary>
/// 移动用户(调岗)
/// </summary>
/// <param name="user_path">用户Path</param>
/// <param name="target_path">目标path</param>
/// <returns></returns>
public string MoveUser(string user_path, string target_path,string OuName, int Id,ADInfo ad)
{
try
{
DirectoryEntry u = new DirectoryEntry(user_path, ad.adminUser, ad.adminPwd);
DirectoryEntry t = new DirectoryEntry(target_path, ad.adminUser, ad.adminPwd); //同时更改部门用户名字
u.Properties["department"][] = OuName;
u.CommitChanges();
//更改OU
u.MoveTo(t); u.Dispose(); logger.Info("用户调岗成功" + user_path);
asy.UpdateStatus(ad.dbCon, Id, "Success");
return u.Path;
}
catch(Exception ex){
logger.Error("用户调岗失败:" + user_path + "," + target_path + ex.Message);
asy.UpdateStatus(ad.dbCon, Id, "Error", ex.Message);
return "";
} }
/// <summary>
/// 初始化移动 用户
/// </summary>
/// <param name="user_path"></param>
/// <param name="target_path"></param>
/// <param name="OuName"></param>
/// <param name="ad"></param>
/// <param name="empCode"></param>
/// <returns></returns>
public string MoveUser(string user_path, string target_path, string OuName, ADInfo ad,string empCode)
{
try
{
DirectoryEntry u = new DirectoryEntry(user_path, ad.adminUser, ad.adminPwd);
DirectoryEntry t = new DirectoryEntry(target_path, ad.adminUser, ad.adminPwd); //同时更改部门用户名字
u.Properties["department"].Value = OuName;
u.CommitChanges();
//更改OU
u.MoveTo(t); u.Dispose(); logger.Info("用户移动成功" + empCode +":"+ user_path);
return u.Path;
}
catch (Exception ex)
{
logger.Error("用户移动失败:" + empCode +":"+ user_path + "," + target_path + ex.Message);
return "";
} }
/// <summary>
/// 禁用指定的帐户(离职)
/// </summary>
/// <param name="de"></param>
public static void DisableUser(DirectoryEntry de)
{ //impersonate.BeginImpersonate();
de.Properties["userAccountControl"][] =
0X0200 | 0X0002;
de.CommitChanges();
//impersonate.StopImpersonate();
de.Close(); } /// <summary>
/// 禁用指定公共名称的用户
/// </summary>
/// <param name="commonName">用户公共名称</param>
public void DisableUser(string sAMacc, int Id,ADInfo ad)
{
try
{
DisableUser(GetDirectoryEntryByAccount(sAMacc,ad));
logger.Info("用户禁用成功:" + sAMacc);
asy.UpdateStatus(ad.dbCon, Id, "Success");
}
catch(Exception ex)
{
logger.Error("用户禁用失败:" + sAMacc+ ex.Message);
asy.UpdateStatus(ad.dbCon, Id, "Error", ex.Message);
}
} /// <summary>
/// 启用指定的域账号
/// </summary>
/// <param name="sAMacc">用户的域账号名称</param>
public bool EnableUser(string sAMacc, int Id, ADInfo ad)
{
try
{
EnableUser(GetDirectoryEntryByAccount(sAMacc, ad));
logger.Info("用户启用成功:" + sAMacc);
asy.UpdateStatus(ad.dbCon, Id, "Success");
return true;
}
catch (Exception ex)
{
logger.Error("用户启用失败:" + sAMacc + ex.Message);
asy.UpdateStatus(ad.dbCon, Id, "Error", ex.Message);
return false;
}
} /// <summary>
/// 启用指定帐户
/// </summary>
/// <param name="de"></param>
public void EnableUser(DirectoryEntry de)
{ de.Properties["userAccountControl"][] =
0X0200;
de.CommitChanges();
de.Close();
} /// <summary>
/// 更新用户 (基本信息 显示名、员工类型、姓和名)
/// </summary>
/// <param name="user"></param>
public void UpdateUser(EmpInfo user, int Id,ADInfo ad)
{ try
{
if (IsAccExists(user.sAMAccountName, ad))
{
DirectoryEntry userEntry = GetDirectoryEntryByAccount(user.sAMAccountName, ad);
//userEntry.Properties["cn"][0] = newDisplayName; userEntry.Rename("CN=" + user.DisplayName);
userEntry.Properties["displayName"][] = user.DisplayName;
// userEntry.Properties["name"][0] = user.DisplayName;
userEntry.Properties["employeeType"][] = user.employeeType;
userEntry.Properties["Sn"][] = user.Surname;//姓
userEntry.Properties["GivenName"][] = user.GivenName;//名
if (!string.IsNullOrEmpty(user.Mail)) { userEntry.Properties["Mail"][] = user.Mail;}
//userEntry.Properties["Mail"][0] = user.Mail;//邮件
// userEntry.Rename("CN=" + newDisplayName);
userEntry.CommitChanges();
userEntry.Dispose();
logger.Info("用户更新成功:" + user.sAMAccountName);
asy.UpdateStatus(ad.dbCon, Id, "Success");
} }
catch (Exception ex)
{
logger.Error("用户更新失败:" + user.sAMAccountName + ex.Message);
asy.UpdateStatus(ad.dbCon, Id, "Error", ex.Message); }
}
public void UpdateUser(EmpInfo user, ADInfo ad)
{
try
{
if (IsAccExists(user.sAMAccountName, ad))
{
DirectoryEntry userEntry = GetDirectoryEntryByAccount(user.sAMAccountName, ad);
//userEntry.Properties["cn"][0] = newDisplayName;
userEntry.Properties["displayName"].Value = user.DisplayName;
userEntry.Properties["employeeID"].Value = user.emloyeeID;
// userEntry.Properties["name"].Value = user.DisplayName;
userEntry.Properties["employeeType"].Value = user.employeeType;
userEntry.Properties["Sn"].Value = user.Surname;//姓
userEntry.Properties["GivenName"].Value = user.GivenName;//名
if (!string.IsNullOrEmpty(user.Mail)) { userEntry.Properties["Mail"].Value = user.Mail; }
// userEntry.Properties["Mail"].Value = user.Mail;//邮件
// userEntry.Rename("CN=" + newDisplayName);
userEntry.CommitChanges();
userEntry.Dispose();
logger.Info("用户更新成功:" + user.sAMAccountName);
} }
catch (Exception ex)
{
logger.Error("用户更新失败:" + user.sAMAccountName + ex.Message); }
}
/// <summary>
/// 根据用户帐号称取得用户的 对象
/// </summary>
/// <param name="sAMAccountName">用户帐号名</param>
/// <returns>如果找到该用户,则返回用户的 对象;否则返回 null</returns>
public DirectoryEntry GetDirectoryEntryByAccount(string sAMAccountName,ADInfo ad)
{
DirectoryEntry de = GetDirectoryObject(ad);
DirectorySearcher deSearch = new DirectorySearcher(de); // DirectoryEntry de = new DirectoryEntry(path, adminUser, adminPwd, AuthenticationTypes.Secure);
deSearch.Filter = "(&(&(objectCategory=person)(objectClass=user))(sAMAccountName=" + sAMAccountName + "))";
deSearch.SearchScope = SearchScope.Subtree;
try
{
SearchResult result = deSearch.FindOne();
de = new DirectoryEntry(result.Path, ad.adminUser, ad.adminPwd);
return de;
}
catch (Exception ex)
{
return null;
}
} /// <summary>
/// 根据用户帐号称取得用户的 对象
/// </summary>
/// <param name="sAMAccountName">用户帐号名</param>
/// <returns>如果找到该用户,则返回用户的 对象;否则返回 null</returns>
public string GetDirectoryPathEntryByAccount(string sAMAccountName, ADInfo ad)
{
DirectoryEntry de = GetDirectoryObject(ad);
DirectorySearcher deSearch = new DirectorySearcher(de);
string path="";
// DirectoryEntry de = new DirectoryEntry(path, adminUser, adminPwd, AuthenticationTypes.Secure);
deSearch.Filter = "(&(&(objectCategory=person)(objectClass=user))(sAMAccountName=" + sAMAccountName + "))";
deSearch.SearchScope = SearchScope.Subtree;
try
{
SearchResult result = deSearch.FindOne();
if (result != null)
{
de = new DirectoryEntry(result.Path, ad.adminUser, ad.adminPwd);
path = de.Path;
}
return path;
}
catch (Exception ex)
{
return "";
}
} /// <summary>
/// 根据ou 路径 取得ou下所有用户
/// </summary>
/// <param name="sAMAccountName">用户帐号名</param>
/// <returns>如果找到该用户,则返回用户的 对象;否则返回 null</returns>
public List<DirectoryEntry> GetListDirectory(string path,ADInfo ad)
{
List<DirectoryEntry> lis = new List<DirectoryEntry>(); DirectoryEntry de = GetDirectoryObject(path, ad);
DirectorySearcher deSearch = new DirectorySearcher(de); deSearch.Filter = "(&(objectCategory=person)(cn=*))";
deSearch.SearchScope = SearchScope.Subtree;
try
{
SearchResultCollection resultList = deSearch.FindAll();
if (resultList != null && resultList.Count>)
foreach (SearchResult item in resultList)
{
de = new DirectoryEntry(item.Path, ad.adminUser, ad.adminPwd);
lis.Add(de);
} return lis;
}
catch (Exception ex)
{
return null;
}
} /// <summary>
///
/// </summary>
/// <param name="path"></param>
/// <returns></returns>
public DirectoryEntry GetOuDirectory(string attribute,ADInfo ad)
{
DirectoryEntry ret = new DirectoryEntry();
DirectoryEntry de = GetDirectoryObject(ad);
DirectorySearcher deSearch = new DirectorySearcher(de); deSearch.Filter = "(&(objectCategory=organizationalUnit)(postalCode=" + attribute + "))";
deSearch.SearchScope = SearchScope.Subtree;
try
{
SearchResult resultList = deSearch.FindOne();
ret = new DirectoryEntry(resultList.Path, ad.adminUser, ad.adminPwd);
return ret;
}
catch (Exception ex)
{
return null;
}
} #region 判断域中是否存在组织单位
/// <summary>
/// 判断域中是否存在组织单位
/// </summary>
/// <param name="organizeName">组织单位名</param>
/// <returns></returns>
private bool ExitOU(string organizeName,ADInfo ad)
{
DirectoryEntry rootUser = null;
DirectoryEntry ouFind = null;
if (string.IsNullOrEmpty(organizeName))
{
return true;
}
else
{
//分解路径
string[] allOu = organizeName.Split(new char[] { '/' });
//获取直属部门
string OUName = allOu[].ToString();
try
{
string path = GetOrganizeNamePath(organizeName, ad);
rootUser = new DirectoryEntry(path, ad.adminUser, ad.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;
}
}
}
/// <summary>
/// 是否村在OU路径
/// </summary>
/// <param name="path"></param>
/// <returns></returns>
public bool IsExistOuPath(string path,ADInfo ad) {
DirectoryEntry rootUser = null;
DirectoryEntry ouFind = null;
rootUser = new DirectoryEntry(path, ad.adminUser, ad.adminPwd, AuthenticationTypes.Secure); if (rootUser != null)
{
return true;
}
return false;
}
#endregion #region 获取组织名称路径
/// <summary>
/// 获取组织名称路径
/// </summary>
/// <param name="organizeUnit">组织</param>
/// <returns></returns>
public string GetOrganizeNamePath(string organizeUnit,ADInfo ad, string userName = null)
{
StringBuilder sb = new StringBuilder();
sb.Append(ad.ldapIdentity);
return sb.Append(SplitOrganizeNameToDN(organizeUnit, ad,userName)).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, ADInfo ad, string userName = null)
{
StringBuilder sb = new StringBuilder(); if (userName != null)
{
sb.Append("CN=" + userName); }
if (organizeName != null && organizeName.Length > )
{
string[] allOu = organizeName.Split(new char[] { '/', '\\' });
for (int i = ; i <= allOu.Length - ; i++)
{
string ou = allOu[i];
if (sb.Length > )
{
sb.Append(",");
}
sb.Append("OU=").Append(ou);
}
}
//如果传入了组织名称,则添加,
if (sb.Length > )
{
sb.Append(",");
}
sb.Append(ad.suffixPath);
return sb.ToString(); }
#endregion #region GetDirectoryObject /// <summary>
/// 获得DirectoryEntry对象实例,以管理员登陆AD
/// </summary>
/// <returns></returns>
private DirectoryEntry GetDirectoryObject(ADInfo ad)
{
DirectoryEntry entry = new DirectoryEntry(ad.ldapIdentity+ad.suffixPath, ad.adminUser, ad.adminPwd, AuthenticationTypes.Secure);
return entry;
} /// <summary>
/// 根据指定用户名和密码获得相应DirectoryEntry实体
/// </summary>
/// <param name="userName"></param>
/// <param name="password"></param>
/// <returns></returns>
//private DirectoryEntry GetDirectoryObject(string userName, string password)
//{
// DirectoryEntry entry = new DirectoryEntry(_ldapIdentity,
// userName, password, AuthenticationTypes.None);
// return entry;
//} /// <summary>
/// i.e. /CN=Users,DC=creditsights, DC=cyberelves, DC=Com
/// </summary>
/// <param name="domainReference"></param>
/// <returns></returns>
private DirectoryEntry GetDirectoryObject(string domainReference,ADInfo ad)
{
DirectoryEntry entry = new DirectoryEntry(domainReference, ad.adminUser, ad.adminPwd,
AuthenticationTypes.Secure);
return entry;
} /// <summary>
/// 获得以UserName,Password创建的DirectoryEntry
/// </summary>
/// <param name="domainReference"></param>
/// <param name="userName"></param>
/// <param name="password"></param>
/// <returns></returns>
//private DirectoryEntry GetDirectoryObject(string domainReference,
// string userName, string password)
//{
// DirectoryEntry entry = new DirectoryEntry(_ldapIdentity + domainReference,
// userName, password, AuthenticationTypes.Secure);
// return entry;
//} #endregion /// <summary>
/// 判断帐户是否存在
/// </summary>
/// <param name="commonName">Account用户名</param>
/// <returns>是否存在</returns>
public bool IsAccExists(string sAMAccountName, ADInfo ad)
{
DirectoryEntry de = GetDirectoryObject(ad);
DirectorySearcher deSearch = new DirectorySearcher(de);
deSearch.Filter = "(&(&(objectCategory=person)(objectClass=user))(sAMAccountName=" +
sAMAccountName + "))"; // LDAP 查询串
SearchResultCollection results = deSearch.FindAll();
if (results.Count == )
return false;
else
return true;
} public bool IsAccExistsCN(string sAMAccountName, ADInfo ad)
{
DirectoryEntry de = GetDirectoryObject(ad);
DirectorySearcher deSearch = new DirectorySearcher(de);
deSearch.Filter = "(&(&(objectCategory=person)(objectClass=user))(CN=" +
sAMAccountName + "))"; // LDAP 查询串
SearchResultCollection results = deSearch.FindAll();
if (results.Count == )
return false;
else
return true;
}
} public class DomainUser
{
public string UserName { get; set; }
public string UserPrincipalName { get; set; }
public string UserId { get; set; }
public string PhysicalDeliveryOfficeName { get; set; }
public string Department { get; set; }
public string Telephone { get; set; }
public string Email { get; set; }
public string Description { get; set; }
public string UserPwd { get; set; }
} public class EmpInfo {
public string emloyeeID { get; set; }
public string sAMAccountName { get; set; }
public string userPrincipalName { get; set; }
public string employeeType { get; set; }
public string DepartmentName { get; set; }
public string Mail { get; set; }
public string DisplayName { get; set; }
public string Surname { get; set; }
public string GivenName { get; set; }
public string Department { get; set; }
public string Oupath { get; set; }
} public class ADInfo{ public string domain { get; set; }
public string domainIp { get; set; }
public string adminUser { get; set; }
public string adminPwd { get; set; }
public string ldapIdentity { get; set; }
public string suffixPath { get; set; }
public string adsur { get; set; }
public string houzhui { get; set; }
public string dbCon { get; set; }
} public class PingYinHelper
{
private static Encoding gb2312 = Encoding.GetEncoding("GB2312"); /// <summary>
/// 汉字转全拼
/// </summary>
/// <param name="strChinese"></param>
/// <returns></returns>
public static string ConvertToAllSpell(string strChinese)
{
try
{
if (strChinese.Length != )
{
StringBuilder fullSpell = new StringBuilder();
for (int i = ; i < strChinese.Length; i++)
{
var chr = strChinese[i];
fullSpell.Append(GetSpell(chr));
} return fullSpell.ToString().ToUpper();
}
}
catch (Exception e)
{
Console.WriteLine("全拼转化出错!" + e.Message);
} return string.Empty;
} /// <summary>
/// 汉字转首字母
/// </summary>
/// <param name="strChinese"></param>
/// <returns></returns>
public static string GetFirstSpell(string strChinese)
{
//NPinyin.Pinyin.GetInitials(strChinese) 有Bug 洺无法识别
//return NPinyin.Pinyin.GetInitials(strChinese); try
{
if (strChinese.Length != )
{
StringBuilder fullSpell = new StringBuilder();
for (int i = ; i < strChinese.Length; i++)
{
var chr = strChinese[i];
fullSpell.Append(GetSpell(chr)[]);
} return fullSpell.ToString().ToUpper();
}
}
catch (Exception e)
{
Console.WriteLine("首字母转化出错!" + e.Message);
} return string.Empty;
} private static string GetSpell(char chr)
{
var coverchr = NPinyin.Pinyin.GetPinyin(chr); bool isChineses = ChineseChar.IsValidChar(coverchr[]);
if (isChineses)
{
ChineseChar chineseChar = new ChineseChar(coverchr[]);
foreach (string value in chineseChar.Pinyins)
{
if (!string.IsNullOrEmpty(value))
{
return value.Remove(value.Length - , );
}
}
} return coverchr; }
}
}

通过Ldap实现人事系统组织人事和AD的同步的更多相关文章

  1. linux/windows系统oracle数据库简单冷备同步

    linux/windows系统oracle数据库简单冷备同步 我们有一个财务系统比较看重财务数据的安全性,同时我们拥有两套系统,一个生产环境(linux),一个应急备份环境(windows).备份环境 ...

  2. ftp客户端自动同步 Windows系统简单操作ftp客户端自动同步

    服务器管理工具它是一款功能强大的服务器集成管理器,包含win系统和linux系统的批量连接,vnc客户端,ftp客户端等等实用功能.我们可以使用这款软件的ftp客户端定时上传下载的功能来进实现ftp客 ...

  3. AJAX+jQuery+ASP实现实时验证身份证信息是否已存在---人事系统

    很多时候在网站上注册时,我们会发现,注册表单通常需要检查用户名和电子邮件地址的可用性:从而确保用户之间不拥有相同的用户名和电子邮件地址:一些网站喜欢在用户提交填写的用户信息时,做信息可用性的检查,而一 ...

  4. 被公司的垃圾XG人事系统吓尿了

    OA要尝试设置单点登录,拿现有的HR系统尝试,结果不知道HR系统的加密方式和验证地址,于是乎找HR厂商——厦门XG软件实施人员.结果那个技术人员支支吾吾不肯给我,搞得非常的烦. 真奇怪了,不开源的软件 ...

  5. OA系统开发人事模块关于请假跨月的处理

    前言:其实对于跨月的数据单独处理是不难的,但是对于后台显示页面,肯定不是单纯拼接一个where条件的,因此在我的项目也是如此,并不能够用普遍的方法来处理,此时就想尽量用简单的方法来处理跨月数据的准确性 ...

  6. 基于PySpark的网络服务异常检测系统 (四) Mysql与SparkSQL对接同步数据 kmeans算法计算预测异常

    基于Django Restframework和Spark的异常检测系统,数据库为MySQL.Redis, 消息队列为Celery,分析服务为Spark SQL和Spark Mllib,使用kmeans ...

  7. 使用Novell.Directory.Ldap.NETStandard在.NET Core中验证AD域账号

    Novell.Directory.Ldap.NETStandard是一个在.NET Core中,既支持Windows平台,又支持Linux平台,进行Windows AD域操作的Nuget包. 首先我们 ...

  8. linux系统时间与网络时间不同步

    在解决问题之前,我们首先来了解下面几个知识点: 1. date命令: #date 显示系统时间 2.hwclock命令   (即hardwareclock系统硬件时间) #hwclock 显示硬件时间 ...

  9. CentOS7系统时间和硬件时间不同步问题

    CentOS7系统中有两个时间:系统时间 和 硬件时间 我们常用命令 date 会输出系统时间,用 date 命令修改的也是系统时间 硬件时间是写入到 BIOS 中的时间,用 hwclock -r 命 ...

随机推荐

  1. Linux操作系统的压缩、解压缩工具介绍

    Linux操作系统的压缩.解压缩工具介绍 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.compress/uncompress命令常用参数 Linux compress命令: ...

  2. Samba应用案例

    一.配置文件详解 Samba配置文件非常简洁明了,所有的设置都在 /etc/samba/smb.conf 配置文件中进行,通过对该配置文件的修改,可以将Samba配置为一台匿名文件服务器.基于账户的文 ...

  3. Iptables不适用与socks协议吗?

    需求描述   现有一个台多公网IP服务器,用作于内网网关,通过NAT访问公网使用,要求不同的内网地址访问公网时使用不同的公网IP.可以简单理解为内网与公网IP进行一对一访问外网的映射. 服务器名称 I ...

  4. uniapp增加百度统计代码(h5)

    做了个微信公众号文章互相阅读的h5界面,http://mptask.wintp.top/(只能微信浏览器打开),其中用到了统计代码,记录如下. 1.新建 tj.html 界面 可放置在项目的根目录,文 ...

  5. CanvasRenderingContext2D.fillText(text, x, y [, maxWidth]);

    CanvasRenderingContext2D.fillText(text, x, y [, maxWidth]); [, maxWidth]的意思是,方括号代表可有可无,有fillText(tex ...

  6. Git挽回错误的push(commit)

    若你的(zhu)队友不小心把错误的代码提交到远程仓库,特别是包含了很多删除文件指令,不要尝试使用Git的API修改,或者删除Git仓库里的某次提交记录,风险十分大,正确的做法是备份你的本地源码,然后拉 ...

  7. 引入jquery时,页面一直加载

    注意jquery的引用位置最好放在<head>下面.

  8. Pandas | 01 数据结构

    Pandas的三种数据结构: 系列(Series) 数据帧(DataFrame) 面板(Panel) 这些数据结构,构建在Numpy数组之上,这意味着它们很快 维数和描述 考虑这些数据结构的最好方法是 ...

  9. hasura graphql-engine + plv8 集成

    hasura graphql-engine 是一款很不错的基于pg 的graphql 引擎,plv8 是pg 的一个扩展,我们可以使用js 编写 函数 ,触发器,而且对于es6 的语法也有比较完备的支 ...

  10. 图的遍历 | 1034 map处理输入数据,连通块判断

    这题写得比较痛苦.首先有点不在状态,其次题目比较难读懂. “Gang”成立的两个条件:①成员数大于两个  ②边权总和大于阈值K 首先,在录数据的时候通过map或者字符串哈希建立string到int的映 ...