AccountManagement for Windows Active Directory
一般來說,要來進行網域帳號的管理,最基本的方式就是透過 MMC 的 Snap-in AD 管理模組來處理。但並不是所有的電腦都有這一個 Snap-in 並且也並沒有足夠的權限可以使用,而且透過 MMC 來管理時權限過大,並不適合開放給非管理人員來使用。
在 NET Framework 3.5 的組件中, 提供了 AccountManagement 這個命名空間,可以對 Active Directory 來進行存取與管理。因此可以透過 AccountManagement 來手工打造一個簡易的 AD 帳戶管理工具。
AccountManagement 簡介
程式使用了 AccountManagement 所提供的以下類別:
類別名稱 | 說明 |
UserPrincipal | 封裝本身為使用者帳戶的主體。 |
GroupPrincipal | 封裝群組帳戶。群組帳戶可以是主體物件的任意集合,或針對管理目的建立的帳戶。 |
PrincipalContext | 封裝用以執行所有作業的伺服器或網域、這些作業的基底容器,以及作業執行時使用的認證。 |
UserPrincipal 類別
提供的方法
方法名稱 | 說明 |
ChangePassword | 將帳戶密碼從舊密碼變更為新密碼。 |
CheckDisposedOrDeleted | 判斷是否已在這個類別上呼叫 Dispose 或 Delete 方法。 |
Delete | 從存放區刪除主體物件。 |
ExpirePasswordNow | 使這個帳戶的密碼到期。這會強制使用者在下一次登入時變更密碼。 |
FindByIdentity | 傳回符合指定的識別值之使用者主體物件。 |
GetAuthorizationGroups | 傳回主體物件的集合,其中包含這個使用者所屬的所有授權群組。這個函式只會傳回安全性群組,不會傳回通訊群組。 |
GetGroups | 傳回群組物件的集合,指定目前的主體是哪些群組的成員。 |
IsAccountLockedOut | 傳回這個指定帳戶目前是否遭鎖定。 |
IsMemberOf | 傳回這個指定帳戶是否為指定群組的成員。 |
RefreshExpiredPassword | 重新整理到期的密碼。 |
Save | 將在主體物件上所做的變更儲存至存放區。 |
SetPassword | 將帳戶密碼設定為指定的值。 |
UnlockAccount | 如果帳戶目前遭鎖定,則解除鎖定。 |
提供的屬性
屬性名稱 | 說明 | 存取 |
AccountExpirationDate | 指定帳戶到期的日期和時間。 | Read / Write |
BadLogonCount | 嘗試用不正確的認證登入這個帳戶的次數。 | Read |
Description | 這個帳戶的描述。 | Read / Write |
DisplayName | 這個帳戶的顯示名稱。 | Read / Write |
EmailAddress | 這個帳戶的電子郵件地址。 | Read / Write |
EmployeeId | 這個帳戶的員工 ID。 | Read / Write |
Enabled | 指定是否已針對此帳戶啟用驗證。 | Read / Write |
GivenName | 這個帳戶的的名字。 | Read / Write |
HomeDirectory | 這個帳戶的主目錄。 | Read / Write |
HomeDrive | 這個帳戶的主磁碟機。 | Read / Write |
LastBadPasswordAttempt | 上次嘗試用錯誤密碼登入這個帳戶的日期和時間。 | Read |
LastLogon | 上次登入這個帳戶的日期和時間。 | Read |
LastPasswordSet | 上次為這個帳戶設定密碼的日期和時間。 | Read |
MiddleName | 這個帳戶的中間名。 | Read / Write |
Name | 這個帳戶的名稱。 | Read / Write |
PasswordNeverExpires | 此帳戶的密碼是否會到期。 | Read / Write |
PasswordNotRequired | 此帳戶是否需要密碼。 | Read / Write |
SamAccountName | 這個主體的 SAM 帳戶名稱。 | Read / Write |
ScriptPath | 這個帳戶的指令碼路徑。 | Read / Write |
Sid | 安全識別項 (SID)。 | Read |
Surname | 使用者主體的姓氏。 | Read / Write |
UserCannotChangePassword | 使用者是否可以變更此帳戶的密碼。 | Read / Write |
GroupPrincipal 類別
提供的屬性
屬性名稱 | 說明 | 存取 |
Description | 這個群組的描述。 | Read / Write |
DisplayName | 這個群組的顯示名稱。 | Read / Write |
Members | 群組成員之物件的集合。 | Read |
Name | 這個群組的名稱。 | Read / Write |
Sid | 安全識別項 (SID)。 | Read |
使用方式
透過 new PrincipalContext( ContextType_內容型別, String_名稱, String_連線帳戶, String_連線密碼 ) 來產生執行個體,其中連線帳戶必需要有權限修改 AD 上的帳戶資料。如果帳戶與密碼代入 Null 值,則會使用目前執行人員的帳戶資訊。
範例:
DomainPrincipal = new PrincipalContext(ContextType.Domain, "abc.com.tw", null, null);
or
DomainPrincipal = new PrincipalContext(ContextType.Domain, "abc.com.tw", "administrator", "password");
接下來要查詢使用者帳戶是否存在於 AD 之中,可以透過 UserPrincipal.FindByIdentity 方法來進行確認。
範例:
UserPrincipal objUser = UserPrincipal.FindByIdentity("abc.com.tw", "YourUserName");
當使用者存在時,就可以利用 UserPrincipal 類別中的方法與屬性來修改或管理該帳戶的資料。
假設程式要提供的功能有修改 E-Mail 位址、帳戶描述、帳戶名稱、帳戶對應的員工ID,解鎖帳戶,查看帳戶到期日、認證失敗次數、帳戶狀態、最後登入的日期與時間與所屬的群組。
修改部份的程式碼範例:
objUser.EmailAddress = "新的 Mail 位址";
objUser.Description = "新的描述";
objUser.Surname = "使用者的姓氏";
objUser.GivenName = "使用者的名字";
objUser.MiddleName = "使用者的中間名";
objUser.DisplayName = "使用者的顯示名稱";
objUser.Name = "帳戶的名稱";
objUser.EmployeeId = "員工的 ID";
做完所有的異動之後,記得要執行 objUser.Save() 將資料寫回 AD。
查閱資料的程式碼範例:
return objUser.BadLogonCount.ToString(); // 驗證失敗的次數
return objUser.Enabled == true ? "啟用" : "停用"; // 帳戶的狀態
return objUser.LastLogon == null ? "" : objUser.LastLogon.ToString(); // 帳戶最後登入的日期與時間
列出使用者所屬的群組
foreach (GroupPrincipal tmpPrincipal in objUser.GetGroups())
{
UserGroups += tmpPrincipal.Name + Environment.NewLine;
}
return UserGroups; // 使用者所屬的群組名稱
參考資料:MSDN System.DirectoryServices.AccountManagement 命名空間
程式是運氣與直覺堆砌而成的奇蹟。
若不具備這兩者,不可能以這樣的工時實現這樣的規格。
修改規格是對奇蹟吐槽的褻瀆行為。
而追加修改則是相信奇蹟還會重現的魯莽行動。