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

PowerShell 用戶憑證驗證函數:支援域/本機雙模式

     編輯:Java 相關知識

場景與原理

在自動化運維腳本中,常需驗證 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 "用戶名或密碼錯誤"
}

關鍵點解析

  • PrincipalContext 類型:Machine 對應本機 SAM 資料庫,Domain 對應 AD 域控制器。
  • ValidateCredentials 方法:內部調用 Win32 API LogonUser,不會鎖定帳戶(不計入錯誤嘗試次數),返回 $true/$false。
  • 域角色檢測:Win32_ComputerSystem.DomainRole 值 1/3/4/5 表示已加域工作站/伺服器,0/2 表示獨立工作站/備用域控。
  • 權限要求:執行腳本的用戶需具備查詢 AD 的權限(通常域用戶默認具備);本機模式需本機管理員權限才能驗證其他本地用戶。

進階擴展:獲取用戶詳細屬性

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 輸入
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved