Dieser Beitrag soll eine Hilfestellung für die Optimierung von Windows Terminalserver sein. Einige sind logische Konsequenzen auf Grund von Leistungseinbußen während des Betriebs, andere Tipps sind aus anderen Quellen und umfassen ggf. Eigenheiten von Windows, die umgestellt werden sollten. Die Tipps sind ab Windows Server 2016 anwendbar.
Falls weitere Erkenntnisse dazu kommen, trage ich die hier nach. Gerne in die Kommentare, falls ihr noch weitere Erkenntnisse und Hilfen habt.
Ich hatte mich dem Thema etwas mehr angenommen, da einige Benutzer immer wieder von Hängern und Verbindungsverlusten über die zur Verfügung gestellten Remote Apps klagten.
Hardware/VM Konfiguration
Man sollte natürlich in erster Linie für die entsprechende Nutzeranzahl und anwendungsspezifischen Voraussetzungen auch die entsprechende Leistung vorhalten.
Wenn möglich, RDS Hosts auf eigenen physischen Netzwerkkarten oder Netzwerkkarten mit hohem Bandbreitendurchsatz laufen lassen.
Genug RAM und Prozessor-Kerne vorhalten – heißt Anwendung begutachten und prüfen wie viel Arbeitsspeicher benötigt wird und wie hoch die Prozessor-Last pro Benutzer ist. Ggf. Erfahrungswerte direkt vom Hersteller/Dienstleister einholen.
Zusätzlich 1-2 Kerne und mindestens 2-4 GB RAM, für OS bedingte Prozesse, mehr zur Verfügung stellen, damit sich das alles ein wenig verteilen kann.
Wenn möglich NVMe Speicher verwenden. HDDs sind heutzutage kostengünstig, aber für Application- und Terminalserver keine gute Wahl, da HDDs sehr wenige gleichzeitige I/O Zugriffe zulassen.
Energieeinstellungen prüfen
Darauf achten, dass Höchstleistung eingestellt ist.
Zur Prüfung einfach in der Systemsteuerung / den Einstellungen den Energieplan prüfen und umstellen oder in Powershell folgenden Befehl ausführen.
powercfg /list
powercfg /s 8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c
Mit /list kann man sich die verfügbaren Energiepläne anzeigen. Der mit * markierte Plan ist aktiv.
Und mit /s und der ID des Energieplans kann dann der entsprechende Plan gesetzt werden. Hier Höchstleistung.
Festplattenoptimierung deaktivieren
Defragmentierung der HDDs oder Optimierung der SSDs führt zu erhöhten Zugriffen auf den Festplatten, was die I/Os in die Höhe treibt. Außerdem verursacht das auch Prozessorlast. Und meist werden diese Optimierung an den unmöglichsten Zeiten ausgeführt.
Daher, vor allem wenn man FSLogix Benutzerprofile verwendet, den Dienst „Laufwerke optimieren“ deaktivieren. Die FSLogix VHDs werden nämlich von Windows immer defragmentiert, wenn sie eingehangen werden und Windows meint es hat den Termin zum Defragmentieren verpasst. Leider funktioniert auch das Exkludieren nicht gut, da neu erkannte Festplatten immer automatisch zur Optimierung aktiviert werden.
Zum Deaktivieren in die MMC für Services gehen und den Dienst deaktivieren oder folgenden Befehl in Powershell ausführen.
Set-Service -Name defragsvc -StartupType Disabled

