How to Set Up Remote Desktop Services on Windows Server 2019
Remote Desktop Services (RDS) on Windows Server 2019 provides a platform for delivering virtual desktops, session-based desktops, and RemoteApp programs to users. RDS is the technology behind Windows Virtual Desktop, server-based computing, and centralized application delivery. This guide covers deploying a standard RDS scenario including the RD Session Host, RD Connection Broker, RD Web Access, and RD Licensing roles.
RDS Role Components Overview
A full RDS deployment involves several role services. The RD Session Host (RDSH) hosts the Windows sessions where users run desktops and applications. The RD Connection Broker (RDCB) manages connections, load-balances between multiple session hosts, and enables reconnection to existing sessions. The RD Web Access (RDWA) provides a web portal at https://server/RDWeb where users can access RemoteApp programs and session desktops through a browser. The RD Licensing (RDLS) manages Remote Desktop Client Access Licenses (RDS CALs). The RD Gateway (RDGW) enables secure remote access over HTTPS without a VPN.
Quick Deployment Using Server Manager
For small deployments on a single server, use the Quick Start wizard. This installs all required roles on one machine. For production environments, distribute roles across multiple servers. The deployment must be initiated from a domain-joined server using a domain admin account:
# Install all RDS role services for a quick single-server deployment
Install-WindowsFeature `
-Name RDS-RD-Server, RDS-Connection-Broker, RDS-Web-Access, RDS-Licensing `
-IncludeManagementTools `
-Restart
Creating an RDS Deployment
After installing the role services, create the RDS deployment. This associates the role services and creates the management framework in Server Manager’s RDS section:
Import-Module RemoteDesktop
# Create a new RDS deployment
# Replace server names with your actual server FQDNs
New-RDSessionDeployment `
-ConnectionBroker "rdcb01.corp.example.com" `
-WebAccessServer "rdwa01.corp.example.com" `
-SessionHost "rdsh01.corp.example.com"
# Verify the deployment
Get-RDServer -ConnectionBroker "rdcb01.corp.example.com"
Configuring RD Licensing
RDS requires CALs for each user or device connecting to session hosts. Per User CALs allow a single user to connect from any device. Per Device CALs are assigned to a device and allow any user on that device to connect. Configure the licensing server and mode:
# Add the licensing server to the deployment
Add-RDServer `
-Server "rdls01.corp.example.com" `
-Role RDS-LICENSING `
-ConnectionBroker "rdcb01.corp.example.com"
# Configure the licensing mode (PerUser or PerDevice)
Set-RDLicenseConfiguration `
-LicenseServer "rdls01.corp.example.com" `
-Mode PerUser `
-ConnectionBroker "rdcb01.corp.example.com" `
-Force
# Activate the licensing server and install CALs via GUI:
# Server Manager > RDS > Licensing > License Manager
# Or via WMI:
$obj = Get-WmiObject -Namespace root/cimv2 -Class Win32_TSLicenseServer
$obj.ActivateServer()
# Check license server status
Get-RDLicenseConfiguration -ConnectionBroker "rdcb01.corp.example.com"
Creating Session Collections
Session collections define groups of RD Session Hosts and configure how users access desktops and applications. Create a collection for your users:
# Create a session collection for general users
New-RDSessionCollection `
-CollectionName "General Desktop" `
-CollectionDescription "General purpose Windows desktop for office users" `
-SessionHost "rdsh01.corp.example.com", "rdsh02.corp.example.com" `
-ConnectionBroker "rdcb01.corp.example.com"
# Configure collection properties
Set-RDSessionCollectionConfiguration `
-CollectionName "General Desktop" `
-ConnectionBroker "rdcb01.corp.example.com" `
-UserGroup "CORPRDS-Users" `
-MaxRedirectedMonitors 2 `
-ClientPrinterRedirected $true `
-ClientDeviceRedirectionOptions AudioVideoPlayBack, PlugAndPlayDevice
# View collection configuration
Get-RDSessionCollectionConfiguration `
-CollectionName "General Desktop" `
-ConnectionBroker "rdcb01.corp.example.com"
Publishing RemoteApp Programs
RemoteApp programs run on the session host but appear as if they are running locally on the user’s desktop. Publish frequently used applications without giving users a full desktop:
# Publish Microsoft Word as a RemoteApp
New-RDRemoteApp `
-Alias "Word" `
-DisplayName "Microsoft Word 2019" `
-FilePath "C:Program FilesMicrosoft OfficerootOffice16WINWORD.EXE" `
-ShowInWebAccess $true `
-CollectionName "General Desktop" `
-ConnectionBroker "rdcb01.corp.example.com"
# Publish a custom application
New-RDRemoteApp `
-Alias "ERPApp" `
-DisplayName "ERP Application" `
-FilePath "C:Program FilesERPerp.exe" `
-CommandLineSetting Require `
-RequiredCommandLine "/server=erpdb01" `
-ShowInWebAccess $true `
-CollectionName "General Desktop" `
-ConnectionBroker "rdcb01.corp.example.com"
# List all published RemoteApps
Get-RDRemoteApp -CollectionName "General Desktop" `
-ConnectionBroker "rdcb01.corp.example.com"
Configuring RD Gateway
RD Gateway allows users to connect to internal RDS resources securely over the internet using HTTPS (port 443), eliminating the need to expose RDP (port 3389) directly to the internet:
# Install the RD Gateway role service
Install-WindowsFeature RDS-Gateway -IncludeManagementTools
# Add gateway to deployment
Add-RDServer `
-Server "rdgw01.corp.example.com" `
-Role RDS-GATEWAY `
-ConnectionBroker "rdcb01.corp.example.com" `
-GatewayExternalFqdn "rdgateway.company.com"
# Create a Connection Authorization Policy (CAP) - who can use the gateway
New-Item -Path 'HKLM:SOFTWAREMicrosoftWindows NTCurrentVersionTSGatewayPoliciesCAPs' -Name "AllowAll" -Force | Out-Null
# Use the TS Gateway Manager or PowerShell module for CAP/RAP configuration
Import-Module TSGateway
# Add a CAP: allow domain users to connect
New-TSGatewayCAP `
-Name "Allow Domain Users" `
-UserGroupNames @("CORPDomain Users") `
-ComputerGroupPolicy AnyComputer `
-PasswordEnabled $true
Configuring User Profile Disks
User Profile Disks (UPDs) are VHD files stored on a file server that contain user profile data. They roam with the user across session hosts in a collection, ensuring settings and documents persist between sessions:
# Enable User Profile Disks for a collection
Set-RDSessionCollectionConfiguration `
-CollectionName "General Desktop" `
-ConnectionBroker "rdcb01.corp.example.com" `
-EnableUserProfileDisk $true `
-DiskPath "\fs01UserProfileDisks" `
-MaxUserProfileDiskSizeGB 20
# The share must exist and RDSH computer accounts need write access
# Create the share on the file server:
New-SmbShare -Name "UserProfileDisks" -Path "D:UPDs" -FullAccess "CORPRDSH Computers"
RDS Session Configuration and Limits
Configure session timeouts and limits to reclaim resources from disconnected or idle sessions:
# Set session time limits via Group Policy or registry
# Via registry on each RDSH:
# Disconnect idle sessions after 30 minutes
$RegPath = "HKLM:SOFTWAREPoliciesMicrosoftWindows NTTerminal Services"
Set-ItemProperty -Path $RegPath -Name "MaxIdleTime" -Value 1800000 -Type DWord
# Disconnect session after it has been active for 8 hours
Set-ItemProperty -Path $RegPath -Name "MaxConnectionTime" -Value 28800000 -Type DWord
# End disconnected sessions after 2 hours
Set-ItemProperty -Path $RegPath -Name "MaxDisconnectionTime" -Value 7200000 -Type DWord
# View current RDS sessions
query session /server:rdsh01
# or
Get-RDUserSession -ConnectionBroker "rdcb01.corp.example.com"
Monitoring RDS Capacity
Monitor session counts and server load to ensure the RDS environment is not over capacity:
# Get all active user sessions
Get-RDUserSession -ConnectionBroker "rdcb01.corp.example.com" | `
Select-Object UserName, HostServer, SessionState, IdleTime
# Get session host load information
Get-RDSessionHost -CollectionName "General Desktop" `
-ConnectionBroker "rdcb01.corp.example.com" | `
Select-Object SessionHost, NewConnectionAllowed, Sessions
# Log off a disconnected session remotely
Invoke-RDUserLogoff `
-HostServer "rdsh01.corp.example.com" `
-UnifiedSessionID 5 `
-Force
A properly deployed RDS environment provides users with a consistent, managed desktop experience regardless of their physical location or device. Size your RD Session Hosts with at least 2 GB of RAM per concurrent user for typical office workloads, ensure storage is fast (NVMe or SSD RAID), and use Network Policy Server to enforce health checks via NAP for connecting clients.