Sapere quando una password scade e quando è stata cambiata l’ultima volta è fondamentale per la gestione della sicurezza: consente di prevenire blocchi imprevisti degli utenti, verificare la conformità alle policy aziendali e produrre report per audit. La procedura varia a seconda dell’ambiente: dominio Active Directory on-premises, Microsoft Entra ID o account locali su un singolo PC Windows. In questo articolo vedremo i comandi PowerShell per un dominio Active Directory.
Sintassi dei comandi
In un dominio AD, la data di scadenza effettiva della password non è un attributo diretto dell’utente ma viene calcolata dal controller di dominio combinando la policy password applicata e la data dell’ultimo cambio. Il modo più affidabile per ottenerla è attraverso l’attributo calcolato msDS-UserPasswordExpiryTimeComputed.
Il valore è un timestamp in formato Windows FILETIME (numero di intervalli di 100 nanosecondi dal 1° gennaio 1601) e va convertito con [datetime]::FromFileTime(). Vediamo alcuni esempi.
Ottenere la scadenza della password per un singolo utente
Get-ADUser -Identity "NomeUtente" -Properties msDS-UserPasswordExpiryTimeComputed |
Select-Object Name,
@{Name="ScadenzaPassword"; Expression={
[datetime]::FromFileTime($_."msDS-UserPasswordExpiryTimeComputed")
}}
# Output atteso
Name ScadenzaPassword
---- ----------------
Mario Rossi 14/10/2026 21:51:38Ottenere la data dell’ultimo cambio della password per un singolo utente
Get-ADUser -Identity "NomeUtente" -Properties PasswordLastSet |
Select-Object Name, PasswordLastSet
# Output atteso
Name PasswordLastSet
---- ---------------
Mario Rossi 16/07/2026 21:51:38Report combinato (ultimo cambio + scadenza) per un singolo utente
$utente = Get-ADUser -Identity "NomeUtente" `
-Properties msDS-UserPasswordExpiryTimeComputed, PasswordLastSet
[PSCustomObject]@{
Nome = $utente.Name
Ultimocambio = $utente.PasswordLastSet
ScadenzaPassword = [datetime]::FromFileTime($utente."msDS-UserPasswordExpiryTimeComputed")
GiorniRimanenti = ([datetime]::FromFileTime($utente."msDS-UserPasswordExpiryTimeComputed") - (Get-Date)).Days
}
# Output atteso
Nome Ultimocambio ScadenzaPassword GiorniRimanenti
---- ------------ ---------------- ---------------
Mario Rossi 16/07/2026 21:51:38 14/10/2026 21:51:38 89Report combinato (ultimo cambio + scadenza) per tutti gli utenti attivi escludendo quelli con l’opzione “Password Never Expired”
Get-ADUser -Filter "Enabled -eq 'True' -and PasswordNeverExpires -eq 'False'" `
-Properties msDS-UserPasswordExpiryTimeComputed, PasswordLastSet |
Select-Object Name, UserPrincipalName,
PasswordLastSet,
@{Name="ScadenzaPassword"; Expression={
[datetime]::FromFileTime($_."msDS-UserPasswordExpiryTimeComputed")
}} |
Sort-Object ScadenzaPassword
# Output atteso
Name UserPrincipalName PasswordLastSet ScadenzaPassword
---- ----------------- --------------- ----------------
Mario Rossi mario.rossi@domain.local 16/07/2026 15:15:15 14/10/2026 15:15:15
Giovanni Verdi giovanni.verdi@domain.local 16/07/2026 16:51:38 14/10/2026 16:51:38
Laura Bianchi laura.bianchi@domain.local 16/07/2026 16:53:50 14/10/2026 16:53:50Report per identificare gli utenti la cui password scade entro un numero configurabile di giorni (nell’esempio 14)
$oggi = Get-Date
$limite = $oggi.AddDays(14)
Get-ADUser -Filter "Enabled -eq 'True' -and PasswordNeverExpires -eq 'False'" `
-Properties msDS-UserPasswordExpiryTimeComputed, PasswordLastSet |
Select-Object Name, UserPrincipalName,
PasswordLastSet,
@{Name="ScadenzaPassword"; Expression={
[datetime]::FromFileTime($_."msDS-UserPasswordExpiryTimeComputed")
}} |
Where-Object { $_.ScadenzaPassword -gt $oggi -and $_.ScadenzaPassword -le $limite } |
Sort-Object ScadenzaPassword
# Output atteso
Name UserPrincipalName PasswordLastSet ScadenzaPassword
---- ----------------- --------------- ----------------
Mario Rossi mario.rossi@domain.local 18/04/2026 08:31:46 17/07/2026 08:31:46
Giovanni Verdi giovanni.verdi@domain.local 18/04/2026 17:40:46 17/07/2026 17:40:46
Laura Bianchi laura.bianchi@domain.local 20/04/2026 07:45:57 19/07/2026 07:45:57Esempio di utilizzo
Scenario: produrre un report completo di tutti gli utenti attivi del dominio con la data dell’ultimo cambio password e quella di scadenza, filtrando chi scade entro i prossimi 30 giorni, ed esportarlo in un file CSV
$oggi = Get-Date
$preavviso = $oggi.AddDays(30)
$outputCsv = "C:\Report\scadenza_password_$(Get-Date -Format 'yyyyMMdd').csv"
Get-ADUser -Filter "Enabled -eq 'True' -and PasswordNeverExpires -eq 'False'" `
-Properties msDS-UserPasswordExpiryTimeComputed, PasswordLastSet |
Select-Object Name, UserPrincipalName,
PasswordLastSet,
@{Name="ScadenzaPassword"; Expression={
[datetime]::FromFileTime($_."msDS-UserPasswordExpiryTimeComputed")
}} |
Where-Object { $_.ScadenzaPassword -gt $oggi -and $_.ScadenzaPassword -le $preavviso } |
Sort-Object ScadenzaPassword |
Export-Csv -Path $outputCsv -NoTypeInformation -Encoding UTF8
Write-Host "Report salvato in: $outputCsv"
# Output atteso nel file csv
"Name","UserPrincipalName","PasswordLastSet","ScadenzaPassword"
"Mario Rossi","mario.rossi@dominio.local","07/01/2026 09:14:22","07/31/2026 09:14:22"
"Laura Bianchi","laura.bianchi@dominio.local","07/05/2026 11:03:45","08/04/2026 11:03:45"
"Giovanni Verdi","giovanni.verdi@dominio.local","07/10/2026 08:55:10","08/09/2026 08:55:10"L’elenco degli articoli di questa serie può essere consultato qui