在自動化運維腳本中,常需驗證 Windows 用戶名/密碼是否正確。PowerShell 可通過 .NET 的 System.DirectoryServices.AccountManagement.PrincipalContext 類實現,支援本機帳戶(SAM)與 Active Directory 域帳戶雙模式驗證,無需安裝額外模塊。
function Test-UserCredential {
[CmdletBinding()]
[OutputType([bool])]
param(
[Parameter(Mandatory=$true)]
[ValidateNotNullOrEmpty()]
[string] $Username,
[Parameter(Mandatory=$true)]
[ValidateNotNullOrEmpty()]
[string] $Password,
[Parameter()]
[switch] $Domain
)
begin {
# 載入 AD 管理程序集
$null = [System.Reflection.Assembly]::LoadWithPartialName('System.DirectoryServices.AccountManagement')
}
process {
try {
# 判斷當前機器角色
$computerSystem = Get-WmiObject -Class Win32_ComputerSystem
$isDomainJoined = $computerSystem.DomainRole -in 1, 3, 4, 5 # Workstation/Server in domain
if ($Domain) {
# 域模式:要求機器已加域
if (-not $isDomainJoined) {
throw "當前電腦未加入域,無法進行域憑證驗證。"
}
$context = New-Object System.DirectoryServices.AccountManagement.PrincipalContext `
-ArgumentList 'Domain', $computerSystem.Domain
} else {
# 本機模式
$context = New-Object System.DirectoryServices.AccountManagement.PrincipalContext `
-ArgumentList 'Machine', $env:COMPUTERNAME
}
# 執行驗證,返回布爾值
return $context.ValidateCredentials($Username, $Password)
}
catch {
Write-Error "憑證驗證失敗: $_"
throw
}
}
}
# 本機管理員驗證
Test-UserCredential -Username "Administrator" -Password "P@ssw0rd"
# 域用戶驗證(需加 -Domain 開關)
Test-UserCredential -Username "jdoe" -Password "Secret123" -Domain
# 在腳本中判斷結果
if (Test-UserCredential -Username $user -Password $pwd -Domain) {
Write-Host "驗證通過,繼續執行..."
} else {
Write-Warning "用戶名或密碼錯誤"
}
Machine 對應本機 SAM 資料庫,Domain 對應 AD 域控制器。LogonUser,不會鎖定帳戶(不計入錯誤嘗試次數),返回 $true/$false。Win32_ComputerSystem.DomainRole 值 1/3/4/5 表示已加域工作站/伺服器,0/2 表示獨立工作站/備用域控。function Get-ADUserDetail {
param([string]$Username, [switch]$Domain)
$ctx = if ($Domain) {
[System.DirectoryServices.AccountManagement.PrincipalContext]::new('Domain')
} else {
[System.DirectoryServices.AccountManagement.PrincipalContext]::new('Machine')
}
$user = [System.DirectoryServices.AccountManagement.UserPrincipal]::FindByIdentity($ctx, $Username)
if ($user) {
[pscustomobject]@{
DisplayName = $user.DisplayName
Email = $user.EmailAddress
Enabled = $user.Enabled
LastLogon = $user.LastLogon
Groups = $user.GetGroups().SamAccountName -join ';'
}
}
}
| 錯誤現象 | 原因 | 解決方案 |
|---|---|---|
| 「伺服器不可用」 | 域控制器不可達或 DNS 解析失敗 | 檢查網絡連通性、DNS 設置、防火牆規則 |
| 「拒絕訪問」 | 當前用戶無權查詢 AD | 使用有權限的服務帳戶運行腳本,或委派讀取權限 |
| 驗證總是失敗 | 密碼包含特殊字符未正確轉義 | 使用單引號包裹密碼字符串,或通過 Read-Host -AsSecureString 輸入 |