Private Function GetDomainDN(ByVal dnsDomainName As String) As String
' 例:corp.contoso.com → DC=corp,DC=contoso,DC=com
Dim parts() As String = dnsDomainName.Split("."c)
Dim sb As New System.Text.StringBuilder()
For i As Integer = 0 To parts.Length - 1
If i > 0 Then sb.Append(",")
sb.Append("DC=").Append(parts(i))
Next
Return sb.ToString()
End Function
Public Sub ChangeUserPassword( _
ByVal domainDnsName As String, _
ByVal userName As String, _
ByVal ouPath As String, _ ' 例:"OU=Users,OU=Taipei"
ByVal oldPassword As String, _
ByVal newPassword As String)
Try
' 建立 LDAP 路徑:LDAP://CN=Administrator,OU=Users,OU=Taipei,DC=corp,DC=contoso,DC=com
Dim ldapPath As String = String.Format( _
"LDAP://CN={0},{1},{2}", _
userName, ouPath, GetDomainDN(domainDnsName))
' 繫結使用者物件 (使用目前執行緒認證)
Dim user As ActiveDs.IADsUser = _
DirectCast(GetObject(ldapPath), ActiveDs.IADsUser)
' 變更密碼 (需知舊密碼)
user.ChangePassword(oldPassword, newPassword)
user.SetInfo() ' 送交變更
MessageBox.Show("密碼變更成功")
Catch ex As System.Runtime.InteropServices.COMException
' ADSI 錯誤代碼處理
Select Case ex.ErrorCode
Case &H8007052D ' ERROR_LOGON_FAILURE
Throw New Exception("舊密碼錯誤或帳號鎖定")
Case &H80070005 ' E_ACCESSDENIED
Throw New Exception("權限不足:需具備「重設密碼」或「變更密碼」權限")
Case &H8007202F ' 密碼不符合原則
Throw New Exception("新密碼不符合網域密碼原則 (長度、複雜度、歷程記錄)")
Case Else
Throw New Exception(String.Format("ADSI 錯誤 0x{0:X}: {1}", ex.ErrorCode, ex.Message))
End Select
Catch ex As Exception
Throw New Exception("發生未預期錯誤: " & ex.Message)
End Try
End Sub
Private Sub btnChangePwd_Click(sender As Object, e As EventArgs) Handles btnChangePwd.Click
Try
ChangeUserPassword( _
domainDnsName:="corp.contoso.com", _
userName:="jdoe", _
ouPath:="OU=Users,OU=Taipei", _
oldPassword:=txtOldPwd.Text, _
newPassword:=txtNewPwd.Text)
Catch ex As Exception
MessageBox.Show(ex.Message, "錯誤", MessageBoxButtons.OK, MessageBoxIcon.Error)
End Try
End Sub
| 操作 | 方法 | 權限需求 | 適用情境 |
|---|---|---|---|
| 變更密碼 | IADsUser.ChangePassword | 使用者自身、需知舊密碼 | 使用者自助變更 |
| 重設密碼 | IADsUser.SetPassword | 管理員 (Reset Password 權限) | 管理員解鎖/重設、服務帳號輪換 |
| HRESULT | 常數名稱 | 說明 |
|---|---|---|
| 0x8007052D | ERROR_LOGON_FAILURE | 舊密碼錯誤、帳號停用/鎖定/過期 |
| 0x80070005 | E_ACCESSDENIED | 權限不足 (ACL 未授予 Change/Reset Password) |
| 0x8007202F | - | 密碼違反網域原則 (歷程、長度、複雜度) |
| 0x8007203A | - | 密碼太短 |
| 0x8000500D | E_ADS_PROPERTY_NOT_SET | 屬性未設定 (如嘗試 SetPassword 於未啟用帳號) |
Imports System.DirectoryServices
Dim entry As New DirectoryEntry( _
"LDAP://CN=jdoe,OU=Users,DC=corp,DC=contoso,DC=com", _
Nothing, Nothing, AuthenticationTypes.Secure)
entry.Invoke("ChangePassword", oldPwd, newPwd)
entry.CommitChanges()
System.DirectoryServices 為 .NET 原生封裝,無需 COM Interop,效能與部署較佳,建議新專案優先採用。
Windows 2000 系統選項配置全攻略:用戶設定檔、記憶體與環境變數詳細設定
Windows Server 2003 Optimize Tool 一鍵優化神器完整評測
微軟 Windows Server 2008 內建「Drain Mode」負載平衡維護功能,挑戰 Citrix 傳統優勢
Windows 2000 秘密武器:Browstat.exe 瀏覽器服務狀態診斷工具詳解
Windows 2000 記事本新功能全解析:取代/跳轉、快速鍵強化、多重編碼支援與大檔案讀取突破
Windows Server 2003 以 IPsec 保護 SNMP 通訊安全設定教學