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

C# 使用 CDO/ADSI 在 Active Directory 建立使用者與 Exchange 信箱

     編輯:關於C語言

前言

在企業環境中,常需透過程式自動化建立 AD 使用者帳號並啟用 Exchange 信箱。本文示範使用 CDO.PersonClass (Collaboration Data Objects) 與 CDOEXM.IMailboxStore 介面,透過 LDAP 路徑在 Active Directory 建立使用者、設定屬性、建立信箱與郵件地址的完整流程。

必要參考與命名空間

  • COM 參考:Microsoft CDO for Exchange Management (CDOEXM)
  • COM 參考:Active DS Type Library (ADSI)
  • 命名空間:using CDO; using CDOEXM; using ADODB;

完整程式碼

public int CreateUserWithMailbox(string loginName)
{
    // 管理員認證與網域參數 (實務應從設定檔讀取)
    const string adminUser = "admin";
    const string adminPwd = "P@ssw0rd";
    const string domainName = "mycompany.com";           // DNS 網域名
    const string dcPath = "DC=mycompany,DC=com";        // LDAP 基底 DN
    const string serverName = "EXCH01";                 // Exchange 伺服器名稱

    if (string.IsNullOrEmpty(loginName)) return -1;

    try
    {
        // 1. 建立 CDO Person 物件
        PersonClass user = new PersonClass();
        user.FirstName = loginName;
        user.LastName = "";

        // 2. 設定 AD 屬性
        user.Fields["userAccountControl"].Value = 66048; // PASSWD_NOTREQD | DONT_EXPIRE_PASSWD
        user.Fields["userPrincipalName"].Value = $"{loginName}@{domainName}";
        user.Fields.Update();

        // 3. 儲存至 AD (LDAP 路徑)
        string userLdap = $"LDAP://{domainName}/CN={loginName},CN=Users,{dcPath}";
        user.DataSource.SaveTo(userLdap, null, 
            ConnectModeEnum.adModeReadWrite,
            RecordCreateOptionsEnum.adCreateOverwrite,
            RecordOpenOptionsEnum.adOpenSource,
            adminUser, adminPwd);

        // 4. 建立 Exchange 信箱
        IMailboxStore mbox = (IMailboxStore)user.GetInterface("IMailboxStore");
        string mdbUrl = $@"LDAP://{domainName}/CN=Mailbox Store ({serverName})," +
            @"CN=First Storage Group,CN=InformationStore," +
            $@"CN={serverName},CN=Servers,CN=First Administrative Group," +
            @"CN=Administrative Groups,CN=First Organization," +
            @"CN=Microsoft Exchange,CN=Services,CN=Configuration," + dcPath;

        mbox.CreateMailbox(mdbUrl);

        // 5. 設定郵件屬性
        user.Email = $"SMTP:{loginName}@{domainName}";
        user.Fields["mailNickname"].Value = $"mailnickname{loginName}";
        user.Fields.Update();
        user.DataSource.Save();

        return 1; // 成功
    }
    catch (Exception ex)
    {
        // 實務應記錄 ex.ToString() 至日誌
        System.Diagnostics.Debug.WriteLine($"CreateUser failed: {ex}");
        return -1;
    }
}

關鍵參數說明

常見錯誤與排查

參數/屬性說明
userAccountControl = 660480x10200 = ADS_UF_DONT_EXPIRE_PASSWD (0x10000) | ADS_UF_PASSWD_NOTREQD (0x00200),密碼永不過期、不強制密碼
userPrincipalNameUPN 格式登入帳號,如 user@domain.com
SaveTo 參數adModeReadWrite 讀寫、adCreateOverwrite 覆寫既有、adOpenSource 開啟現有資料來源
Mailbox Store LDAP 路徑需對應實際 Exchange 組織拓撲:儲存群組 → 資訊存放區 → 伺服器 → 系統管理群組 → 組織 → 設定
mailNicknameExchange 別名,用於舊版用戶端與 GAL 顯示

現代替代方案建議

  • PowerShell + Exchange Management Shell:New-Mailbox -UserPrincipalName ...,原生支援、腳本化容易。
  • Microsoft Graph API / Azure AD Graph:適用於 Office 365 / Azure AD 環境,RESTful、跨平台。
  • System.DirectoryServices.AccountManagement:.NET 封裝 ADSI,建立使用者更簡潔 (UserPrincipal),但建立 Exchange 信箱仍需 CDOEXM 或 PowerShell 遠端。

安全性注意事項

  • 管理員密碼嚴禁硬編碼,應使用 Windows 認證 (Kerberos/NTLM) 或安全儲存 (DPAPI、Key Vault、Secret Manager)。
  • 遵循最小權限原則:服務帳號僅授予建立使用者/信箱所需的委派權限。
  • 記錄稽核日誌:建立時間、操作帳號、目標 OU、成功/失敗原因。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved
錯誤現象可能原因解決方向
COMException: 80072030 (物件已存在)CN 已存在於 Users 容器先查詢 AD 是否存在,或使用不同 CN/OU
CreateMailbox 失敗Mailbox Store 路徑錯誤、權限不足、Exchange 服務未啟動用 ADSI Edit 驗證 MDB 路徑、確認管理員有 Exchange 權限
郵件地址未生效收件者更新服務 (RUS) 尚未處理等待 RUS 排程,或手動觸發更新
存取被拒絕執行身分無 AD 寫入權限使用具備 Account Operators/Exchange Admin 權限的服務帳號執行