Hai impostato Maximum password age a 365 giorni nella Default Domain Policy, hai fatto cambiare la password a tutti, ma dopo circa 40 giorni gli utenti vedono di nuovo l’avviso di scadenza. Il comportamento è tipico quando una Fine‑Grained Password Policy (FGPP) sovrascrive la policy di default del dominio.
Panoramica del problema
Dopo aver configurato la durata massima della password a 365 giorni nell’oggetto Default Domain Policy, gli utenti hanno iniziato a ricevere notifiche di scadenza di nuovo a distanza di ~40 giorni. Le verifiche comuni non mostrano anomalie: il GPO risulta applicato (gpresult /R
), l’attributo pwdLastSet
segna l’ultimo cambio a metà marzo mentre la scadenza annunciata cade a fine aprile (~40 giorni), non esistono altri GPO che alterino la password policy e nel Registro era presente un MaximumPasswordAge del servizio Netlogon impostato a 30 giorni poi corretto a 365. Inoltre c’è un solo Domain Controller, quindi non si tratta di replica incoerente.
Perché il GPO non basta da solo
La sezione Account Policies > Password Policy del GPO collegato alla radice del dominio determina la Default Domain Password Policy. Tuttavia:
- Il GPO non applica direttamente i valori a ciascun utente: definisce la policy predefinita del dominio, che vale quando nessuna policy più specifica è in gioco.
- Da Windows Server 2008 in poi esistono le Fine‑Grained Password Policies (FGPP): oggetti di tipo Password Settings Object (PSO) che possono essere applicati a singoli utenti o gruppi, prevalendo sulla policy di default. Se una FGPP definisce un
MaxPasswordAge
intorno a 40–42 giorni, quella durata vincerà sul valore 365 giorni configurato nel GPO. - GPResult non è una prova dell’effettiva policy password: mostra i GPO applicati, ma l’effettiva password policy per un utente è data da Default Domain Password Policy oppure da una FGPP (se presente). Le FGPP non sono GPO e non compaiono in GPResult.
- La chiave di Registro
HKLM\SYSTEM\CurrentControlSet\Services\Netlogon\Parameters\MaximumPasswordAge
regola l’età massima della password dei computer account (rotazione del canale sicuro), non la scadenza delle password degli utenti. Correggerla non cambia i promemoria di scadenza per gli utenti di dominio.
Indizi che puntano alle FGPP
- Scadenza persistente intorno a 40–42 giorni nonostante il GPO a 365 giorni (molte FGPP storiche mantengono il vecchio default di 42 giorni).
- Alcuni utenti o reparti colpiti, altri no (tipico quando la PSO è assegnata a specifici gruppi).
- Output di
net user <utente> /domain
che riporta una data di scadenza coerente con ~40–42 giorni dall’ultimo cambio, mentrenet accounts
sul DC mostra 365.
Come funzionano davvero le FGPP
Le FGPP sono oggetti AD (Password Settings Object, PSO) memorizzati in CN=Password Settings Container, CN=System, DC=…. Ogni PSO contiene parametri come complessità, lunghezza minima, cronologia, blocco e soprattutto MaxPasswordAge
. Una PSO può essere applicata direttamente a utenti o a gruppi (con valutazione della membership transitiva).
Se più PSO sono applicabili allo stesso utente, vince quella con valore di precedenza (msDS-PasswordSettingsPrecedence
) più basso. È buona pratica mantenere valori di precedenza univoci per evitare pareggi.
L’oggetto utente espone un attributo calcolato, msDS-ResultantPSO
, che indica quale PSO è risultata vincente; se è null, si applica la Default Domain Password Policy.
Procedura di diagnosi e risoluzione
Controllare la presenza di FGPP
Metodo grafico (ADAC)
- Apri Active Directory Administrative Center (ADAC).
- Vai in System > Password Settings Container.
- Ispeziona la lista di PSO e verifica i valori di MaxPasswordAge.
Metodo PowerShell
# Elenca tutte le FGPP con precedenza e durata massima
Get-ADFineGrainedPasswordPolicy -Filter * |
Select-Object Name, msDS-PasswordSettingsPrecedence, MaxPasswordAge, MinPasswordLength, PasswordHistoryCount |
Sort-Object msDS-PasswordSettingsPrecedence
Verificare la PSO effettiva per gli utenti
Metodo grafico (ADAC): apri la scheda dell’utente e scegli View resultant password settings.
Metodo PowerShell (due alternative):
# Mostra la PSO risultante (se c'è) per un utente
Get-ADUser <samAccountName> -Properties msDS-ResultantPSO |
Select-Object SamAccountName, msDS-ResultantPSO
Oppure ottieni direttamente i dettagli della policy effettiva
Get-ADUserResultantPasswordPolicy -Identity
Per controllare a colpo d’occhio tutti gli utenti che non stanno usando la policy di default:
# Elenco utenti con una PSO assegnata (diretta o tramite gruppo)
Get-ADUser -Filter * -Properties msDS-ResultantPSO |
Where-Object { $_.'msDS-ResultantPSO' } |
Select-Object SamAccountName, msDS-ResultantPSO
Individuare le associazioni PSO–gruppo/utente
Una volta identificata la PSO sospetta (quella con MaxPasswordAge
~40–42 giorni), estrai i soggetti a cui è assegnata:
# Soggetti (utenti/gruppi) a cui è applicata la PSO
Get-ADFineGrainedPasswordPolicySubject -Identity "Nome-PSO"
Verifica l’appartenenza ai gruppi: spesso la PSO è applicata a un gruppo intermedio (es. “Utenti Reparto X”) del quale gli interessati sono membri indiretti.
Rimuovere o modificare le FGPP indesiderate
Se il requisito è avere 365 giorni per tutti:
- Opzione A – Eliminare la PSO: rimuovi la PSO con durata anomala e fai in modo che gli utenti tornino alla Default Domain Password Policy.
- Opzione B – Adeguare la PSO: aggiorna
MaxPasswordAge
a365.00:00:00
(formato giorni:ore:minuti:secondi).
# Imposta MaxPasswordAge a 365 giorni su una PSO esistente
Set-ADFineGrainedPasswordPolicy -Identity "Nome-PSO" -MaxPasswordAge (New-TimeSpan -Days 365)
Oppure rimuovi l'associazione ai soggetti per tornare alla policy di default
Remove-ADFineGrainedPasswordPolicySubject -Identity "Nome-PSO" -Subjects "CN=Utenti Reparto X,OU=Gruppi,DC=contoso,DC=local"
Se desideri mantenere più policy (es. reparti con requisiti diversi), verifica la colonna msDS-PasswordSettingsPrecedence: un numero più basso vince. Assegna precedenze coerenti per evitare sorprese.
Forzare la replica e la nuova valutazione
Le FGPP sono oggetti AD; non seguono l’elaborazione “classica” dei GPO. Non ha senso forzare gpupdate
sui client per loro. Tuttavia è buona prassi assicurarsi che il DC abbia replicato (se ne avessi più di uno). Nel tuo scenario è presente un solo Domain Controller, quindi la replica inter‑DC non è un tema, ma puoi comunque sincronizzare manualmente i servizi.
:: Aggiorna criteri locali (utile dopo modifiche al GPO, non alle FGPP)
gpupdate /force
:: Replica AD in ambienti multi-DC (non necessario se hai un solo DC)
repadmin /syncall
Per confermare la policy di default effettiva sul dominio:
:: Eseguito su un Domain Controller
net accounts
:: Eseguito su un membro del dominio per interrogare la policy del dominio
net accounts /domain
Convalidare con un utente di prova
- Reimposta la password di un utente di test e annota
pwdLastSet
. - Ottieni la policy effettiva (default o FGPP) e calcola la scadenza.
# Ottiene data ultimo cambio e data di scadenza calcolata
$user = Get-ADUser <samAccountName> -Properties pwdLastSet, msDS-UserPasswordExpiryTimeComputed
$pwdChanged = [DateTime]::FromFileTime([Int64]$user.pwdLastSet)
$expiresComputed = [DateTime]::FromFileTime([Int64]$user.'msDS-UserPasswordExpiryTimeComputed')
[PSCustomObject]@{
User = $user.SamAccountName
PwdLastSet = $pwdChanged
PasswordExpiry = $expiresComputed
}
Approfondimenti pratici
Tabella di comandi e strumenti
Comando / Strumento | Scopo rapido |
---|---|
Get-ADFineGrainedPasswordPolicy -Filter * | Elenca tutte le FGPP presenti |
Get-ADUser <u> -Properties msDS-ResultantPSO | Mostra la PSO effettiva per l’utente (se presente) |
Get-ADUserResultantPasswordPolicy -Identity <u> | Dettaglio completo della policy password applicata all’utente |
Get-ADFineGrainedPasswordPolicySubject -Identity "PSO" | Elenca utenti e gruppi a cui è applicata la PSO |
Get-ADDefaultDomainPasswordPolicy | Mostra la Default Domain Password Policy |
net accounts (su DC) / net accounts /domain | Riassunto della password policy predefinita |
ADAC → Password Settings Container | Gestione grafica delle FGPP |
Script di audit “tutto in uno”
Usa questo script per mappare la situazione: quali PSO esistono, quali utenti ne ereditano una, quali scadenze reali hanno.
# Richiede modulo ActiveDirectory
1) PSO esistenti
"== PSO esistenti =="
Get-ADFineGrainedPasswordPolicy -Filter * |
Select Name, msDS-PasswordSettingsPrecedence, MaxPasswordAge, MinPasswordLength, PasswordHistoryCount |
Sort msDS-PasswordSettingsPrecedence | Format-Table -AutoSize
2) Utenti con PSO risultante
"`n== Utenti con PSO risultante =="
Get-ADUser -Filter * -Properties msDS-ResultantPSO |
Where-Object { $_.msDS-ResultantPSO } |
Select SamAccountName, msDS-ResultantPSO | Format-Table -AutoSize
3) Scadenze effettive per un campione (o per tutti, se preferisci)
"`n== Scadenze effettive (campione) =="
$sample = Get-ADUser -Filter * -Properties pwdLastSet, msDS-UserPasswordExpiryTimeComputed -ResultPageSize 200
$sample | Select-Object SamAccountName,
@{N='PwdLastSet';E={[DateTime]::FromFileTime([Int64]$*.pwdLastSet)}},
@{N='Expires';E={ if ($*.'msDS-UserPasswordExpiryTimeComputed') {[DateTime]::FromFileTime([Int64]$_.'msDS-UserPasswordExpiryTimeComputed')} else { $null }}} |
Sort-Object Expires | Format-Table -AutoSize
Errori frequenti e come evitarli
- Modificare il GPO “Default Domain Controllers Policy” invece della “Default Domain Policy”: la policy password di dominio viene presa dal GPO con impostazioni di Account Policies collegato alla radice del dominio (per default, la Default Domain Policy). Le impostazioni sotto l’OU Domain Controllers influenzano solo i DC.
- Usare GPResult per “verificare” la password policy: non rivela la presenza o l’assenza di FGPP. Verifica sempre
msDS-ResultantPSO
oGet-ADUserResultantPasswordPolicy
. - Confondere Netlogon\MaximumPasswordAge con la scadenza delle password utente: è la rotazione della password del computer account, non degli utenti.
- Precedenze incoerenti nelle PSO: se mantieni più FGPP, assegna msDS-PasswordSettingsPrecedence univoci e documentati (più basso = maggiore priorità).
- Non considerare le membership indirette: una PSO applicata a un gruppo “padre” può colpire gli utenti tramite gruppi annidati.
- Trascurare l’attributo “Password never expires”: gli utenti con il flag DONTEXPIREPASSWORD non riceveranno promemoria, generando apparenti incoerenze nelle verifiche.
Checklist rapida di debug
- Conferma la Default Domain Password Policy corrente:
Get-ADDefaultDomainPasswordPolicy | Select-Object MaxPasswordAge, MinPasswordLength, PasswordHistoryCount, ComplexityEnabled
- Elenca tutte le FGPP e individua valori < 365 giorni:
Get-ADFineGrainedPasswordPolicy -Filter * | Where-Object { $_.MaxPasswordAge.Days -lt 365 } | Select Name, MaxPasswordAge
- Per un utente affetto, verifica la policy risultante:
Get-ADUserResultantPasswordPolicy -Identity <samAccountName>
- Se necessario, rimuovi/aggiusta la PSO e verifica i soggetti associati:
Set-ADFineGrainedPasswordPolicy -Identity "Nome-PSO" -MaxPasswordAge (New-TimeSpan -Days 365) Get-ADFineGrainedPasswordPolicySubject -Identity "Nome-PSO"
- Convalida le scadenze:
net user <samAccountName> /domain
Esempio completo end‑to‑end
- Osservazione del sintomo: utenti che hanno cambiato password il 15 marzo ricevono avviso di scadenza attorno al 25–30 aprile.
- Verifica GPO: Default Domain Policy mostra Maximum password age = 365. GPResult conferma l’applicazione del GPO, ma non è sufficiente.
- Ricerca FGPP:
Get-ADFineGrainedPasswordPolicy -Filter * | Select Name, MaxPasswordAge, msDS-PasswordSettingsPrecedence
Viene rilevata una PSO “PSO-RepartoX” conMaxPasswordAge = 42.00:00:00
. - Verifica soggetti:
Get-ADFineGrainedPasswordPolicySubject -Identity "PSO-RepartoX"
La PSO è assegnata al gruppo GG-RepartoX-Utenti del quale gli utenti affetti sono membri. - Rimedi: si decide di uniformare a 365 giorni.
Set-ADFineGrainedPasswordPolicy -Identity "PSO-RepartoX" -MaxPasswordAge (New-TimeSpan -Days 365)
- Convalida:
Get-ADUserResultantPasswordPolicy -Identity mario.rossi Get-ADUser mario.rossi -Properties msDS-UserPasswordExpiryTimeComputed | Select SamAccountName, @{N='Expires';E={[DateTime]::FromFileTime([Int64]$_.msDS-UserPasswordExpiryTimeComputed)}}
L’utente ora mostra scadenza a 365 giorni dall’ultimo cambio.
Domande frequenti
Le FGPP richiedono un livello funzionale specifico?
Sì, sono disponibili da AD DS livello funzionale dominio/foresta Windows Server 2008 o superiore. In ambienti moderni è lo standard.
Le FGPP sono GPO?
No. Sono oggetti AD (classe msDS-PasswordSettings) nel Password Settings Container. Non compaiono in gpresult
o rsop.msc
.
Come faccio a sapere la policy effettiva senza calcoli?
Usa l’attributo calcolato msDS-UserPasswordExpiryTimeComputed
o Get-ADUserResultantPasswordPolicy
per vedere direttamente la scadenza e i parametri.
Perché “net accounts” e i client dicono cose diverse?
Su un DC, net accounts
riporta la policy di dominio. Su un client, usa net accounts /domain
per interrogare la policy del dominio; senza /domain
vedresti solo la policy locale.
Serve eseguire gpupdate per applicare le FGPP?
No. Essendo oggetti AD, si applicano per effetto della valutazione dei criteri di password da parte del DC. gpupdate
è utile quando modifichi GPO, non le FGPP.
Best practice operative
- Documenta e versiona le PSO: mantieni un inventario con scopo, soggetti, durata e precedenza.
- Usa gruppi dedicati per applicare le PSO, evitando assegnazioni dirette agli utenti.
- Uniforma i valori: se vuoi una sola durata, elimina o adegua tutte le PSO con
MaxPasswordAge
diversi. - Monitora le scadenze con report periodici basati su
msDS-UserPasswordExpiryTimeComputed
. - Evita precedenze duplicate: definisci una scala (es. 10, 20, 30…) e non riutilizzare gli stessi numeri.
Diagnosi rapida con albero decisionale
- Gli utenti vedono scadenza intorno a 40–42 giorni? → Sì.
- La Default Domain Policy è a 365 giorni? → Sì (
Get-ADDefaultDomainPasswordPolicy
). - L’utente ha una PSO risultante? → Verifica
msDS-ResultantPSO
oGet-ADUserResultantPasswordPolicy
. - Esistono PSO con MaxPasswordAge < 365? → Identifica e modifica/elimina.
- Conferma scadenze post‑fix →
msDS-UserPasswordExpiryTimeComputed
restituisce la data corretta a +365 giorni.
Nota importante sulla chiave Netlogon
La voce HKLM\SYSTEM\CurrentControlSet\Services\Netlogon\Parameters\MaximumPasswordAge
spesso genera confusione: regola il periodo dopo il quale le macchine di dominio ruotano automaticamente la password del proprio account computer (per impostazione predefinita circa 30 giorni). Non influenza la scadenza delle password degli utenti. Per questi ultimi contano solo Default Domain Password Policy e le FGPP.
Riepilogo operativo
Il sintomo “scadenza a ~40 giorni” con GPO a 365 è quasi sempre dovuto a una Fine‑Grained Password Policy che prevale sulla Default Domain Password Policy. Individua la PSO con MaxPasswordAge
corto, verifica a chi è assegnata, quindi elimina o adegua la PSO a 365 giorni. Convalida infine con Get-ADUserResultantPasswordPolicy
e msDS-UserPasswordExpiryTimeComputed
.
Appendice: riferimenti veloci
Attività | Comando |
---|---|
Default Domain Password Policy | Get-ADDefaultDomainPasswordPolicy |
Elenco FGPP | Get-ADFineGrainedPasswordPolicy -Filter * |
Policy effettiva per un utente | Get-ADUserResultantPasswordPolicy -Identity <u> |
PSO risultante (DN) | Get-ADUser <u> -Properties msDS-ResultantPSO |
Soggetti di una PSO | Get-ADFineGrainedPasswordPolicySubject -Identity "PSO" |
Modificare MaxPasswordAge | Set-ADFineGrainedPasswordPolicy -Identity "PSO" -MaxPasswordAge (New-TimeSpan -Days 365) |
Verifica scadenza calcolata | Get-ADUser -Properties msDS-UserPasswordExpiryTimeComputed |
Con questa guida puoi ricondurre le scadenze a 365 giorni in modo sistematico, evitando false piste (GPO “visibile”, chiavi di Registro non pertinenti) e concentrandoti sul vero discriminante: la presenza di una FGPP con durata più breve.
In estrema sintesi: se la scadenza torna a farsi viva dopo ~40 giorni, la Default Domain Policy non è l’unica in gioco. C’è una PSO da trovare, comprendere e allineare.
Checklist finale
- Conferma il valore a 365 nella Default Domain Password Policy.
- Elenca le FGPP e individua quelle con MaxPasswordAge < 365.
- Verifica l’associazione PSO–utente/gruppo e le precedenze.
- Modifica o rimuovi la PSO, poi valida la scadenza con gli attributi calcolati.