首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> 關於C語言

C# 批量建立 Active Directory 域帳號與 Exchange 郵箱自動化實戰

     編輯:關於C語言

業務背景與痛點

企業導入 Microsoft 技術棧構建 OA 系統時,通常採用主域控制模式,IT 部門需為每位員工建立 AD 域帳號。隨著企業規模擴大,人工逐一建立帳號不僅耗時,還易因重複錄入導致資料錯誤。HR 部門已錄入員工資料(姓名、工號、部門、主管、電話等),IT 再次錄入屬於典型的「重複勞動」。

解決方案架構

本文提供一套 C# 自動化程式,讀取 Access 資料庫(HR 提供標準格式),批量建立 AD 帳號並同步在 Exchange 中建立郵箱,實現「HR 填表、程式跑批」的無縫對接。

核心技術棧

  • System.DirectoryServices:操作 Active Directory (LDAP)
  • CDOEXM:Exchange 郵箱建立介面
  • ADODB:讀取 Access 資料庫

關鍵實現步驟

1. 定義常數與變數

string defaultNC = "DC=Test,DC=net";           // 預設網域
string domainName = "test.Net";
string password = @"PassWord";                  // 預設初始密碼
string homeMDB = "CN=Test,CN=控股公司,"        // Exchange 郵箱儲存位置
    + "CN=InformationStore,CN=MAIL,CN=Servers,"
    + "CN=First Administrative Group,CN=Administrative Groups,"
    + "CN=test,CN=Microsoft Exchange,CN=Services,"
    + "CN=Configuration,DC=Test,DC=net";

2. 讀取「模板帳號」屬性

先手動建立一個標準帳號作為模板,程式讀取其 memberOf、userParameters、manager、scriptPath、department、company 等屬性,作為新帳號的預設值。

DirectoryEntry deMb = new DirectoryEntry();
deMb.Path = "LDAP://CN=模板, OU=項目組,OU=部門,DC=Test,DC=net";
strMemberof = deMb.Properties["memberOf"][0].ToString();
strUserParm = deMb.Properties["userParameters"][0].ToString();
strManager = deMb.Properties["manager"][0].ToString();
// ... 其他屬性同理
deMb.Close();

3. 連接 Access 資料庫讀取人員名單

string connStr = @"Provider=Microsoft.Jet.OLEDB.4.0;Data Source=db1.mdb;...";
ADODB.Connection objConn = new ADODB.Connection();
objConn.Open(connStr, "", "", -1);

ADODB.Command objCmd = new ADODB.Command();
objCmd.CommandText = "select * from sheet1";
objCmd.ActiveConnection = objConn;
ADODB.Recordset objRs = objCmd.Execute();

4. 迴圈建立帳號與郵箱

DirectoryEntry container = new DirectoryEntry("LDAP://OU=項目組,OU=部門," + defaultNC);

while (!objRs.EOF)
{
    fullName = objRs.Fields[1].Value.ToString();   // 姓名
    alias = objRs.Fields[4].Value.ToString();      // 登入別名
    strGivenName = objRs.Fields[2].Value.ToString(); // 工號

    // 檢查重複帳號
    DirectorySearcher searcher = new DirectorySearcher(new DirectoryEntry("LDAP://DC=Test,DC=net"));
    searcher.Filter = "(&(objectClass=user)(sAMAccountName=" + alias + "))";
    if (searcher.FindAll().Count > 0)
    {
        fullName += strGivenName;  // 追加工號區分
        alias += strGivenName;
    }

    // 建立使用者物件
    DirectoryEntry user = container.Children.Add("cn=" + fullName, "user");
    user.Properties["sAMAccountName"].Add(alias);
    user.Properties["userPrincipalName"].Add(alias + "@Test.Net");
    user.Properties["givenName"].Add(strGivenName);
    user.Properties["sn"].Add(fullName);
    user.Properties["company"].Add(strCompany);
    user.Properties["department"].Add(strdepartment);
    // ... 套用模板屬性:scriptPath, manager, userParameters 等

    // 設定帳號到期時間(需注意 Ticks 換算與時區)
    DateTime dt = new DateTime(2004, 10, 31);
    long longAE = dt.Ticks - 504910656000000000; // 扣除 8 時區
    user.Properties["accountExpires"].Add(longAE.ToString());

    user.Properties["userPassword"].Add(password);
    user.CommitChanges();
    user.Invoke("SetPassword", new object[] { password });
    user.Properties["userAccountControl"].Value = 0x200; // 正常帳號
    user.CommitChanges();

    // 建立 Exchange 郵箱
    CDOEXM.IMailboxStore mailbox = (CDOEXM.IMailboxStore)user.NativeObject;
    mailbox.CreateMailbox(homeMDB);
    user.CommitChanges();

    objRs.MoveNext();
}

關鍵技術細節補充

帳號到期時間的 Ticks 計算

AD 的 accountExpires 為 64 位整數,單位為 100 奈秒間隔,基準時間為 1601/1/1 UTC。C# DateTime.Ticks 基準同為 1601/1/1 但為本地時間,需扣除時區差(8 小時 = 28,800 秒 = 288,000,000,000 Ticks)。文中常數 504910656000000000 似為特定版本計算結果,建議改用標準轉換:

long ToADLargeInteger(DateTime dt)
{
    // 轉 UTC 再取 Ticks
    return dt.ToUniversalTime().Ticks;
}

啟用帳號的 userAccountControl

0x200 (ADS_UF_NORMAL_ACCOUNT) 代表正常啟用帳號;若需停用請設 0x202 (ADS_UF_ACCOUNTDISABLE)。

部署與注意事項

  1. 執行帳號需具備 AD「建立使用者物件」與 Exchange「建立郵箱」權限
  2. Access 檔案 (db1.mdb) 需放置於程式執行目錄或指定完整路徑
  3. Exchange 版本需支援 CDOEXM (Exchange 2000/2003/2007);Exchange 2010+ 建議改用 PowerShell / EWS Managed API
  4. 大量建立時建議加入 Thread.Sleep(100) 避免 LDAP 連線過載
  5. 正式上線前請在測試環境驗證 OU 路徑、屬性名稱、郵箱資料庫 DN

總結

透過「模板帳號 + Access 資料來源 + LDAP 批次寫入 + CDOEXM 郵箱建立」,可將原本數小時的人工作業縮減至數分鐘,並消除人為錯誤。此模式可擴充至離職停用、屬性同步、跨域遷移等場景,是企業資訊化基礎建設的經典自動化範例。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved