【PowerShell】Active Directoryユーザーのパスワード期限を一覧表示する方法

【PowerShell】ユーザーのパスワード期限を一覧表示する方法 PowerShell

Active Directory(AD)環境では、パスワードの有効期限が近いユーザーを事前に把握して通知することでアカウントロックアウトを防げます。PowerShellを使えばパスワード期限の一覧取得・フィルタリング・メール通知まで自動化できます。

この記事で学べること:ADモジュールのインストール確認・パスワード期限一覧取得・CSV出力・期限切れ前通知スクリプト
スポンサーリンク

前提条件

  • Remote Server Administration Tools(RSAT)のADモジュールがインストール済み
  • PowerShellを管理者として実行
  • 対象ドメインへの接続権限
# ADモジュールの確認
Get-Module -ListAvailable -Name ActiveDirectory

# インストールされていない場合(Windows 10/11)
Add-WindowsCapability -Online -Name "Rsat.ActiveDirectory.DS-LDS.Tools~~~~0.0.1.0"

基本:パスワード期限を一覧表示する

# 有効なユーザーのパスワード期限を一覧表示
Import-Module ActiveDirectory

Get-ADUser -Filter {Enabled -eq $true -and PasswordNeverExpires -eq $false} `
    -Properties DisplayName, PasswordLastSet, PasswordExpired, PasswordNeverExpires |`
    Select-Object -Property `
        DisplayName,
        SamAccountName,
        PasswordLastSet,
        PasswordExpired,
        @{Name="PasswordExpiryDate"; Expression={
            $maxAge = (Get-ADDefaultDomainPasswordPolicy).MaxPasswordAge
            if ($_.PasswordLastSet -ne $null) {
                $_.PasswordLastSet + $maxAge
            } else {
                "未設定"
            }
        }} |`
    Sort-Object PasswordExpiryDate |`
    Format-Table -AutoSize

CSVファイルに出力する

Import-Module ActiveDirectory

$maxAge = (Get-ADDefaultDomainPasswordPolicy).MaxPasswordAge

Get-ADUser -Filter {Enabled -eq $true -and PasswordNeverExpires -eq $false} `
    -Properties DisplayName, PasswordLastSet, Mail |`
    Select-Object -Property `
        @{N="氏名";        E={$_.DisplayName}},
        @{N="ユーザー名";  E={$_.SamAccountName}},
        @{N="メール";      E={$_.Mail}},
        @{N="最終変更日";  E={$_.PasswordLastSet}},
        @{N="有効期限";    E={
            if ($_.PasswordLastSet) { $_.PasswordLastSet + $maxAge }
            else { "未設定" }
        }},
        @{N="残日数";      E={
            if ($_.PasswordLastSet) {
                [int](($_.PasswordLastSet + $maxAge - (Get-Date)).TotalDays)
            } else { 999 }
        }} |`
    Sort-Object 残日数 |`
    Export-Csv -Path "C:\temp\password_expiry.csv" -NoTypeInformation -Encoding UTF8BOM

Write-Host "CSVファイルを出力しました: C:\temp\password_expiry.csv"
Export-Csv -Encoding UTF8BOM:BOM付きUTF-8で出力するとExcelで日本語が文字化けしません。PowerShell 5.xではUTF8BOMの代わりにUTF8と指定します(こちらはBOMなし)。

期限切れ前のユーザーのみ抽出する

Import-Module ActiveDirectory

$maxAge     = (Get-ADDefaultDomainPasswordPolicy).MaxPasswordAge
$warnDays   = 14  # 何日前から警告するか
$warnDate   = (Get-Date).AddDays($warnDays)

$expiringUsers = Get-ADUser -Filter {Enabled -eq $true -and PasswordNeverExpires -eq $false} `
    -Properties DisplayName, PasswordLastSet, Mail |`
    Where-Object {
        if ($_.PasswordLastSet) {
            $expiry = $_.PasswordLastSet + $maxAge
            $expiry -lt $warnDate -and $expiry -gt (Get-Date)
        }
    } |`
    Select-Object DisplayName, SamAccountName, Mail,
        @{N="有効期限"; E={ $_.PasswordLastSet + $maxAge }},
        @{N="残日数";   E={ [int](($_.PasswordLastSet + $maxAge - (Get-Date)).TotalDays) }}

$expiringUsers | Format-Table -AutoSize
Write-Host "合計 $($expiringUsers.Count) 名が期限切れ間近です"

期限切れ間近のユーザーにメール通知する

# 期限切れ間近ユーザーへのメール通知
foreach ($user in $expiringUsers) {
    if ($user.Mail) {
        $body = @"
$($user.DisplayName) 様

パスワードの有効期限が $($user.有効期限.ToString("yyyy/MM/dd")) に切れます。
(残り $($user.残日数) 日)

期限前にパスワードを変更してください。
変更方法: Ctrl + Alt + Delete → パスワードの変更
"@
        Send-MailMessage `
            -To $user.Mail `
            -From "admin@example.com" `
            -Subject "【重要】パスワード有効期限のお知らせ" `
            -Body $body `
            -Encoding UTF8 `
            -SmtpServer "smtp.example.com"
        Write-Host "送信完了: $($user.DisplayName) ($($user.Mail))"
    }
}
タスクスケジューラーで自動実行:このスクリプトをタスクスケジューラーに登録し、毎朝実行することで期限切れ前の自動通知システムが構築できます。

よくある質問(FAQ)

Q. パスワードが無期限(PasswordNeverExpires)のユーザーも表示するにはどうすればよいですか?
A. -Filter {Enabled -eq $true}のようにPasswordNeverExpiresの条件を外し、PasswordNeverExpiresプロパティも取得してSelect-Objectに追加します。無期限ユーザーは有効期限列に”無期限”と表示するよう条件分岐を追加できます。
Q. 特定のOU(組織単位)のユーザーだけを対象にするにはどうすればよいですか?
A. Get-ADUserに-SearchBase "OU=Sales,DC=example,DC=com"パラメータを追加します。これで指定したOU配下のユーザーのみが対象になります。
Q. PasswordLastSetがnullになるユーザーがいるのはなぜですか?
A. パスワードが一度も設定されていないアカウントや、Active Directory移行時にデータが引き継がれなかった場合にnullになります。nullのユーザーはパスワードポリシーが正しく機能しない可能性があるため、個別に確認・対処することを推奨します。

まとめ

  • Get-ADUserにPasswordLastSetプロパティを指定してパスワード最終変更日を取得
  • 最大パスワード期間(MaxPasswordAge)を加算して有効期限を計算
  • Export-CsvでCSV出力・Send-MailMessageでメール通知
  • タスクスケジューラーに登録することでパスワード期限切れ通知を自動化できる