AccountManagement for Windows Active Directory

  • 24417
  • 0
  • C#
  • 2022-10-25

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 命名空間


程式是運氣與直覺堆砌而成的奇蹟。
若不具備這兩者,不可能以這樣的工時實現這樣的規格。
修改規格是對奇蹟吐槽的褻瀆行為。
而追加修改則是相信奇蹟還會重現的魯莽行動。