#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 }