Nun will man aber natürlich, dass die lokalen Festplatten defragmentiert bzw. optimiert und der TRIM-Befehl für SSDs ausgeführt wird. Daher erstellt man sich in der Aufgabenplanung eine Aufgabe für wann auch immer man morgens, wenn wenig los ist, die Festplatten defragmentieren will.
Dazu erstellt man sich ein Powershell Skript und legt es für dieses Beispiel auf C:\Windows\Skripte ab.
Set-Service -Name defragsvc -StartupType Manual
Defrag.exe /AllVolumes
Stop-Service defragsvc
Set-Service -Name defragsvc -StartupType Disabled
chkdsk C: /perf /scan
Ein CheckDisk kann auch nicht schaden. Allerdings wird hier nur geprüft, nicht repariert. Und jeder Laufwerksbuchstabe muss per chkdsk separat angesprochen werden. In der Ereignisanzeige unter Anwendungen kann man dann prüfen, ob man den Server aus dem Pool nehmen muss, um eine Fehlerreparatur durchzuführen.
Nun wird noch mit folgendem Konstrukt eine Aufgabe über Powershell geplant. Einfach Copy and Paste.
$action = New-ScheduledTaskAction -Execute C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe -Argument '-ExecutionPolicy Bypass -file "C:\Windows\Skripte\Defrag.ps1"'
$trigger = New-ScheduledTaskTrigger -Weekly -WeeksInterval 4 -DaysOfWeek Sunday -At 5am
$principal = New-ScheduledTaskPrincipal -UserId 'NT AUTHORITY\SYSTEM' -RunLevel Highest
$settings = New-ScheduledTaskSettingsSet
$task = New-ScheduledTask -Action $action -Principal $principal -Trigger $trigger -Settings $settings
Register-ScheduledTask "Defrag All 5 Uhr" -InputObject $task
Hier wird jetzt alle 4 Wochen am Sonntag um 5 Uhr morgens eine Prüfung durchgeführt. Ich habe mein PS1-Skript im übrigen einfach Defrag.ps1 genannt.
Boot tut Gut
Es macht sicherlich auch Sinn den Terminalserver regelmäßig neu zu starten um Treiber neu zu initialisieren, den Arbeitsspeicher zu leeren und einfach mal die Dienste wieder neu zu starten.
Das kann man natürlich auch wieder mit einer geplanten Aufgabe erledigen.
$action = New-ScheduledTaskAction -Execute C:\Windows\System32\shutdown.exe -Argument '/r /f'
$trigger = New-ScheduledTaskTrigger -Daily -At 4am
$principal = New-ScheduledTaskPrincipal -UserId 'NT AUTHORITY\SYSTEM' -RunLevel Highest
$settings = New-ScheduledTaskSettingsSet
$task = New-ScheduledTask -Action $action -Principal $principal -Trigger $trigger -Settings $settings
Register-ScheduledTask "Restart 4 Uhr" -InputObject $task
Leistungsoptionen einstellen
Es ist sinnvoll das ganze Bling Bling auszumachen. Also Fenster beim Ziehen anzeigen, Animationen oder sonstiges. Das kann man dann unter der Systemsteuerung – System – Erweiterte Systemeinstellungen tun.
Dort dann noch in den Reiter „Erweitert“ gehen und mit einem Klick auf „Einstellungen“ bei Leistung das Konfigurationsfenster öffnen. Dort dann einfach „Für optimal Leistung anpassen“ auswählen und mit „OK“ bestätigen.

Firewall UWP App Bug auf Windows Server
Das was mir komplett neu war und mich wieder an Microsoft verzweifeln lies, ist ein scheinbarer Bug, dass für jeden Benutzer jedes mal für jede UWP App ein Firewall Eintrag in die Registry geschrieben wird. Das führt dazu, dass Remoteserver stottern, laggen und ggf. auch die Verbindung verlieren können.
Microsoft hat ein Registry-Key per Update implementiert, welcher dafür sorgt, dass diese Einträge bei Logout des Benutzers wieder gelöscht werden. Muss man aber natürlich manuell setzen.
Mir ist davon abgesehen schon mal aufgefallen, dass die Firewalleinträge scheinbar für jeden Benutzer erstellt werden. Ich habe mich gewundert, aber nicht weiter darüber nachgedacht. Man sieht das auch gut in der GUI in den erweiterten Firewalleinstellungen.
Es ist möglich, sich die tausenden Einträge auch wundervoll in der Registry unter
„HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\RestrictedServices\AppIso\FirewallRules“
anzuschauen.
Für Windows Server 2016 wäre der Schlüsselpfad folgend:
„HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\RestrictedServices\Configurable\System“
Es muss also als erstes der Inhalt des Registry-Pfads gelöscht werden.
#Delete Firewall Rules Server 2016
reg delete "HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\RestrictedServices\Configurable\System" /va /f
#Delete Firewall Rules Server 2019
reg delete "HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\RestrictedServices\AppIso\FirewallRules" /va /f
Anschließend wird ein neuer Schlüsselwert erstellt, der dann dafür sorgt, dass während der Abmeldung des Benutzers diese Einträge automatisch entfernt werden.
New-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy" -Type DWord -Name DeleteUserAppContainersOnLogoff -Value 1
Quellen:
https://learn.microsoft.com/en-us/archive/msdn-technet-forums/992e86c8-2bee-4951-9461-e3d7710288e9
https://www.windowspro.de/roland-eich/remote-desktop-windows-server-20162019-startmenue-funktioniert-nicht
https://stackoverflow.com/questions/40620634/speed-up-powershells-remove-netfirewallrule/40915201#40915201

