AD 帳號問題快篩工具
13 |
使用 Windows 整合驗驗的網站有時會接到使用者反映他們無法用 AD 帳號登入,常見原因有記錯密碼、帳號被鎖、密碼到期... 等等,另外也曾遇過一些罕見案例是與 Domain Controller 間網路不通、電腦時鐘不對。 處理 AD 帳號無法登入 SOP 的第一步應先排除常見的帳號被鎖、密碼過期等狀況再花時間調查,就像除濕機、微波爐、電視機的使用手冊最後都有張常見故障排除表,叫你先檢查電源線有沒有插、開關有沒開一樣,避免大家在低級錯誤上虛耗時間。
查詢 AD 帳號資訊多要靠網管人員操作 UI 找帳號看狀態,我花了點時間寫了以下 PowerShell 讓 SOP 最佳化,不需要開管理介面滑鼠,下指令敲帳號兩秒便知結果,就叫它「AD 帳號問題快篩」吧!
param (
[Parameter(Mandatory=$True)]
[string] $userId
)
$dc = "company-domain.com"
Write-Host "*** AD 帳號問題快篩 Ver 1.0***" -ForegroundColor Yellow
$ErrorActionPreference = "STOP"
$match = [System.Text.RegularExpressions.Regex]::Match($userId, "^(?<d>.+)\\(?<u>.+)`$")
if (!$match.Success) {
Write-Host "請輸入 DomainName\UserId 帳號格式"
Exit
}
$domain = $match.Groups["d"].Value
$userId = $match.Groups["u"].Value
try
{
[string]$svr = (Get-ADDomainController -Discover -Domain "$domain.$dc").HostName
$user = Get-ADUser $userId -Properties LockedOut,LastLogonDate,PasswordLastSet,PasswordNeverExpires,msDS-UserPasswordExpiryTimeComputed -Server $svr
}
catch
{
Write-Host "找不到使用者 - $userId"
Exit
}
function Print([string]$label, [string]$value, $pass = $null) {
Write-Host "$($label): " -ForegroundColor Cyan -NoNewline
$color = [ConsoleColor]::White
if ($null -ne $pass) {
if ($pass -eq $true) { $color = [System.ConsoleColor]::Green }
else { $color = [ConsoleColor]::Red }
}
Write-Host $value -ForegroundColor $color
}
function ToYN([bool]$bool) {
if ($bool) {
return "是"
}
return "否"
}
Print "登入帳號" $user.SamAccountName
Print "帳號名稱" "$($user.Name) / $($user.GivenName)"
Print "上次登入" $user.LastLogonDate.ToString("yyyy-MM-dd HH:mm:ss")
Print "是否啟用" (ToYN $user.Enabled) -pass ($user.Enabled)
Print "是否鎖定" (ToYN $user.LockedOut) -pass (!$user.LockedOut)
[DateTime]$lastPwdSet = $user.PasswordLastSet
Print "上次密碼修改" $lastPwdSet.ToString("yyyy-MM-dd HH:mm:ss")
if (!$user.PasswordNeverExpires)
{
[DateTime]$nextChgDate = [DateTime]::FromFileTime($user."msDS-UserPasswordExpiryTimeComputed")
[timespan]$timeLeft = $nextChgDate - [DateTime]::Now
Print "密碼到期日" $nextChgDate.ToString("yyyy-MM-dd HH:mm:ss") -pass ($timeLeft.TotalSeconds -gt 0)
Write-Host "密碼到期提示: " -NoNewline -ForegroundColor Cyan
if ($timeLeft.TotalSeconds -lt 0)
{
Write-Host "密碼己於 $($nextChgDate.ToString("yyyy-MM-dd HH:mm:ss")) 到期]" -ForegroundColor Red
}
else {
$color = [ConsoleColor]::Yellow
[int]$daysLeft = $timeLeft.TotalDays
if ($daysLeft -le 7) { $color = [ConsoleColor]::Magenta }
Write-Host "密碼還有 $($daysLeft) 天到期" -ForegroundColor $color
}
}
else {
Write-Host "** 密碼永久有效 **" -ForegroundColor Magenta
}
執行結果如下,輸入「網域名稱\AD帳號」即會顯示帳號是否啟用、是否被鎖定、上次登入時間、上次密碼修改時間、密碼到期時間等,方便先排除 AD 常見問題再進一步追查,有需要的朋友請自取。
A PowerShell script example to check AD account status (enabled, lockedOut, password expired) quickly.
Comments
# by Eric
老大 請問這個有辦法同時也取得最近或是最後一次登入的電腦名稱嗎
# by Jeffrey
to Eric, 我只有看過抓每台電腦最後登入者,跟你想做的有點落差 https://social.technet.microsoft.com/Forums/en-US/859384b1-6ec0-449c-bb2e-ad1f22e8e912/get-last-logon-timecomputer-and-username-together-with-powershell?forum=winserverpowershell
# by Jason
請問 我在$dc = "company-domain.com",這段設定了網域DomainName,在實際執行輸入尋找網域名稱\AD帳號,會找不到使用者?,是沒有連動到網域嗎 謝謝
# by Jeffrey
to Jason, $dc 之後會用於 Get-ADDomainController -Discover -Domain "$domain.$dc",我建議先把 "$domain.$dc" 換成你們公司的網域名稱手動測試,成功後再對映出 $domain 與 $dc 的值。
# by 艾里克斯
也可用 net user /domain [Account]
# by metavige
以我們公司為例,我們公司的 $domain 與 $dc 的最前面一段是重複的 舉例,像是我們公司可能是 "abc.com.corp", domain 是 "abc" 我把 Get-ADDomainController -Discover -Domain "$domain.$dc" 改成 Get-ADDomainController -Discover -Domain "$dc" 就可以用了
# by Neo Chen
感謝您的程式,我修改了一下換成用Email來查詢。 您的這一段程式真的給了我很好的靈感!
# by Alex
To Jason 可能是沒有此 Feature, 試試輸入以下指令: Import-Module ServerManager Add-WindowsFeature RSAT-AD-PowerShell Import-Module ActiveDirectory
# by Arthur
感謝您的分享
# by wayneT
謝謝你的分享,很實用的好工具。
# by Paul
實用 感謝分享
# by leosedward
請問這個可以改寫為解鎖帳號的網頁?
# by Jeffrey
to leosedward,.NET 有 API 可以解鎖 https://learn.microsoft.com/en-us/dotnet/api/system.directoryservices.accountmanagement.authenticableprincipal.unlockaccount?view=dotnet-plat-ext-7.0 但解鎖需要用較高權限的帳號執行,要審慎設計以免變成資安漏洞。