用C#的Windows Service 来同步Active Directory
1 public partial class ADSyncService : ServiceBase 2 { 3 private System.Timers.Timer TimerSync; 4 /// <summary> 5 /// 文件写入流 6 /// </summary> 7 private StreamWriter LogFile; 8 9 private int Counter = 0; 10 11 private object SyncLocker = new object(); 12 /// <summary> 13 /// 日志路径 14 /// </summary> 15 private static readonly string CurrentPath = Application.StartupPath + " // "; 16 17 public ADSyncService() 18 { 19 AutoLog = true; 20 CanStop = true; 21 CanPauseAndContinue = true; 22 CanShutdown = true; 23 ServiceName = " ADSyncService "; // "Active Directory Synchronization Service"; 24 InitializeComponent(); 25 } 26 27 #region 服务函数 28 protected override void OnStart( string[] args) 29 { 30 LogFile = new StreamWriter(CurrentPath + " SyncLog " + System.DateTime.Today.ToString( " yyyMMdd ") + " .txt ", false, Encoding.Unicode); 31 LogFile.AutoFlush = true; 32 WriteLog( " ADSyncService Start... "); 33 this.TimerSync = new System.Timers.Timer(); 34 try 35 { 36 GetTimerInterval(); 37 this.TimerSync.Elapsed += new System.Timers.ElapsedEventHandler(tmrSync_Elapsed); 38 this.TimerSync.Enabled = true; 39 } 40 catch (System.Exception ex) 41 { 42 WriteLog( " Exception: " + ex.Message); 43 } 44 } 45 /// <summary> 46 /// 获取时间间隔 47 /// </summary> 48 private void GetTimerInterval() 49 { 50 BaseSysConfig baseSysConfig = new BaseSysConfig(); 51 double multiplier = 0; 52 double syncFrequency = ( double)StringUtils.GetDbDecimal(baseSysConfig.GetSysConfigValue( " SyncFrequency ")); 53 WriteLog( " syncFrequency: " + syncFrequency.ToString()); 54 int syncFrequencyUnit = StringUtils.GetDbInt(baseSysConfig.GetSysConfigValue( " SyncFrequencyUnit ")); 55 WriteLog( " syncFrequencyUnit: " + syncFrequencyUnit.ToString()); 56 switch (syncFrequencyUnit) 57 { 58 case 1: multiplier = 60000; break; // 分钟 59 case 2: multiplier = 3600000; break; // 小时 60 case 3: multiplier = 86400000; break; // 天 61 case 4: multiplier = 604800000; break; // 周 62 case 5: multiplier = 2592000000; break; // 月 30天 63 case 6: multiplier = 31104000000; break; // 年 64 default: multiplier = 3600000; break; 65 } 66 if (syncFrequency < 0.5) 67 { 68 throw new Exception( string.Format( " 设置的同步频率数值太小:{0} ", syncFrequency)); 69 } 70 double newFreq = ( double)syncFrequency * multiplier; 71 WriteLog( " newFreq: " + newFreq.ToString()); 72 this.TimerSync.Interval = newFreq; // 设置计时器事件间隔执行时间 3600000(小时级)* 3600000 73 } 74 75 protected override void OnStop() 76 { 77 WriteLog( " Service is stopped manually "); 78 LogFile.Close(); 79 this.TimerSync.Enabled = false; 80 } 81 82 protected override void OnShutdown() 83 { 84 WriteLog( " Service is stopping... "); 85 Stop(); 86 } 87 #endregion 88 /// <summary> 89 /// 同步用户 90 /// </summary> 91 /// <param name="obj"> 同步次数计算器 </param> 92 private void ProcessSync() 93 { 94 try 95 { 96 Loger.MyLog.Write(Loger.MyLog.LogLevel.Info, " Timer Running "); 97 WriteLog( " Timer Running "); 98 #region 执行同步 99 SyncClass syncClass = new SyncClass(); 100 BaseSysConfig baseSysConfig = new BaseSysConfig(); 101 SyncClass.SyncResult syncResult = new SyncClass.SyncResult(); ; 102 bool enableSync = StringUtils.SafeBool(baseSysConfig.GetSysConfigValue( " EnableADSyncService ").ToString(), false); 103 if (enableSync) 104 { 105 lock (SyncLocker) 106 { 107 syncResult = syncClass.SyncData(); 108 Counter++; 109 if (syncResult.TotalSyncNumber > 0) 110 { 111 // 调试 112 syncClass.SaveNewSyncTime(DateTime.Now); 113 } 114 if (syncResult.ErrorMessage != string.Empty) 115 { 116 WriteLog( " 同步时出现的错误信息: "+syncResult.ErrorMessage); 117 } 118 Loger.MyLog.Write(Loger.MyLog.LogLevel.Info, string.Format( " Sync Time: {0};Sync Times:{1};Sync AddNumber:{2};Sync UpdateNumber:{3};Sync TotalNumber:{4} ", 119 DateTime.Now, Counter, syncResult.AddCount, syncResult.UpdateCount, syncResult.TotalSyncNumber)); 120 WriteLog( string.Format( " Sync Result:Sync Time: {0};Sync Times:{1};Sync AddNumber:{2};Sync UpdateNumber:{3};Sync TotalNumber:{4};AdUserCount:{5} ", 121 DateTime.Now, Counter, syncResult.AddCount, syncResult.UpdateCount, syncResult.TotalSyncNumber,syncResult.AdUserCount)); 122 WriteLog( string.Format( " DebugString:{0} ", syncResult.DebugString)); 123 } 124 } 125 #endregion 126 } 127 catch (System.Exception ex) 128 { 129 WriteLog( " Exception: " + ex.Message+ex.Source+ex.Data); 130 Loger.MyLog.Write(Loger.MyLog.LogLevel.Error, string.Format( " Sync Exception {0}... ", ex.Message)); 131 } 132 } 133 134 private void tmrSync_Elapsed( object sender, System.Timers.ElapsedEventArgs e) 135 { 136 try 137 { 138 BaseSysConfig bsc = new BaseSysConfig(); 139 GetTimerInterval(); 140 ProcessSync(); 141 } 142 catch (System.Exception ex) 143 { 144 WriteLog( " Exception: "+ex.Message); 145 } 146 } 147 /// <summary> 148 /// 写日志 149 /// </summary> 150 /// <param name="szEvent"> 日志内容 </param> 151 public void WriteLog( string szEvent) 152 { 153 try 154 { 155 if (LogFile != null) 156 { 157 LogFile.WriteLine( " {0}: {1} ", DateTime.Now, szEvent); 158 } 159 } 160 catch (Exception) 161 { 162 } 163 } 164 }
View Code
1 ///2 /// 获取所有域用户 3 /// 4 ///5 public static DataTable GetADUsers() 6 { 7 DataTable dt = new DataTable(); 8 dt.TableName = "ADHelperTable"; 9 dt.Columns.Add("sAMAccountName");//帐号 10 dt.Columns.Add("Name");//姓名 11 dt.Columns.Add("mail"); //邮箱地址 12 dt.Columns.Add("department"); //部门 13 dt.Columns.Add("whenChanged"); //修改时间 14 dt.Columns.Add("whenCreated"); //创建时间 15 dt.Columns.Add("OU"); //用户组织 16 dt.Columns.Add("memberOf"); //属于 17 dt.Columns.Add("userAccountControl"); //用户账户控制 18 19 DirectoryEntry adRoot = GetDirectoryObject(); 20 DirectoryEntry ou; 21 if (!string.IsNullOrEmpty(ADOUName)) 22 { 23 ou = adRoot.Children.Find("OU=" + ADOUName); 24 } 25 else 26 { 27 ou = adRoot; 28 } 29 DirectorySearcher mySearcher = new DirectorySearcher(ou); 30 //mySearcher.Filter = "(&(objectClass=user))"; 31 //mySearcher.Filter = string.Format("(&(objectClass=user)(objectCategory=person)(CN={0}))", MemberOf); 32 if (!string.IsNullOrEmpty(MemberOf)) 33 { 34 mySearcher.Filter = "(&(objectClass=user)(objectCategory=person)(memberOf=" + MemberOf + "))"; 35 } 36 else 37 { 38 mySearcher.Filter = "(&(objectCategory=person)(objectClass=user))"; 39 } 40 mySearcher.SearchScope = SearchScope.Subtree; 41 mySearcher.Sort = new SortOption("name", SortDirection.Ascending); 42 mySearcher.PageSize = 500; 43 mySearcher.PropertiesToLoad.AddRange( 44 new string[] { "sAMAccountName", "Name", "mail", "department", "whenChanged", "whenCreated", "OU", "memberOf", "userAccountControl" }); 45 46 //&(objectCategory=person) 47 using (SearchResultCollection results = mySearcher.FindAll()) 48 { 49 foreach (System.DirectoryServices.SearchResult resEnt in results) 50 { 51 DataRow dr = dt.NewRow(); 52 dr["sAMAccountName"] = string.Empty; 53 dr["Name"] = string.Empty; 54 dr["mail"] = string.Empty; 55 dr["department"] = string.Empty; 56 dr["whenChanged"] = DateTime.MinValue; 57 dr["whenCreated"] = DateTime.MinValue; 58 dr["OU"] = string.Empty; 59 dr["memberOf"] = string.Empty; 60 dr["userAccountControl"] = 0; 61 62 DirectoryEntry user = resEnt.GetDirectoryEntry(); 63 64 if (user.Properties.Contains("userAccountControl")) 65 { 66 dr["userAccountControl"] = user.Properties["userAccountControl"][0].ToString(); 67 } 68 if (user.Properties.Contains("memberOf")) 69 { 70 int memberOfCount = user.Properties["memberOf"].Count; 71 if (memberOfCount != 0) 72 { 73 for (int i = 0; i < memberOfCount; i++) 74 { 75 dr["memberOf"] += user.Properties["memberOf"][i].ToString() + ";"; 76 } 77 } 78 } 79 if (user.Properties.Contains("sAMAccountName")) 80 { 81 dr["sAMAccountName"] = user.Properties["sAMAccountName"][0].ToString(); 82 } 83 if (user.Properties.Contains("Name")) 84 { 85 dr["Name"] = user.Properties["Name"][0].ToString(); 86 } 87 if (user.Properties.Contains("mail")) 88 { 89 dr["mail"] = user.Properties["mail"][0].ToString(); 90 } 91 if (user.Properties.Contains("department")) 92 { 93 dr["department"] = user.Properties["department"][0].ToString(); 94 } 95 if (user.Properties.Contains("whenChanged")) 96 { 97 dr["whenChanged"] = StringUtils.GetDateTime(user.Properties["whenChanged"][0]);//.ToString("yyyy-MM-dd HH:mm:ss") 98 } 99 if (user.Properties.Contains("whenCreated"))100 {101 dr["whenCreated"] = StringUtils.GetDateTime(user.Properties["whenCreated"][0]);102 }103 if (user.Parent.Name != string.Empty && user.Parent.Name.IndexOf('=') > -1)104 {105 //获取用户所在的组织单位106 dr["OU"] = user.Parent.Name.Split('=')[1];107 }108 109 dt.Rows.Add(dr);110 }111 }112 return dt;113 }
代码下载:
服务安装工具: