Terminal Services to Remote Desktop Services Migration Guide

Tyler Maginnis | January 15, 2024

Terminal ServicesRDSRemote DesktopMigrationWindows Server 2022Legacy SystemsWindows Server 2003

Need Professional Windows Server 2003?

Get expert assistance with your windows server 2003 implementation and management. Tyler on Tech Louisville provides priority support for Louisville businesses.

Same-day service available for Louisville area

Terminal Services to Remote Desktop Services Migration Guide

Critical Notice

⚠️ Windows Server 2003 Terminal Services lacks modern security features and is vulnerable to numerous exploits. Immediate migration to RDS on Windows Server 2022 is critical.

Overview

Terminal Services in Windows Server 2003 was the predecessor to modern Remote Desktop Services (RDS). This guide provides comprehensive strategies for migrating from Terminal Services to RDS while maintaining user productivity and data integrity.

Understanding the Differences

Terminal Services (2003) vs RDS (2022)

Feature Terminal Services 2003 RDS 2022
Security Basic RDP encryption Advanced encryption, MFA support
RemoteApp Not available Full application virtualization
Connection Broker Basic load balancing Advanced broker with HA
Gateway Not available Secure HTTPS gateway
Web Access Limited Full HTML5 support
GPU Support None RemoteFX, GPU passthrough
Multi-monitor Limited Full support

Pre-Migration Assessment

1. Terminal Services Inventory

@echo off
:: TSInventory.bat - Document Terminal Services configuration
echo Terminal Services Inventory > TS_Inventory.txt
echo Generated: %date% %time% >> TS_Inventory.txt
echo ================================ >> TS_Inventory.txt

:: Server configuration
echo. >> TS_Inventory.txt
echo Server Configuration: >> TS_Inventory.txt
wmic os get Caption, ServicePackMajorVersion, TotalVisibleMemorySize /format:list >> TS_Inventory.txt

:: Terminal Services settings
echo. >> TS_Inventory.txt
echo Terminal Services Configuration: >> TS_Inventory.txt
reg query "HKLM\SYSTEM\CurrentControlSet\Control\Terminal Server" /s >> TS_Inventory.txt

:: Licensing configuration
echo. >> TS_Inventory.txt
echo Licensing Information: >> TS_Inventory.txt
wmic path Win32_TSLicenseServer get LicenseServer >> TS_Inventory.txt

echo Inventory saved to TS_Inventory.txt

2. User Session Analysis

' AnalyzeTSSessions.vbs - Analyze Terminal Services usage
Set objWMI = GetObject("winmgmts:\\.\root\cimv2")
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objFile = objFSO.CreateTextFile("TSSessionAnalysis.csv", True)

' Write header
objFile.WriteLine "Date,Time,Active Sessions,Total Users,Peak Memory,Avg Session Time"

' Collect data for analysis
For i = 1 To 7 ' 7 days of data
    Set colSessions = objWMI.ExecQuery("SELECT * FROM Win32_TSSession")
    activeSessions = colSessions.Count

    totalMemory = 0
    totalTime = 0
    userCount = 0

    For Each objSession In colSessions
        If objSession.SessionState = 0 Then ' Active
            userCount = userCount + 1
            totalMemory = totalMemory + objSession.WorkingSetSize
            totalTime = totalTime + objSession.ConnectTime
        End If
    Next

    If userCount > 0 Then
        avgMemory = totalMemory / userCount
        avgTime = totalTime / userCount
    Else
        avgMemory = 0
        avgTime = 0
    End If

    objFile.WriteLine Date & "," & Time & "," & activeSessions & "," & _
                     userCount & "," & avgMemory & "," & avgTime

    WScript.Sleep 3600000 ' Wait 1 hour
Next

objFile.Close
WScript.Echo "Session analysis saved to TSSessionAnalysis.csv"

3. Application Compatibility Assessment

# AssessAppCompatibility.ps1 - Check application compatibility for RDS
$installedApps = Get-WmiObject Win32_Product | Select-Object Name, Version, Vendor

$compatibility = @()
foreach($app in $installedApps) {
    $appInfo = @{
        Name = $app.Name
        Version = $app.Version
        Vendor = $app.Vendor
        RDSCompatible = "Unknown"
        RemoteAppCapable = "Unknown"
        Notes = ""
    }

    # Check known compatibility issues
    switch -Wildcard ($app.Name) {
        "*Office 2003*" { 
            $appInfo.RDSCompatible = "No"
            $appInfo.Notes = "Upgrade to Office 365"
        }
        "*Internet Explorer 6*" {
            $appInfo.RDSCompatible = "No"
            $appInfo.Notes = "Use Edge or Chrome"
        }
        "*Adobe*" {
            $appInfo.RemoteAppCapable = "Yes"
        }
    }

    $compatibility += New-Object PSObject -Property $appInfo
}

$compatibility | Export-Csv -Path "AppCompatibility.csv" -NoTypeInformation
Write-Host "Application compatibility report saved"

Migration Architecture

1. RDS Farm Design

# DesignRDSFarm.ps1 - Generate RDS farm design based on current load
$currentSessions = (Get-WmiObject Win32_TSSession).Count
$peakSessions = $currentSessions * 1.5 # 50% growth buffer

# Calculate required servers
$sessionsPerServer = 50 # Recommended for good performance
$requiredServers = [Math]::Ceiling($peakSessions / $sessionsPerServer)

# Design output
$design = @"
RDS Farm Design Recommendations
================================
Current Peak Sessions: $currentSessions
Projected Peak: $peakSessions
Sessions per Server: $sessionsPerServer
Required RD Session Hosts: $requiredServers

Recommended Architecture:
- RD Connection Brokers: 2 (HA)
- RD Session Hosts: $requiredServers
- RD Gateway Servers: 2 (NLB)
- RD Web Access Servers: 2 (NLB)
- RD Licensing Server: 1

Hardware Requirements per Session Host:
- CPU: 8 cores minimum
- RAM: $(4 + ($sessionsPerServer * 0.5))GB
- Storage: 100GB OS + User profiles
- Network: 1Gbps minimum
"@

$design | Out-File "RDS_Farm_Design.txt"
Write-Host "RDS farm design saved to RDS_Farm_Design.txt"

2. Network Requirements

@echo off
:: NetworkRequirements.bat - Calculate network requirements

echo RDS Network Requirements > NetworkReqs.txt
echo ======================= >> NetworkReqs.txt

:: Current bandwidth usage
echo. >> NetworkReqs.txt
echo Current TS Bandwidth Usage: >> NetworkReqs.txt
netstat -e >> NetworkReqs.txt

:: Calculate RDS requirements
echo. >> NetworkReqs.txt
echo Estimated RDS Bandwidth Requirements: >> NetworkReqs.txt
echo - Basic RDP: 30-60 Kbps per user >> NetworkReqs.txt
echo - With graphics: 100-200 Kbps per user >> NetworkReqs.txt
echo - RemoteFX: 500+ Kbps per user >> NetworkReqs.txt
echo - Printing: Additional 100 Kbps per active print job >> NetworkReqs.txt

:: Firewall ports needed
echo. >> NetworkReqs.txt
echo Required Firewall Ports: >> NetworkReqs.txt
echo - RDP: TCP 3389 >> NetworkReqs.txt
echo - RD Gateway: TCP 443 (HTTPS) >> NetworkReqs.txt
echo - RD Web Access: TCP 443 (HTTPS) >> NetworkReqs.txt
echo - RD Licensing: TCP 135, 49152-65535 >> NetworkReqs.txt

type NetworkReqs.txt

Migration Process

Phase 1: Infrastructure Preparation

1. Deploy RDS Infrastructure

# DeployRDSInfra.ps1 - Deploy RDS infrastructure components
Import-Module RemoteDesktop

# Add RDS roles
$servers = @{
    ConnectionBroker = "RDCB01", "RDCB02"
    WebAccess = "RDWA01", "RDWA02"
    Gateway = "RDGW01", "RDGW02"
    SessionHost = "RDSH01", "RDSH02", "RDSH03"
    Licensing = "RDLIC01"
}

# Install Connection Broker (Primary)
Add-WindowsFeature -Name RDS-Connection-Broker -ComputerName $servers.ConnectionBroker[0]

# Create new deployment
New-RDSessionDeployment -ConnectionBroker $servers.ConnectionBroker[0] `
                       -WebAccessServer $servers.WebAccess[0] `
                       -SessionHost $servers.SessionHost[0]

# Add additional servers
foreach($sh in $servers.SessionHost[1..2]) {
    Add-RDServer -Server $sh -Role "RDS-RD-SERVER" `
                 -ConnectionBroker $servers.ConnectionBroker[0]
}

# Configure HA for Connection Broker
Add-RDServer -Server $servers.ConnectionBroker[1] -Role "RDS-CONNECTION-BROKER" `
             -ConnectionBroker $servers.ConnectionBroker[0]

Write-Host "RDS infrastructure deployed"

2. Configure RD Gateway

# ConfigureRDGateway.ps1 - Configure RD Gateway for secure access
$gatewayServer = "RDGW01.domain.local"

# Install RD Gateway role
Install-WindowsFeature -Name RDS-Gateway -IncludeManagementTools -ComputerName $gatewayServer

# Configure RD Gateway
$gatewayConfig = @{
    GatewayName = $gatewayServer
    SSLCertificate = "CN=remote.company.com"
    AuthenticationMethod = "NTLM"
    ResourceAuthorizationPolicy = "RDG_AllowAll"
}

# Create CAP (Connection Authorization Policy)
New-Item -Path "RDS:\GatewayServer\CAP" -Name "CAP_AllUsers" -UserGroups "Domain Users" `
         -AuthMethod 1 -ComputerGroupType 2

# Create RAP (Resource Authorization Policy)  
New-Item -Path "RDS:\GatewayServer\RAP" -Name "RAP_AllComputers" -UserGroups "Domain Users" `
         -ComputerGroup "Domain Computers"

Write-Host "RD Gateway configured"

Phase 2: Application Migration

1. Prepare Applications for RemoteApp

# PrepareRemoteApps.ps1 - Configure applications for RemoteApp publishing
$sessionHost = "RDSH01.domain.local"
$connectionBroker = "RDCB01.domain.local"

# Get installed applications
$apps = Get-WmiObject Win32_Product -ComputerName $sessionHost | 
        Where-Object {$_.Name -notlike "*Update*" -and $_.Name -notlike "*Driver*"}

# Create RemoteApp programs
foreach($app in $apps) {
    # Find executable
    $exePath = Get-ChildItem "${env:ProgramFiles}\$($app.Name)" -Filter "*.exe" -Recurse |
               Select-Object -First 1

    if($exePath) {
        try {
            New-RDRemoteApp -CollectionName "Business Apps" `
                           -DisplayName $app.Name `
                           -FilePath $exePath.FullName `
                           -ConnectionBroker $connectionBroker

            Write-Host "Published RemoteApp: $($app.Name)"
        } catch {
            Write-Warning "Failed to publish: $($app.Name)"
        }
    }
}

2. User Profile Migration

@echo off
:: MigrateUserProfiles.bat - Migrate user profiles from TS to RDS

set SourcePath=\\OldTSServer\Profiles$
set DestPath=\\FileServer\RDSProfiles$

echo Migrating user profiles...

:: Create profile disk location
mkdir "%DestPath%"

:: Set permissions
icacls "%DestPath%" /grant:r "Domain Users:(OI)(CI)M" /T

:: Copy profiles with robocopy
robocopy "%SourcePath%" "%DestPath%" /E /COPYALL /R:3 /W:10 /MT:16 /LOG:ProfileMigration.log

:: Convert to User Profile Disks (UPD)
powershell -Command "& {
    $profiles = Get-ChildItem '%DestPath%'
    foreach($profile in $profiles) {
        $vhdPath = '%DestPath%\' + $profile.Name + '.vhdx'
        New-VHD -Path $vhdPath -SizeBytes 10GB -Dynamic
        Mount-VHD -Path $vhdPath
        Initialize-Disk -Number (Get-VHD -Path $vhdPath).DiskNumber -PartitionStyle MBR
        New-Partition -DiskNumber (Get-VHD -Path $vhdPath).DiskNumber -UseMaximumSize |
            Format-Volume -FileSystem NTFS -Confirm:$false
        Dismount-VHD -Path $vhdPath
    }
}"

echo Profile migration complete.

Phase 3: Client Configuration

1. Deploy New RDP Files

' DeployRDPFiles.vbs - Create and deploy RDP connection files
Dim objFSO, objFile
Set objFSO = CreateObject("Scripting.FileSystemObject")

' RDS farm connection
Set objFile = objFSO.CreateTextFile("CompanyRDS.rdp", True)
objFile.WriteLine "full address:s:remote.company.com"
objFile.WriteLine "gatewayhostname:s:remote.company.com"
objFile.WriteLine "gatewayusagemethod:i:1"
objFile.WriteLine "gatewaycredentialssource:i:0"
objFile.WriteLine "workspace id:s:remote.company.com"
objFile.WriteLine "use multimon:i:1"
objFile.WriteLine "screen mode id:i:2"
objFile.WriteLine "audiomode:i:0"
objFile.WriteLine "redirectprinters:i:1"
objFile.WriteLine "redirectclipboard:i:1"
objFile.WriteLine "redirectsmartcards:i:1"
objFile.WriteLine "devicestoredirect:s:*"
objFile.WriteLine "drivestoredirect:s:*"
objFile.WriteLine "loadbalanceinfo:s:tsv://MS Terminal Services Plugin.1.BusinessApps"
objFile.Close

' Deploy to users
Set objNetwork = CreateObject("WScript.Network")
userDesktop = "C:\Users\" & objNetwork.UserName & "\Desktop\"
objFSO.CopyFile "CompanyRDS.rdp", userDesktop

WScript.Echo "RDP file deployed to desktop"

2. Update Group Policy

# UpdateRDSPolicy.ps1 - Configure RDS client settings via GPO
Import-Module GroupPolicy

$gpoName = "RDS Client Configuration"
New-GPO -Name $gpoName

# Configure RDP settings
Set-GPRegistryValue -Name $gpoName -Key "HKCU\Software\Policies\Microsoft\Windows NT\Terminal Services" `
                    -ValueName "AuthenticationLevel" -Type DWord -Value 2

Set-GPRegistryValue -Name $gpoName -Key "HKCU\Software\Policies\Microsoft\Windows NT\Terminal Services" `
                    -ValueName "RedirectDrives" -Type DWord -Value 1

Set-GPRegistryValue -Name $gpoName -Key "HKCU\Software\Policies\Microsoft\Windows NT\Terminal Services" `
                    -ValueName "RedirectPrinters" -Type DWord -Value 1

# Set default RD Gateway
Set-GPRegistryValue -Name $gpoName -Key "HKCU\Software\Policies\Microsoft\Windows NT\Terminal Services" `
                    -ValueName "DefaultTSGateway" -Type String -Value "remote.company.com"

# Link to domain
New-GPLink -Name $gpoName -Target "DC=company,DC=local"

Write-Host "RDS client GPO created and linked"

Security Hardening

1. RDS Security Configuration

# SecureRDS.ps1 - Apply security hardening to RDS deployment

# Configure SSL/TLS
$sessionHosts = Get-RDServer -Role "RDS-RD-SERVER"
foreach($server in $sessionHosts) {
    # Force TLS 1.2
    Set-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Control\Terminal Server\WinStations\RDP-Tcp" `
                     -Name "SecurityLayer" -Value 2 -ComputerName $server.Server

    Set-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Control\Terminal Server\WinStations\RDP-Tcp" `
                     -Name "MinEncryptionLevel" -Value 3 -ComputerName $server.Server
}

# Configure NLA
Set-RDSessionHost -SessionHost $sessionHosts.Server -NewConnectionAllowed $true `
                  -AuthenticateUsingNLA $true

# Set session limits
$collectionName = "Business Apps"
Set-RDSessionCollectionConfiguration -CollectionName $collectionName `
    -IdleSessionLimitMin 30 `
    -DisconnectedSessionLimitMin 60 `
    -MaxSessionLimit 480

Write-Host "Security hardening applied"

2. Multi-Factor Authentication

# ConfigureMFA.ps1 - Configure MFA for RDS
# Example using Azure MFA

# Install NPS extension
$url = "https://download.microsoft.com/download/NpsExtnForAzureMFA.exe"
Invoke-WebRequest -Uri $url -OutFile "NpsExtnForAzureMFA.exe"
Start-Process -FilePath "NpsExtnForAzureMFA.exe" -ArgumentList "/quiet" -Wait

# Configure NPS for RD Gateway
Import-Module NPS
New-NpsRadiusClient -Name "RDGateway" -Address "10.0.0.10" -SharedSecret "ComplexSecret123!"

# Create connection request policy
$policy = @{
    Name = "RDS_MFA_Policy"
    Conditions = @{
        NASPortType = "Virtual"
        CalledStationId = "remote.company.com"
    }
    AuthenticationMethods = "MSCHAP-v2"
    AuthenticationProvider = "Azure MFA"
}

New-NpsConnectionRequestPolicy @policy

Write-Host "MFA configuration complete"

Performance Optimization

1. RDS Performance Tuning

# OptimizeRDSPerformance.ps1 - Optimize RDS performance settings

$sessionHosts = Get-RDServer -Role "RDS-RD-SERVER"

foreach($server in $sessionHosts.Server) {
    # Configure RemoteFX
    Set-VMRemoteFX3dVideoAdapter -VMName $server -Enable $true

    # Set graphics optimization
    Invoke-Command -ComputerName $server -ScriptBlock {
        # Disable visual effects
        Set-ItemProperty -Path "HKCU:\Software\Microsoft\Windows\CurrentVersion\Explorer\VisualEffects" `
                         -Name "VisualFXSetting" -Value 2

        # Configure RDP compression
        Set-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services" `
                         -Name "CompressLevel" -Value 2

        # Enable UDP for RDP
        Set-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services" `
                         -Name "SelectTransport" -Value 0
    }
}

# Configure fair share CPU scheduling
Set-RDSessionHost -SessionHost $sessionHosts.Server -EnableFairShareCPUScheduling $true

Write-Host "Performance optimization complete"

2. Monitor Performance

# MonitorRDSPerformance.ps1 - Real-time RDS performance monitoring
$counters = @(
    "\Terminal Services\Active Sessions",
    "\Terminal Services\Total Sessions",
    "\Terminal Services Session(*)\% Processor Time",
    "\Terminal Services Session(*)\Working Set",
    "\RemoteFX Graphics(*)\Frames Skipped/Second",
    "\Processor(_Total)\% Processor Time",
    "\Memory\Available MBytes"
)

while($true) {
    Clear-Host
    Write-Host "RDS Performance Monitor - $(Get-Date)" -ForegroundColor Green
    Write-Host "="*50

    foreach($counter in $counters) {
        try {
            $data = Get-Counter -Counter $counter -ErrorAction SilentlyContinue
            foreach($sample in $data.CounterSamples) {
                Write-Host "$($sample.Path): $([math]::Round($sample.CookedValue, 2))"
            }
        } catch {
            Write-Host "$counter: Unable to read" -ForegroundColor Red
        }
    }

    Start-Sleep -Seconds 5
}

Testing and Validation

1. Automated Testing Script

# TestRDSDeployment.ps1 - Comprehensive RDS testing
$testResults = @()

# Test RD Gateway connectivity
$gatewayTest = Test-NetConnection -ComputerName "remote.company.com" -Port 443
$testResults += [PSCustomObject]@{
    Test = "RD Gateway Connectivity"
    Result = $gatewayTest.TcpTestSucceeded
    Details = $gatewayTest.RemoteAddress
}

# Test RD Web Access
try {
    $webResponse = Invoke-WebRequest -Uri "https://remote.company.com/RDWeb" -UseBasicParsing
    $testResults += [PSCustomObject]@{
        Test = "RD Web Access"
        Result = $webResponse.StatusCode -eq 200
        Details = $webResponse.StatusDescription
    }
} catch {
    $testResults += [PSCustomObject]@{
        Test = "RD Web Access"
        Result = $false
        Details = $_.Exception.Message
    }
}

# Test RemoteApp
$remoteApps = Get-RDRemoteApp -ConnectionBroker "RDCB01.domain.local"
foreach($app in $remoteApps) {
    $testResults += [PSCustomObject]@{
        Test = "RemoteApp: $($app.DisplayName)"
        Result = $app.ShowInWebAccess
        Details = $app.FilePath
    }
}

$testResults | Format-Table -AutoSize
$testResults | Export-Csv -Path "RDSTestResults.csv" -NoTypeInformation

2. User Load Testing

# LoadTestRDS.ps1 - Simulate user load for testing
param(
    [int]$NumberOfUsers = 50,
    [int]$DurationMinutes = 60
)

$credential = Get-Credential -Message "Enter test user credentials"
$server = "remote.company.com"

1..$NumberOfUsers | ForEach-Object -Parallel {
    $session = New-PSSession -ComputerName $using:server -Credential $using:credential

    # Simulate user activity
    $endTime = (Get-Date).AddMinutes($using:DurationMinutes)
    while((Get-Date) -lt $endTime) {
        # Open application
        Invoke-Command -Session $session -ScriptBlock {
            Start-Process "notepad.exe"
            Start-Sleep -Seconds 30
            Stop-Process -Name "notepad" -Force
        }

        Start-Sleep -Seconds (Get-Random -Minimum 60 -Maximum 300)
    }

    Remove-PSSession $session
} -ThrottleLimit 10

Write-Host "Load test completed"

Cutover Process

1. Cutover Checklist

# RDS Migration Cutover Checklist

## Pre-Cutover (T-7 days)
- [ ] Complete all testing
- [ ] Verify backup systems
- [ ] Train help desk staff
- [ ] Communicate to users
- [ ] Schedule maintenance window

## Cutover Day (T-0)
- [ ] 1. Disable new connections to Terminal Services
- [ ] 2. Wait for existing sessions to complete
- [ ] 3. Final profile sync
- [ ] 4. Update DNS records
- [ ] 5. Enable RDS farm
- [ ] 6. Test with pilot users
- [ ] 7. Open for all users
- [ ] 8. Monitor performance

## Post-Cutover (T+1 to T+7)
- [ ] Monitor error logs
- [ ] Address user issues
- [ ] Performance tuning
- [ ] Document lessons learned
- [ ] Decommission old servers

2. Rollback Plan

@echo off
:: RDSRollback.bat - Emergency rollback procedure

echo RDS MIGRATION ROLLBACK
echo ====================

set /p confirm="Rollback to Terminal Services? (Y/N): "
if /i not "%confirm%"=="Y" exit

:: Disable RDS farm
echo Disabling RDS farm...
powershell -Command "Set-RDSessionHost -SessionHost RDSH01,RDSH02,RDSH03 -NewConnectionAllowed $false"

:: Re-enable Terminal Services
echo Enabling Terminal Services...
sc \\OldTSServer config TermService start= auto
sc \\OldTSServer start TermService

:: Update DNS
echo Updating DNS records...
dnscmd /recorddelete company.local remote A /f
dnscmd /recordadd company.local remote A 10.0.0.5

:: Notify users
msg * "Terminal Services has been restored. Please reconnect to your sessions."

echo Rollback complete.

Post-Migration Tasks

1. Decommission Terminal Services

# DecommissionTS.ps1 - Safely decommission Terminal Services
$tsServer = "OldTSServer"

# Export final configuration
$exportPath = "\\FileServer\Archive\TS_Final_Config"
New-Item -Path $exportPath -ItemType Directory -Force

# Export registry
reg export "\\$tsServer\HKLM\SYSTEM\CurrentControlSet\Control\Terminal Server" `
          "$exportPath\TS_Registry.reg"

# Archive user data
robocopy "\\$tsServer\C$\Documents and Settings" `
         "$exportPath\UserData" /E /COPYALL /R:3 /W:10

# Disable services
Invoke-Command -ComputerName $tsServer -ScriptBlock {
    Stop-Service TermService
    Set-Service TermService -StartupType Disabled

    # Remove from domain
    Remove-Computer -Force -Restart
}

Write-Host "Terminal Services decommissioned"

2. Documentation Update

# GenerateDocumentation.ps1 - Generate RDS documentation
$doc = @"
# RDS Environment Documentation

## Infrastructure
$(Get-RDServer | Format-Table -AutoSize | Out-String)

## Collections
$(Get-RDSessionCollection | Format-Table -AutoSize | Out-String)

## Published Applications
$(Get-RDRemoteApp | Format-Table -AutoSize | Out-String)

## Security Configuration
- NLA Required: Yes
- Encryption Level: High
- MFA Enabled: Yes
- Gateway URL: remote.company.com

## Support Procedures
1. User cannot connect: Check RD Gateway logs
2. Application issues: Verify RemoteApp publishing
3. Performance issues: Check session host resources

## Monitoring
- RDS Performance Counters configured
- Alerts configured for high CPU/Memory
- Daily health reports enabled
"@

$doc | Out-File "RDS_Documentation.md"
Write-Host "Documentation generated"

Conclusion

Migrating from Terminal Services to RDS provides significant improvements in security, functionality, and user experience. Following this guide ensures a smooth transition while minimizing disruption to users.

Support Information

  • Tyler on Tech Louisville: (202) 948-8888
  • 24/7 RDS Support: Available
  • Email: rds-support@tylerontechlouisville.com

Last Updated: January 2024
Author: Tyler Maginnis, Tyler on Tech Louisville