Windows Server 2016/2019 RDS Server – Black screen or Start Menu not working | Phy2Vir

An IT Blog covering anything from Physical to Virtual in I.T

Windows Server 2016/2019 RDS Server – Black screen or Start Menu not working

A customer informed us that some users were getting a black screen after logon and others could not open the start menu after they got past the black screen. The customer restarted the RDS host but the issue was not resolved.

When checking the event logs I noticed system events with ID 10001 like the one below

This led me to think there was an issue with Appx and came across some material that suggested repairing Cortana. Trying to run the suggested PowerShell command failed and upon reviewing the AppPackage Log as suggested by the failure error I noticed that the package did not install because of insufficient resources. The system had only 6GB out of 128GB ram used and CPU (8 Cores) were at 2%

Searching further, I found this technet forum post in which the cause and solution are discussed.

Basically, every time a user logs into the RDS server, a new set of firewall rules is created and are not removed when the users log off, but new ones are re-created when they login again. This appears to happen most when using User Profile Disks (UPD). You may notice at this time that when trying to open WWindows Defender Firewall with Advanced Security to view the rules, the window would take a very long time to appear and end up in a “Not Responding” state.

This was resolved in Windows Server 2016 and 2019 by installing a Windows update, link for 2016 and 2019, and manually applying a registry key.

The updates were already installed so we proceeded to add the registry key as per below using Regedit.

Add “DeleteUserAppContainersOnLogoff” (DWORD) in “HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy” and set it to 1. 

We logged off and logged back in and the Start menu was working again. All the other users also reported that this resolved the issue.

At this stage it is suggested that the previously created firewall rules are also deleted. These are the registry keys were the rules are stored.

HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\FirewallRules (Server 2016 and 2019)
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\\RestrictedServices\AppIso\FirewallRules (Server 2019 only)

Instead of deleting the whole set of entries, we decided on taking another path and use the PowerShell script provided by user Paul Boerefijn CCS which removes the firewall rules and keeps a set of unique rules. The process was going to take over 15hrs to remove 12,000 inbound rules and we don’t know how long it was going to take to remove the outbound rules. So instead we used a different script found on stackoverflow which rather than using the “Remove-NetFirewallRule” PowerShell command it removed the rules directly from within the registry with the “Remove-ItemProperty” command which sped up the process and all 30,000 rules were deleted in 1.5Hrs. The script used is available below with some minor additions

NOTE Make sure that you change the Rule2 deletion line to match the correct registry path depending on which windows server version you are running it on. These are indicated in the script

#Script thanks to user js2010
#source https://stackoverflow.com/a/40915201
#added registry paths notes
$profiles = get-wmiobject -class win32_userprofile

Write-Host "Getting Firewall Rules"

# deleting rules with no owner would be disastrous
$Rules = Get-NetFirewallRule -All | 
  Where-Object {$profiles.sid -notcontains $_.owner -and $_.owner }

Write-Host "Getting Firewall Rules from ConfigurableServiceStore Store"

$rules2 = Get-NetFirewallRule -All -PolicyStore ConfigurableServiceStore | 
  Where-Object { $profiles.sid -notcontains $_.owner -and $_.owner }

$total = $rules.count + $rules2.count
Write-Host "Deleting" $total "Firewall Rules:" -ForegroundColor Green

$result = measure-command {

  # tracking
  $start = Get-Date; $i = 0.0 ; 
  
  foreach($rule in $rules){

    # action
    remove-itemproperty -path "HKLM:\System\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\FirewallRules" -name $rule.name

    # progress
    $i = $i + 1.0
    $prct = $i / $total * 100.0
    $elapsed = (Get-Date) - $start; 
    $totaltime = ($elapsed.TotalSeconds) / ($prct / 100.0)
    $remain = $totaltime - $elapsed.TotalSeconds
    $eta = (Get-Date).AddSeconds($remain)

    # display
    $prctnice = [math]::round($prct,2) 
    $elapsednice = $([string]::Format("{0:d2}:{1:d2}:{2:d2}", $elapsed.hours, $elapsed.minutes, $elapsed.seconds))
    $speed = $i/$elapsed.totalminutes
    $speednice = [math]::round($speed,2) 
    Write-Progress -Activity "Deleting rules ETA $eta elapsed $elapsednice loops/min $speednice" -Status "$prctnice" -PercentComplete $prct -secondsremaining $remain
  }


  # tracking
  # $start = Get-Date; $i = 0 ; $total = $rules2.Count

  foreach($rule2 in $rules2) {

    # action
#change path according to the Windows Server version used:
#Windows Server 2019 Path = "HKLM:\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\RestrictedServices\AppIso\FirewallRules"
#Windows Server 2016 Path = "HKLM:\System\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\RestrictedServices\Configurable\System"
    
    remove-itemproperty -path "HKLM:\System\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\RestrictedServices\Configurable\System" -name $rule2.name

    # progress
    $i = $i + 1.0
    $prct = $i / $total * 100.0
    $elapse = (Get-Date) - $start; 
    $totaltime = ($elapsed.TotalSeconds) / ($prct / 100.0)
    $remain = $totaltime - $elapsed.TotalSeconds
    $eta = (Get-Date).AddSeconds($remain)

    # display
    $prctnice = [math]::round($prct,2) 
    $elapsednice = $([string]::Format("{0:d2}:{1:d2}:{2:d2}", $elapsed.hours, $elapsed.minutes, $elapsed.seconds))
    $speed = $i/$elapsed.totalminutes
    $speednice = [math]::round($speed,2) 
    Write-Progress -Activity "Deleting rules2 ETA $eta elapsed $elapsednice loops/min $speednice" -Status "$prctnice" -PercentComplete $prct -secondsremaining $remain
  }
}

$end = get-date
write-host end $end 
write-host eta $eta

write-host $result.minutes min $result.seconds sec

Once the script completes, the rules are removed and you will notice that the Windows Defender Firewall with Advanced Security window would open normally.

Script Output

Both scripts catered to avoid deleting the rules which had no owner set in the properties. Deleting these rules could case problems.

The purpose of this blog post is to try and consolidate all the information we found to resolve the issue. A big thanks goes to all the contributors in the different forums.

Hope you find it useful.


2 Comments

  • Hello. Thank a lot for your web site. I have the same issue on RDS ferme 2019 : long black screen on logon and start menu doe’nt work.
    I apply script. Durring 3 hours and more 15000 registry entry delete. But after, I have still issue with start menu. Have you an idea ?

    • Hi,
      in some cases I read that clearing the registry manually solved the issue.
      Also make sure that you applied the registry fixes manually to prevent this from happening again.

Post a Comment

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.

  • Free Advertisement

    hostifi.net
  • Microsoft Office 365 Backup
  • Advertisements
  • Google Ads

  • Connect with me

  • Site Menu

  • Follow me on Twitter