- PowerShell 100%
| Filename | Latest commit message | Latest commit date |
|---|---|---|
| example.env | ||
| README.md | ||
| Reset-RDS-GracePeriod.ps1 | ||
RDS Grace Period – kontrola, záloha, reset a e-mailový report
Verze 2.2, Windows PowerShell 5.1, spouštění přímo na RDS Session Hostu.
Skript zjistí počet zbývajících dní. Ručně nabídne potvrzení bez ohledu na čas; automaticky provede akci jen pod limitem. Vyhledává právě jednu hodnotu typu REG_BINARY začínající na L$RTMTIMEBOMB v klíči:
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Terminal Server\RCM\GracePeriod
Nejdříve zálohuje celý klíč, potom smaže pouze nalezenou hodnotu. Oprávnění ani vlastníka registru nemění. Po úspěšném smazání nabídne jednorázový restart; v režimu -y jej naplánuje automaticky, standardně na 22:00 místního času serveru. Parametr -NoReboot plánování vypne. Smazání není potvrzením obnovené grace periody; po restartu je nutné ověřit počet dní a nové přihlášení.
Microsoft reset nedoporučuje a návod Dellu jej omezuje na testovací prostředí. Reset nenahrazuje správné licence a konfiguraci; Per User ve workgroup zůstává problémem.
Soubory a příprava
Reset-RDS-GracePeriod.ps1– skript.example.env– vzor SMTP konfigurace; zkopíruj ho jako.envvedle skriptu.README.md– tento návod.
Rozbal například do C:\Scripts\RDS. Pro úlohu běžící jako SYSTEM musí být skript a .env zapisovatelné pouze správci/SYSTEM, nikoli běžnými uživateli. SMTP heslo v .env je prostý text; omez přístup k souboru. Hodnoty z produkčního SQL nastavení nejsou součástí balíčku.
Použij 64bitový Windows PowerShell. Účet musí mít přístup k RDS CIM, právo exportovat klíč a smazat cílovou hodnotu, zapisovat na cílovou plochu a do složky logů. Samotný SYSTEM nezaručuje obejití ACL. Při Access denied skript skončí chybou; práva automaticky nepřebírá.
Parametry
| Parametr | Výchozí hodnota | Význam |
|---|---|---|
-y, plný název -AutoConfirm |
vypnuto | Automatické potvrzení, bez dotazů a čekání na Enter. Akce jen pod limitem. Staré -f a -Force zůstávají kompatibilní aliasy. |
-DaysThreshold |
14 |
Hranice varování a automatické akce: počet dní menší než limit; rozsah 1–121. Ruční potvrzení neomezuje. |
-DesktopPath |
plocha aktuálního účtu | Absolutní cesta k existující složce plochy. V režimu -y povinná. |
-ConfigPath |
.env vedle skriptu |
Konfigurace e-mailu. Explicitně zadaný neexistující soubor je chyba. |
-LogDirectory |
logs vedle skriptu |
Log a textový report každého běhu. Složka se vytvoří. |
-DryRun |
vypnuto | Bez zálohy, mazání a plánování restartu. Log a případný e-mail se vytvoří. |
-RebootTime |
22:00 |
Výchozí čas restartu ve formátu HH:mm, místní čas serveru. |
-NoReboot |
vypnuto | Po smazání nenabídne ani nenaplánuje restart. Neruší dříve vytvořený plán. |
Při limitu 14:
| Zbývá | Ruční spuštění | Automatické -y |
|---|---|---|
| 14 dní a více | Nabídne ANO/NE, výchozí NE | SKIPPED, bez zálohy a mazání |
| 13 až 0 dní | Kritické varování a nabídka ANO/NE, výchozí NE | Kritické varování, záloha a mazání bez dotazu |
Ruční režim tedy umožňuje potvrdit mazání při libovolném zjištěném počtu dní. Pod limitem vypíše červené upozornění na blížící se nefunkčnost RDS; při nule již může být přihlašování blokované. Varování je také v logu a e-mailový report obsahuje Critical: True. Selhání zjištění času nebo nejednoznačná/chybějící hodnota registru dál akci zastaví.
Ruční spuštění
Z PowerShellu spuštěného jako správce:
& 'C:\Scripts\RDS\Reset-RDS-GracePeriod.ps1'
Bez ohledu na počet dní zobrazí cílovou hodnotu a cestu zálohy. Pouze odpověď ano (libovolná velikost písmen, okolní mezery ignorovány) povolí zálohu a mazání. Enter, ne i všechny jiné odpovědi znamenají NE. Po úspěšném smazání nabídne plán restartu popsaný níže. Nakonec čeká na Enter.
Pro ruční potvrzení při více než 13 dnech není potřeba žádný zvláštní parametr. -DaysThreshold mění v ručním režimu pouze hranici varování.
Při ručním spuštění pod SYSTEM a bez -DesktopPath se zeptá na cestu k ploše; nelze použít plochu SYSTEM jako plochu přihlášeného uživatele. Cestu je možné předat předem:
& 'C:\Scripts\RDS\Reset-RDS-GracePeriod.ps1' -DesktopPath 'C:\Users\Administrator\Desktop'
U přesměrované plochy či OneDrive zadej skutečnou cestu. Příklady s účtem Administrator nahraď svým účtem.
Nejdříve kontrola bez změny registru
Z CMD jako správce, na jednom řádku:
powershell.exe -NoProfile -NonInteractive -ExecutionPolicy Bypass -File "C:\Scripts\RDS\Reset-RDS-GracePeriod.ps1" -y -DaysThreshold 14 -DesktopPath "C:\Users\Administrator\Desktop" -DryRun
Pro kontrolu celé větve bez ohledu na běžný počet dní použij -DaysThreshold 121 -DryRun. Je-li e-mail zapnutý, DryRun opravdu odešle report. V automatickém režimu při 14 dnech a více s limitem 14 je výsledek SKIPPED; skript nekontroluje zápis zálohy ani mazání. Ani DryRun nezaručuje skutečná práva zápisu/mazání nebo budoucí úspěch.
Plánovač úloh – unattended
Vytvoř úlohu na RDS Session Hostu:
-
Obecné: účet
SYSTEMnebo určený servisní účet, nejvyšší oprávnění. U servisního účtu zvol spuštění bez ohledu na přihlášení uživatele. -
Aktivační událost: například denně v 06:00 po dobu dočasného řešení.
-
Akce → Spustit program:
Program:
C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exeArgumenty na jednom řádku:
-NoProfile -NonInteractive -ExecutionPolicy Bypass -File "C:\Scripts\RDS\Reset-RDS-GracePeriod.ps1" -y -DaysThreshold 14 -DesktopPath "C:\Users\Administrator\Desktop" -ConfigPath "C:\Scripts\RDS\.env"Spustit v:
C:\Scripts\RDS -
Nastavení: pokud úloha již běží, nespouštět novou instanci. Skript navíc používá globální mutex proti souběhu svých instancí.
-
První běh spusť s
-DryRun, zkontroluj log i e-mail pod skutečným účtem úlohy, pak tento parametr odeber.
-y musí být za cestou skriptu, nikoli před -File. V unattended režimu se žádný Read-Host neprovádí. Chybějící -DesktopPath je chyba, nikoli dotaz. Opakovanou kontrolní úlohu vytváříš ručně. Po úspěšném smazání skript vytvoří samostatnou jednorázovou úlohu restartu; s -y automaticky na 22:00, pokud nezadáš -NoReboot. Po dokončení doménové/licenční konfigurace dočasnou úlohu vypni.
Záloha
Pevný název na zadané ploše je RDS-GracePeriod-zaloha.reg. Zálohu vytváří jen ručně potvrzená akce (ano, bez ohledu na čas), nebo automatická akce (-y, pouze pod limitem). Přeskočení, odmítnutí a DryRun zálohu nevytvářejí.
Export nejprve uloží do dočasného souboru ve stejné složce, ověří úspěch a přítomnost cílové hodnoty. Teprve potom nahradí existující stejnojmennou zálohu. Selhání exportu zachová předchozí zálohu; selhání uložení zabrání mazání. Na filesystému, který nepodporuje použitou výměnu souboru, skončí chybou bez smazání hodnoty. Doporučená je lokální plocha na NTFS.
Soubor .reg obsahuje klíče a hodnoty, nikoli jejich ACL a vlastníka. Předchozí změny oprávnění je nutné evidovat zvlášť. Pokud po úspěšné záloze selže mazání, nová záloha zůstane zachována.
Pokud cílová hodnota chybí, skript nepřepíše zálohu a nahlásí CHECK_REQUIRED. Může jít o předchozí smazání před restartem; stav je nutné ověřit. Více odpovídajících hodnot je chyba. Tento nástroj nemaže libovolné hodnoty registru.
Prava registru a PsExec
Při Access denied při čtení nebo mazání registru skript zobrazí samostatný blok PRISTUP ODMITNUT, fázi chyby, výsledek zálohy a cestu k tomuto README. Při neúspěšném mazání se restart neplánuje. Pokud záloha již vznikla, zůstane na ploše. Oprávnění skript sám nemění.
Stažení a spuštění Regeditu jako SYSTEM
-
Stáhni PsTools z oficiální stránky Microsoft Sysinternals, případně přímo PsTools.zip.
-
ZIP rozbal například do
C:\Tools\PsTools. Program se nespouští ze ZIPu. Zavři existující okna Regeditu. -
Otevři PowerShell jako správce a spusť:
& 'C:\Tools\PsTools\PsExec64.exe' -i -d -s C:\Windows\regedit.exe -
Pokud pracuješ přes RDP, zjisti svou relaci příkazem
query session; aktuální řádek je označený>. Za-idoplň její číselné ID, například:& 'C:\Tools\PsTools\PsExec64.exe' -i 2 -d -s C:\Windows\regedit.exe
Při prvním spuštění potvrď licenční dialog PsExec. Pokud soubor v balíčku má název PsExec.exe, použij ten. Chyba „not recognized“ znamená, že je potřeba správná celá cesta; v PowerShellu se lokální program spouští s & 'celá cesta' nebo .\PsExec64.exe.
Nastavení oprávnění pro správce
V Regeditu běžícím jako SYSTEM otevři pouze tento klíč:
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Terminal Server\RCM\GracePeriod
- Poznamenej původního vlastníka a oprávnění.
.regzáloha je neobsahuje. Pokud je možné klíč číst, exportuj jej před změnou práv. - Pravým tlačítkem na
GracePeriod→ Oprávnění → Upřesnit. - Pokud nejde přidat oprávnění, u položky Vlastník → Změnit zvol místní skupinu
Administrators(lokalizovaný název může býtAdministrátoři), přes Umístění vyber místní server a použij Kontrola názvů. Potvrď změnu vlastníka. Změna vlastníka sama o sobě právo mazání nepřidává. - Přidej pravidlo Povolit pro skupinu místních správců nebo konkrétní účet, například
SERVER01\Administrator. Nastav Platí pro: Pouze tento klíč. Pro jednoduchou administrátorskou opravu zvol Úplné řízení. Užší varianta v pokročilých oprávněních: Číst a Nastavit hodnotu (Set Value); mazání hodnoty používá Set Value, nikoli právo smazat celý klíč. - Pro úlohu pod SYSTEM ověř odpovídající oprávnění také pro
SYSTEM. Práva udělená účtu Administrator se na účet plánované úlohy automaticky nepřenášejí. Existující explicitní Odepřít může mít přednost před Povolit; neodstraňuj plošně pravidla, vyřeš konkrétní konflikt s místní politikou. - Zavři Regedit. Skript spusť znovu jako správce, případně otestuj pod skutečným účtem plánované úlohy. Binární hodnotu nyní nemaž ručně: skript má nejdříve vytvořit vlastní zálohu.
Neuděluj práva Everyone/Users a neměň celý nadřazený RCM nebo Terminal Server. Po dokončení dočasného řešení vrať původního vlastníka a odstraň dočasná oprávnění. Pokud práva nejdou změnit ani jako SYSTEM, ověř konkrétní ACL a ochranu serveru; PsExec nemá univerzální schopnost obejít všechna oprávnění.
Restart serveru
Restart se nabízí nebo plánuje až po úspěšné záloze, smazání a ověření nepřítomnosti hodnoty. Při odmítnutí mazání, chybě práv, SKIPPED nebo DryRun nevzniká nový plán restartu. Pokud již existuje plán z předchozího běhu, tyto stavy jej neruší.
V ručním režimu se po smazání zobrazí:
RESTART SERVERU
Navrzeny restart: 2026-09-29 22:00
Chces naplanovat restart? [ANO/ne, Enter = ANO]
Cas restartu [Enter = 22:00; HH:mm; yyyy-MM-dd HH:mm; ne = zrusit]
- Enter na první otázce znamená ANO,
neplán odmítne. To je jiný výchozí stav než u mazání, kde Enter stále znamená NE. - Enter na otázce na čas vybere 22:00, nebo hodnotu
-RebootTime. - Lze zadat jiný čas, například
23:30, nebo konkrétní budoucí datum2026-09-30 01:00. - Pokud už dnešní čas uplynul, samotné
HH:mmznamená následující den. Dnešní 22:00 v minulosti nelze naplánovat, skript tedy neprovede okamžitý restart. - Zadání
nena otázce na čas plánování zruší.
S -y se neptá a při úspěšném mazání naplánuje restart na dnešní 22:00; pokud čas již uplynul, na zítřejší 22:00. Vždy jde o místní čas serveru, uvedený ve výstupu. Pro jiný automatický čas přidej například -RebootTime '23:30'. Pro pouhé mazání bez plánu přidej -NoReboot.
Skript vytvoří jednorázovou úlohu \RDS-GracePeriod-Reboot pod SYSTEM s nejvyššími oprávněními. Účet spouštějící skript tedy musí mít právo takovou úlohu vytvořit. Skript nepřepíše stejně pojmenovanou úlohu, která nemá jeho vlastní identifikační popis. Selhání plánování vrátí kód 3; již provedené smazání se nevrací zpět.
Úloha v daném čase vyvolá shutdown.exe /r /t 0, bez /f. Aplikace blokující ukončení mohou restart zdržet nebo zabránit jeho dokončení. Před termínem ulož práci a počítej s odpojením uživatelů. Úloha ověřuje, zda od jejího vytvoření server mezitím nerestartoval; pokud ano, další restart přeskočí. Zmeškaný termín se nedohání okamžitě při dalším startu. Jednorázová úloha zůstává po vykonání v Plánovači bez dalšího opakování.
Kontrola plánu v administrátorském PowerShellu:
Get-ScheduledTask -TaskName 'RDS-GracePeriod-Reboot' -TaskPath '\' |
Select-Object TaskName, State, Triggers
Get-ScheduledTaskInfo -TaskName 'RDS-GracePeriod-Reboot' -TaskPath '\'
Zrušení před termínem spuštění:
Unregister-ScheduledTask -TaskName 'RDS-GracePeriod-Reboot' -TaskPath '\' -Confirm:$false
shutdown /a neodstraní tuto naplánovanou úlohu. Zruš ji v Plánovači nebo uvedeným příkazem; až úloha v termínu zavolá /t 0, není k dispozici odpočítávání pro zrušení.
E-mail stejným způsobem jako SQL backup
Používá stejné klíče .env, System.Net.Mail.SmtpClient a prostý text jako dřívější SqlBackup.ps1. SMTP nastavení můžeš přenést ze SQL .env; uprav prefix předmětu. Příklad:
EMAIL_ENABLED=true
SMTP_SERVER=smtp.example.com
SMTP_PORT=587
SMTP_USE_SSL=true
SMTP_USERNAME=backup@example.com
SMTP_PASSWORD=CHANGE_ME
EMAIL_FROM=backup@example.com
EMAIL_TO=admin@example.com,second-admin@example.com
EMAIL_SUBJECT_PREFIX=[RDS Grace Period]
U relay bez přihlášení ponech SMTP_USERNAME= a SMTP_PASSWORD= prázdné. SMTP_USE_SSL=true znamená STARTTLS, běžně port 587; implicitní TLS na portu 465 tento klient nepodporuje. OAuth není implementován. Heslo se nikam neloguje; parser .env nespouští kód ani nerozbaluje proměnné. Komentáře musí být na vlastním řádku, nikoli za hodnotou. Okolní uvozovky se odstraní.
Bez výchozího .env je e-mail vypnutý. Se zapnutým e-mailem se posílá report každého běhu, včetně SKIPPED, CANCELLED, DRY_RUN, chyby a smazání. Předmět například:
[RDS Grace Period] [RESTART_REQUIRED] SERVER01
Report obsahuje server, začátek/konec, trvání, počet dní před akcí, limit, cestu a výsledek zálohy, výsledek mazání, potřebu restartu, naplánovaný termín a název úlohy restartu, odkaz na README při chybě práv, log a chybu. Smazání není označeno jako ověřený reset na 120 dní.
Konfigurace SMTP se kontroluje před změnou registru, síťové spojení až při odeslání reportu. Chyba odesílání se zapisuje do lokálního logu a na rozdíl od SQL verze vrací nenulový kód. Již provedenou akci nevrací zpět. Při vadné konfiguraci, kvůli níž nelze sestavit odesílač, e-mail o chybě odeslat nelze; použij log. SMTP timeout je 30 sekund.
Výsledky, logy a ověření
| Kód | Význam |
|---|---|
| 0 | Dokončeno: SKIPPED, CANCELLED, DRY_RUN, RESTART_REQUIRED nebo REBOOT_SCHEDULED. Stav určuje report. |
| 1 | Chyba kontroly, konfigurace, zálohy, mazání nebo logování. |
| 2 | Chyba e-mailového reportu; podrobnosti a výsledek akce jsou v logu. |
| 3 | Hodnota smazána, ale plánování restartu selhalo (REBOOT_SCHEDULE_FAILED). Restart zajisti ručně. |
| 10 | CHECK_REQUIRED: hodnota chybí, záloha zůstala zachována. |
Při současné chybě akce a e-mailu zůstává kód 1 (nebo 3 při selhání plánování restartu); chyba e-mailu při CHECK_REQUIRED vrací 2. Chyby parsování parametrů/načítání PowerShellu mohou nastat před vznikem logu. V Plánovači odpovídá 10 zápisu 0xA.
Každý běh vytváří logs\RDS_<datum>_<PID>.log a vedle něj .log.report.txt. Záznam selhání SMTP je v .log; textový report zachycuje stav před odesláním e-mailu. Logy se automaticky nemažou.
Po REBOOT_SCHEDULED je vytvořen plán restartu; po RESTART_REQUIRED či REBOOT_SCHEDULE_FAILED zajisti restart ručně v domluveném okně. Zbývající dobu ověř v administrátorském PowerShellu:
(Get-CimInstance -Namespace root/CIMV2/TerminalServices -ClassName Win32_TerminalServiceSetting | Invoke-CimMethod -MethodName GetGracePeriodDays).DaysLeft
Potom ověř přihlášení běžného uživatele. Skript zde nebyl spuštěn na Windows Serveru, skutečném registru ani SMTP; před nasazením ověř DryRun a report pod účtem plánované úlohy.