AD DSユーザーのパスワード期限は、Get-ADUserでユーザーごとの msDS-UserPasswordExpiryTimeComputed を取得して確認します。全員にドメイン既定のMaxPasswordAgeを足すだけでは、詳細なパスワードポリシー(PSO)があるユーザーの期限を誤る可能性があります。この記事は読み取りと対象の抽出に限定し、アカウントの無効化やメール送信は行いません。
実行前に確認すること
対象はオンプレミスのActive Directory Domain Servicesです。Microsoft Entra IDだけのユーザーやAD LDS向けの手順ではありません。RSATのActive Directory PowerShellモジュール、対象DCへの接続、属性を読む権限を確認します。必要以上のDomain Admins権限を使わず、最初はテストユーザー1名から確認してください。サーバー名、ユーザー名、OUはすべて例です。
1人のパスワード期限を確認する
次の関数は、通常の日付へ変換できない特殊値を先に分類します。期限をUTCで出力し、実行PCのタイムゾーンによる比較の混乱を避けます。PasswordLastSetは取得元の表示なので、列名と時刻の基準を区別してください。
Import-Module ActiveDirectory -ErrorAction Stop
$dc = 'dc01.example.com' # 対象ドメインのDCへ置換
$properties = @('PasswordLastSet','PasswordNeverExpires',
'msDS-UserPasswordExpiryTimeComputed','EmailAddress')
function Convert-PasswordExpiryReport {
param($User)
$raw = $User.'msDS-UserPasswordExpiryTimeComputed'
$expiry = $null
if ($null -eq $raw) {
$state = '未取得・要確認'
} elseif ([long]$raw -eq [long]::MaxValue) {
$state = '通常の期限日時なし'
} elseif ([long]$raw -eq 0) {
$state = 'pwdLastSet未設定または0・要確認'
} else {
try {
$expiry = [datetime]::FromFileTimeUtc([long]$raw)
$state = if ($expiry -le [datetime]::UtcNow) {'期限切れ'} else {'期限内'}
} catch {
$state = '日時変換不可・要確認'
}
}
[pscustomobject]@{
SamAccountName = $User.SamAccountName
Enabled = $User.Enabled
PasswordLastSet = $User.PasswordLastSet
PasswordNeverExpires = $User.PasswordNeverExpires
ExpiryUtc = $expiry
State = $state
EmailAddress = $User.EmailAddress
}
}
$user = Get-ADUser -Identity 'user01' -Server $dc -Properties $properties -ErrorAction Stop
Convert-PasswordExpiryReport $user | Format-List
結果の読み方
ExpiryUtcが実際の期限日時です。「通常の期限日時なし」はPasswordNeverExpiresだけでなく、スマートカード必須など別の条件でも返り得ます。0はpwdLastSetが未設定または0である状態として区別し、1601年などの期限として扱いません。未取得や変換不可を「期限なし」に読み替えず、DC、権限、属性、ユーザー状態を確認します。
パスワードの期限、アカウント自体の有効期限(AccountExpirationDate)、Enabled、ロックアウトは別の状態です。期限切れだからアカウントが自動的に無効になる、または無効化すべきだとは判断しません。
適用されるパスワードポリシーを確認する
Get-ADUserResultantPasswordPolicy -Identity 'user01' -Server $dc
Get-ADDefaultDomainPasswordPolicy -Server $dc
前者はユーザーに適用される詳細なパスワードポリシーを確認するためのコマンドです。該当するPSOがない場合はドメイン既定のポリシーも確認します。問い合わせ先DCを揃え、直前にパスワードやポリシーを変更した場合はレプリケーションの状況も調べてください。
指定OUの期限切れユーザーを一覧にする
先ほどの関数を定義した同じPowerShellで実行します。全ドメインへ無条件に広げず、まず対象OUを指定して結果を照合します。読み取りに失敗した場合は処理を止め、空の結果を「対象なし」と見なさないでください。
$ou = 'OU=Staff,DC=example,DC=com'
$report = @(Get-ADUser -Filter * -SearchBase $ou -Server $dc -Properties $properties -ErrorAction Stop |
ForEach-Object { Convert-PasswordExpiryReport $_ })
$report | Where-Object { $_.Enabled -and $_.State -eq '期限切れ' } |
Select-Object SamAccountName, ExpiryUtc, State
今後14日以内に期限が来る通知候補
既に期限切れの人を混ぜず、「現在より後、14日後まで」の範囲を抽出します。この例は表示だけで、メールを送りません。
$now = [datetime]::UtcNow
$limit = $now.AddDays(14)
$report | Where-Object {
$_.Enabled -and $null -ne $_.ExpiryUtc -and
$_.ExpiryUtc -gt $now -and $_.ExpiryUtc -le $limit
} | Select-Object SamAccountName, EmailAddress, ExpiryUtc
実際の通知は、宛先の正確性、サービス用アカウントの除外、重複送信防止、送信履歴、組織の承認を別途設計します。Send-MailMessageはMicrosoftが非推奨としており、新しい通知処理の前提にしません。承認されたメール基盤の認証・権限を確認し、パスワードや認証情報を本文やコードに埋め込まないでください。
期限切れユーザーを自動無効化しない
期限切れは、そのアカウントを停止する判断材料の一つにすぎません。サービス、バッチ、業務システムに使われるユーザーを一覧から一括無効化すると障害になる可能性があります。結果はまず管理者の確認用とし、所有者、用途、組織ポリシー、復旧手順を確認した別の変更作業で扱います。
運用上の注意
レポートにはアカウント名やメールアドレスが含まれます。公開サイトへ貼り付けず、アクセスを制限した場所で扱います。定期実行する場合も対象OU、問い合わせ先DC、実行日時、取得エラーを記録し、特殊値の件数が急に変わったら調べてください。本例は属性とコマンド仕様に基づくサンプルで、利用組織のAD環境での実行検証はしていません。
公式資料
Microsoft:期限計算属性の仕様/Get-ADUserResultantPasswordPolicy/Send-MailMessageの注意事項。
まとめ
ユーザーごとの計算済み期限を取得し、特殊値と通常の日付を分けて確認するのが基本です。最初は1人、次に限定OUへ広げ、期限切れ・期限前の候補を区別します。調査結果から自動でメール送信やアカウント停止へ進めないことが重要です。


コメント