Wichtige Info

Die Inhalte, die du hier siehst stelle ich dir ohne Werbeanzeigen und ohne Tracking deiner Daten zur Verfügung. Trotzdem muss ich die Server bezahlen sowie Zeit in Recherche, Umsetzung sowie Mail Support stecken.
Um dies leisten zu können, verlinke ich in einigen Artikeln auf die Plattform Amazon. Alle diese Links nennen sich Afiliate Links. Wenn du dir mit diesem Link etwas kaufst, dann erhalte ich eine kleine Provision. Dies ändert jedoch NICHT den Preis, den du bezahlst!
Falls du mich also unterstützen möchtest, kannst du auf den Link zum Produkt klicken und hilfst mir dabei, dieses Hobby weiter zu betreiben.
Da ich Keine Werbung schalte und keine Spenden sammle, ist dies die einzige Möglichkeit, meine Systeme und mich zu finanzieren. Ich hoffe du kannst das verstehen :)



Windows Server 2016+ - Startmenü öffnet nicht


In letzter Zeit tritt vermehrt ein Fehler bei Windows Terminalservern auf, welcher dazu führt, dass das Startmenü nicht mehr geöffnet werden kann.
Im Folgenden ein paar Punkte, an denen es bei euch scheitern könnte. Am Schluss werde ich ein PS Script anhängen, welches die Schritte alle durchgeht. Bei Tests hat dieses funktioniert und vielleicht hilft es auch bei andern.


Grund des Problems (eine Vermutunng)

Bei der Anmeldung eines Users, werden in der Registry unter verschiedenen Keys neue Properties in der Registry angelegt. Diese werden bei jeder Anmeldung neu generiert, aber standardmäßig nicht automatisch gelöscht.
Nach jeder Anmeldung werden also neue properties für die Firewall generiert und beim Öffnen des Startmenüs /oder Cortana, wird die gesamte Liste der Regeln geprüft, sobald der Server dies nicht mehr handeln kann, kann das Startmenü nicht mehr geöffnet werden.

Zur Lösung des Problems habe ich ein kleines Script geschrieben, welches das Problem bei einigen Tests behoben hat. Dieses löscht 2 Keys bzw. die Properties, welche Userbezogen erstellt worden sind und initialisiert daraufhin das Startmenü neu.

Zuletzt wird noch die Funktion zum Löschen der erstellten Einträge gesetzt, wodurch das Problem dauerhaft behoben sein sollte.

Script

$PSDefaultParameterValues['Out-File:Encoding'] = 'utf8'
#> Counter for tracking <#
$removedEntries = 0;
$ignoredEntries = 0;
$toalCheckedEntries = 0;
<# $path = 'Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\sharedAccess\parameters\FirewallPolicy\RestrictedServices\AppIso\FirewallRules' #>
$prePath = 'Registry::';
$path = 'HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\FirewallRules'
$strExportFileName = "RegSaveKey1.reg";
$strExportPath = "C:\temp\registryBackup";
mkdir $strExportPath;

Write-Output 'Script zum beheben von Startmenuproblemen auf WindowsServer2016'
Write-Output 'Loeschen von Firewall Rules'
$cont = Read-Host 'Soll das Script den FireWall Rules Ordner leeren [Y/n]?: '
if($cont -ne "Y" -and $cont -ne "J" -and $cont -ne "")
{
    Write-Output "Der Registry Key 'Firewall Rules' wird nicht geleert! - Script beendet!";
}
else {
    $cont = Read-Host 'Soll die Registry gesichert werden [Y/n] (empfohlen) ?: '
    if($cont -eq "Y" -or $cont -eq "J" -or $cont -eq "")
    {
        Write-Output "Sicherung von $path"
        Write-Output "Sicherung der Registry...";
	    Write-Output "reg export $path $strExportPath\$strExportFileName"
        $res = reg export $path $strExportPath\$strExportFileName;
    }
    else
    {
        $res = 0;
    }
    if($res -eq 1)
    {
        Write-Output "Can't save Registry! - Abort cleaning Folder!";
        Pause
        exit
    }
    if($res -eq 0) {
        Write-Output "Registry gesichert. Pfad: $strExportPath\$strExportFileName";
    $allPropertyNames = @();
    Write-Output "Loesche FireWall Rules unter $path";
    $RegKey = (Get-ItemProperty $prePath$path | Select-Object * -exclude PS*)

    $RegKey.PSObject.Properties | ForEach-Object {
        $allPropertyNames += $_.Name;
    }
    $numberOfProperties = $allPropertyNames.Count;
    Write-Output "Abrufen der Eintraege beendet!"
    Write-Output "Anzahl der zu pruefenden Properties: $numberOfProperties"



    ForEach($entry in $allPropertyNames)
    {
        if($entry.StartsWith("{") -and $entry.EndsWith("}"))
        {
            Remove-ItemProperty -Path $path -Name $entry;
            $removedEntries++;
        }
        else {
            $ignoredEntries++;
        }
        $toalCheckedEntries++;

        if($removedEntries % 1000 -eq 0 -and $removedEntries -ge 1)
        {
            Write-Output "Es wurden $removedEntries properties geloescht"
        }
    }
    Write-Output "Loeschen der Firewall Rules Step 1 beendet."
    Write-Output "Insgesamt geprueft: $toalCheckedEntries, Geloeschte Eintraege: $removedEntries, Ignorierte Entraege: $ignoredEntries";
    } 
}
Get-AppXPackage -AllUsers | Foreach {Add-AppxPackage -DisableDevelopmentMode -Register "$($_.InstallLocation)\AppXManifest.xml"}


