Get-ADPasswordExpiry — raport wygasania haseł AD

🏢 Active Directory POWERSHELL

Lista kont z wygasłym lub wygasającym wkrótce hasłem — uwzględnia Fine-Grained Password Policy

Pobierz .ps1

Opis

Proaktywny monitoring wygasania haseł w Active Directory. Funkcje: - Obsługuje granularne polityki haseł (FGPP) przez msDS-UserPasswordExpiryTimeComputed - Rozróżnia konta z wygasłym hasłem vs wygasające wkrótce - Konfigurowalny próg ostrzeżenia (-DaysAhead, domyślnie 14 dni) - Eksport do CSV (-ExportCSV) - Pomija konta z PasswordNeverExpires i wyłączone Typowe użycie: cotygodniowy raport, powiadomienia dla użytkowników. Użycie: .\Get-ADPasswordExpiry.ps1 -DaysAhead 30 -ExportCSV C:\Temp\pwd.csv

🕒 2026-04-13 📦 Źródło: own
skrypt.ps1
#Requires -Modules ActiveDirectory
<#
.SYNOPSIS
    Raport wygasania haseł w AD — lista kont, którym hasło wygasa wkrótce lub już wygasło.

.DESCRIPTION
    Sprawdza datę wygaśnięcia hasła dla wszystkich aktywnych kont i wyświetla:
    - Konta z wygasłym hasłem
    - Konta, którym hasło wygasa w ciągu N dni
    Uwzględnia granularne polityki haseł (Fine-Grained Password Policy).

.PARAMETER DaysAhead
    Liczba dni do przodu (domyślnie 14) — pokaż konta, którym hasło wygasa w tym czasie.

.PARAMETER SearchBase
    DN jednostki organizacyjnej do przeszukania.

.PARAMETER ExportCSV
    Ścieżka do pliku CSV z wynikami.

.EXAMPLE
    .\Get-ADPasswordExpiry.ps1
    .\Get-ADPasswordExpiry.ps1 -DaysAhead 30 -ExportCSV C:\Temp\passwords.csv
#>

param(
    [int]$DaysAhead = 14,
    [string]$SearchBase = "",
    [string]$ExportCSV = ""
)

Import-Module ActiveDirectory -ErrorAction Stop

$defaultMaxAge = (Get-ADDefaultDomainPasswordPolicy).MaxPasswordAge
$now           = Get-Date
$cutoff        = $now.AddDays($DaysAhead)

$params = @{
    Filter     = { Enabled -eq $true -and PasswordNeverExpires -eq $false -and PasswordLastSet -ne $null }
    Properties = 'PasswordLastSet', 'PasswordNeverExpires', 'PasswordExpired',
                 'DisplayName', 'EmailAddress', 'Department', 'msDS-UserPasswordExpiryTimeComputed'
}
if ($SearchBase) { $params.SearchBase = $SearchBase }

$users = Get-ADUser @params

$results = foreach ($u in $users) {
    # msDS-UserPasswordExpiryTimeComputed uwzględnia FGPP
    $expiryRaw = $u.'msDS-UserPasswordExpiryTimeComputed'
    $expiry = if ($expiryRaw -and $expiryRaw -ne 9223372036854775807) {
        [datetime]::FromFileTime($expiryRaw)
    } else {
        $u.PasswordLastSet + $defaultMaxAge
    }

    $daysLeft = [math]::Round(($expiry - $now).TotalDays)

    if ($expiry -le $cutoff) {
        [PSCustomObject]@{
            SamAccountName = $u.SamAccountName
            DisplayName    = $u.DisplayName
            Department     = $u.Department
            Email          = $u.EmailAddress
            PasswordLastSet = $u.PasswordLastSet?.ToString("yyyy-MM-dd")
            ExpiryDate     = $expiry.ToString("yyyy-MM-dd")
            DaysLeft       = $daysLeft
            Status         = if ($daysLeft -lt 0) { "WYGASŁE" } elseif ($daysLeft -eq 0) { "DZIŚ" } else { "Za $daysLeft dni" }
        }
    }
} | Sort-Object DaysLeft

Write-Host "`n Hasła wygasające do: $($cutoff.ToString('yyyy-MM-dd'))  (próg: $DaysAhead dni)`n" -ForegroundColor Cyan

$expired = $results | Where-Object { $_.DaysLeft -lt 0 }
$expiring = $results | Where-Object { $_.DaysLeft -ge 0 }

if ($expired) {
    Write-Host " WYGASŁE HASŁA ($($expired.Count)):" -ForegroundColor Red
    $expired | Format-Table SamAccountName, DisplayName, Department, ExpiryDate, DaysLeft -AutoSize
}

if ($expiring) {
    Write-Host " WYGASAJĄ WKRÓTCE ($($expiring.Count)):" -ForegroundColor Yellow
    $expiring | Format-Table SamAccountName, DisplayName, Department, ExpiryDate, DaysLeft -AutoSize
}

if (-not $results) {
    Write-Host " Brak kont z wygasającymi hasłami w ciągu $DaysAhead dni." -ForegroundColor Green
}

if ($ExportCSV -and $results) {
    $results | Export-Csv -Path $ExportCSV -NoTypeInformation -Encoding UTF8
    Write-Host "`n Wyeksportowano do: $ExportCSV" -ForegroundColor Green
}