(MS Windows Server 2012 R2)
Na Windows serverech v RDP prostředí s vynucenou NLA autentizací (Network Level Authentication) resp. CredSSP protokolem (Credential Security Support Provider) nelze u klientů mimo doménu provést změnu hesla pomocí aplikace Mstsc.exe (Připojení ke vzdálené ploše).
Tato situace je pro uživatele nepříjemná, protože nezmění-li si heslo včas sami, po expiraci hesla se do systému již nepřihlásí.
Standardní řešení
- zobrazovat výzvu (bublinu) s informací o blížící se expiraci hesla viz https://docs.microsoft.com/en-us/windows/security/threat-protection/security-policy-settings/interactive-logon-prompt-user-to-change-password-before-expiration
- zprovoznit "RD Web" roli na serveru a umožnit tak uživateli změnu hesla pomocí webové služby viz https://docs.microsoft.com/en-us/windows-server/remote/remote-desktop-services/rds-rdweb-gateway-ha
Výzva bohužel nevyžaduje akci uživatele, tudíž bývá mnohdy opomíjena a uvádí postup pomocí zkratky CTRL+ALT+END, která neplatí např. u Linuxových klientů. V případě služby RD Web je třeba uživatele předem informovat a distribuovat mu zástupce resp. URL adresu.
Vlastní řešení - zpráva pomocí PowerShell skriptu
Protože výše uvedená řešení nepovažuji za ideální, připravil jsem PowerShell skript, který zobrazí uživateli zprávu s informací o expiraci hesla a vyžaduje akci. Po kliknutí na ANO se zobrazí tzv. GINA obrazovka (CTRL+ALT+DEL).
Skript načítá informace uložené v AD (Active Directory). Zjišťuje počet dní od poslední změny hesla (hodnota PasswordLastSet v účtu uživatele) a porovnává s hodnotou MaxPasswordAge v Password Policy převedenou na dny. Pokud do expirace hesla zbývá počet dnů v rozsahu 0 - $MsgDays, je uživateli zobrazena zpráva. Z Password Policy se ještě načte informace o minimální délce hesla (MinPasswordLength) a počtu posledních hesel, která nelze použít (PasswordHistoryCount).Zprovoznění skriptu
Na RDP servery je třeba nainstalovat PowerShell modul activedirectory a v AD nad objektem Password Policy (System -> Password Settings Container -> Policy) nastavit uživatelům právo Read pro potřebné vlastnosti (MinPasswordLength, PasswordHistoryCount, MaxPasswordAge) + Read permissions.
Ve skriptu stačí definovat 2 proměnné:
- $PassPolicyName = název Password Policy v AD
- $MsgDays = počet dní pro zobrazení zprávy před expirací hesla
Skript je nutné spouštět pod účtem uživatele po přihlášení a načtení Plochy, např. v GPO zde:
User Configuration -> Policies -> Administrative Templates -> System -> Logon: "Run these programs at user logon"
Skript
############################################################################## # The name of the password policy # (Users need permission to read the properties of this policy.) $PassPolicyName = "Password_Policy_name" # Number of days to display the message (before the password expires) $MsgDays = 14 ############################################################################## # Import ActiveDirectory PS module import-module activedirectory # Date the password was last set. $PassLastSetDate = [DateTime](get-aduser $env:UserName -properties passwordlastset | % passwordlastset) # Today date $Today = [DateTime](Get-Date) # Number of days since the last password was set. $PassLastSetDays = (New-TimeSpan -Start $PassLastSetDate -End $Today).Days # Get the properties of the password policy $PassPolicy = (Get-ADFineGrainedPasswordPolicy -Filter {name -like $PassPolicyName} -Properties MinPasswordLength, PasswordHistoryCount, MaxPasswordAge) # Maximum password age (days) $MaxPassDays = $PassPolicy.MaxPasswordAge.Days # Minimum password length $MinPassLength = $PassPolicy.MinPasswordLength # Number of remembered passwords $PassHistCount = $PassPolicy.PasswordHistoryCount # Remaining days of password validity $RemainingDays = ($MaxPassDays - $PassLastSetDays) # Display message only the X last days ($MsgDays) before the password expires if ( ($RemainingDays -ge 0) -and ($RemainingDays -le $MsgDays) ) { # Text string for the remaining days switch ($RemainingDays) { {$_ -eq 1} { $MsgRemDaysText = "den" } { ($_ -gt 1) -and ($_ -lt 5) } { $MsgRemDaysText = "dny" } Default { $MsgRemDaysText = "dní" } } # MessageBox settings Add-Type -AssemblyName PresentationCore, PresentationFramework $MsgTitle = "ZMĚNA HESLA" $MsgBody = "Vaše heslo vyprší za $RemainingDays $MsgRemDaysText. Chcete-li heslo změnit, klikněte na ANO`na zvolte 'Změnit heslo'.`n`nMin. délka hesla: $MinPassLength (znaků)`nPočet posledních hesel, která nelze použít: $PassHistCount" $MsgIcon = [System.Windows.MessageBoxImage]::Asterisk $MsgButtonType = [System.Windows.MessageBoxButton]::YesNo # MessageBox result $MsgResult = [System.Windows.MessageBox]::Show($MsgBody,$MsgTitle,$MsgButtonType,$MsgIcon) # If the answer ($MsgResult) = YES if ( $MsgResult -eq 6 ) { # Send CTRL+ALT+DEL command (New-Object -COM Shell.Application).WindowsSecurity() } }