<# 2. Ordner wird geloescht#>

#> Counter for tracking <#
$removedEntries = 0;
$ignoredEntries = 0;
$toalCheckedEntries = 0;
<# $path = 'Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\sharedAccess\parameters\FirewallPolicy\RestrictedServices\AppIso\FirewallRules' #>
$prePath = 'Registry::';
$path = 'HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\sharedAccess\parameters\FirewallPolicy\RestrictedServices\AppIso\FirewallRules'
$strExportFileName = "RegSave2.reg";
$strExportPath = "C:\temp\registryBackup";
mkdir $strExportPath;

Write-Output 'Loesche Pfad 2'
Write-Output 'Rufe Properties ab'
$cont = Read-Host 'Soll die Registry gesichert werden (nicht wichtig) [Y/n]?: '
if($cont -eq "Y" -or $cont -eq "J" -or $cont -eq "")
{
    Write-Output "Sicherung von $path"
    Write-Output "Sicherung der Registry...";
    Write-Output "reg export $path $strExportPath\$strExportFileName"
    $res = reg export $path $strExportPath\$strExportFileName;
}
else
{
    $res = 0;
}
if($res -eq 1)
{
    Write-Output "Can't save Registry! - Abort cleaning Folder!";
    Pause
    exit
}
if($res -eq 0) {
    Write-Output "Registry gesichert. Pfad: $strExportPath\$strExportFileName";
$allPropertyNames = @();
Write-Output "Loesche FireWall Rules unter $path";
$RegKey = (Get-ItemProperty $prePath$path | Select-Object * -exclude PS*)
$RegKey.PSObject.Properties | ForEach-Object {
    $allPropertyNames += $_.Name;
}
$numberOfProperties = $allPropertyNames.Count;
Write-Output "Abrufen der Eintraege beendet!"
Write-Output "Anzahl der zu pruefenden Properties: $numberOfProperties"
ForEach($entry in $allPropertyNames)
{
    if($entry.StartsWith("{") -and $entry.EndsWith("}"))
    {
        Remove-ItemProperty -Path $path -Name $entry;
        $removedEntries++;
    }
    else {
        $ignoredEntries++;
    }
    $toalCheckedEntries++;
    if($removedEntries % 1000 -eq 0 -and $removedEntries -ge 1)
    {
        Write-Output "Es wurden $removedEntries properties geloescht"
    }
}
Write-Output "Loeschen der Firewall Rules beendet."
Write-Output "Insgesamt geprueft: $toalCheckedEntries, Geloeschte Eintraege: $removedEntries, Ignorierte Entraege: $ignoredEntries";
} 

Get-AppXPackage -AllUsers | Foreach {Add-AppxPackage -DisableDevelopmentMode -Register "$($_.InstallLocation)\AppXManifest.xml"}


$cont = Read-Host 'Alle problematischen Eintraege geloescht...'
DWORD "DeleteUserAppContainersOnLogoff = 1 in HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy"
Write-Output "Das Script wird beendet!"
Pause

Back…