項目需求:
同步人事系統的組織架構-對應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 = 0; //重復變量 private string sAMAccountName = ""; protected int AdRepeatNum = ObjConvert.ObjInt(ConfigurationManager.AppSettings["AdRepeatNum"]) == 0 ? 8 : 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 > 0) { 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"]) == "1") { string path = "", orgName = "", relateId = ObjConvert.ObjString(item["RelateID"]); DataTable orgDatatable = asy.GetOrgById(conn, relateId); string parentOrgId = ""; string name = ""; if (orgDatatable != null && orgDatatable.Rows.Count > 0) { name = ObjConvert.ObjString(orgDatatable.Rows[0]["organizationalname"]); parentOrgId = ObjConvert.ObjString(orgDatatable.Rows[0]["ParentOrganizationalID"]); } else { DataTable hisTable = asy.GetHistoryOrg(conn, relateId); if (hisTable != null && hisTable.Rows.Count > 0) { name = ObjConvert.ObjString(hisTable.Rows[0]["organizationalname"]); parentOrgId = ObjConvert.ObjString(hisTable.Rows[0]["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 > 0) { string CNName = ObjConvert.ObjString(empTable.Rows[0]["CNName"]); string piyin = ObjConvert.ObjString(empTable.Rows[0]["Pinyin"]); if (string.IsNullOrEmpty(piyin)) { piyin = ObjConvert.ObjStringToLower(PingYinHelper.ConvertToAllSpell(CNName)); } string ADName = ObjConvert.ObjString(empTable.Rows[0]["CN_ADName"]); empDetail.emloyeeID = ObjConvert.ObjString(empTable.Rows[0]["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[0]["empTypeText"]); empDetail.DepartmentName = ObjConvert.ObjString(empTable.Rows[0]["OrganizationalName"]); empDetail.Mail = ObjConvert.ObjString(empTable.Rows[0]["Email"]); empDetail.DisplayName = CNName; if (CNName.Length > 1) { empDetail.Surname = CNName.Substring(0, 1);//姓 empDetail.GivenName = CNName.Substring(1, CNName.Length - 1);//名 } else { empDetail.Surname = CNName; } empDetail.Department = ObjConvert.ObjString(empTable.Rows[0]["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 = 0; 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[0]["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 > 0) { foreach (DirectoryEntry item in list) { item.Properties["department"][0] = 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 > 0) { DirectoryEntry t = new DirectoryEntry(GetOuDirectory(newUnit, ad).Path, ad.adminUser, ad.adminPwd); for (int i = 0; i < deleteArr.Length; i++) { List<DirectoryEntry> list = GetListDirectory(GetOuDirectory(deleteArr[i],ad).Path,ad); if (list != null && list.Count > 0) { //if (mergeEmpTable != null && mergeEmpTable.Rows.Count > 0) //{ foreach (DirectoryEntry item in list) { string saName = ObjConvert.ObjString(item.Properties["sAMAccountName"][0]); //DataRow[] dtrows= mergeEmpTable.Select("CN_ADName='" + saName + "'"); //if (dtrows != null && dtrows.Count() > 0) { //服務邏輯是先同步部門操作,合並的時候 //可能發生 已經從這個部門調轉出去了,但是服務先合並到別的部門了,所有沒法后續的人員調崗操作了 //同時更改部門用戶名字 item.Properties["department"][0] = 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 + "0" + i.ToString(); user.userPrincipalName = sAMAccountName + "0" + 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 + "0" + 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"][0] = 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"][0] = 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"][0] = 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"][0] = user.DisplayName; // userEntry.Properties["name"][0] = user.DisplayName; userEntry.Properties["employeeType"][0] = user.employeeType; userEntry.Properties["Sn"][0] = user.Surname;//姓 userEntry.Properties["GivenName"][0] = user.GivenName;//名 if (!string.IsNullOrEmpty(user.Mail)) { userEntry.Properties["Mail"][0] = 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>0) 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[0].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 > 0) { string[] allOu = organizeName.Split(new char[] { '/', '\\' }); for (int i = 0; i <= allOu.Length - 1; i++) { string ou = allOu[i]; if (sb.Length > 0) { sb.Append(","); } sb.Append("OU=").Append(ou); } } //如果傳入了組織名稱,則添加, if (sb.Length > 0) { 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 == 0) 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 == 0) 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 != 0) { StringBuilder fullSpell = new StringBuilder(); for (int i = 0; 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 != 0) { StringBuilder fullSpell = new StringBuilder(); for (int i = 0; i < strChinese.Length; i++) { var chr = strChinese[i]; fullSpell.Append(GetSpell(chr)[0]); } 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[0]); if (isChineses) { ChineseChar chineseChar = new ChineseChar(coverchr[0]); foreach (string value in chineseChar.Pinyins) { if (!string.IsNullOrEmpty(value)) { return value.Remove(value.Length - 1, 1); } } } return coverchr; } } }