{"id":811,"date":"2026-10-11T13:00:00","date_gmt":"2026-10-11T13:00:00","guid":{"rendered":"https:\/\/vpslake.com\/blog\/?p=811"},"modified":"2026-10-11T13:00:00","modified_gmt":"2026-10-11T13:00:00","slug":"change-default-rdp-port-windows-server","status":"publish","type":"post","link":"https:\/\/vpslake.com\/blog\/2026\/10\/11\/change-default-rdp-port-windows-server\/","title":{"rendered":"How to Change the Default RDP Port on Windows Server"},"content":{"rendered":"\n<p class=\"wp-block-paragraph\">Change the default RDP port on Windows Server by staging a Windows Firewall rule, updating the RDP-Tcp registry value, and reconnecting through the new port. The PowerShell workflow takes about ten minutes and includes a rollback path if the first connection test fails.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Prerequisites<\/h2>\n\n\n\n<ul class=\"wp-block-list\">\n\n<li>A supported Windows Server installation with Remote Desktop already enabled. The procedure applies to Windows Server 2016, 2019, 2022, and 2025.<\/li>\n\n\n<li>An active RDP session using a local or domain account with local administrator rights. Keep the VPS control panel&#8217;s console or another out-of-band recovery method available in case the new rule is wrong.<\/li>\n\n\n<li>A new unused TCP port. This guide uses <code>3390<\/code>; choose another port if a service already owns it. Ports from <code>1024<\/code> through <code>49151<\/code> are usually a practical range for a manually assigned service port.<\/li>\n\n\n<li>The server&#8217;s public IP address or DNS name and a separate computer for testing the new endpoint.<\/li>\n\n\n<li>If you need an administrator-ready Windows environment, see <a href=\"https:\/\/vpslake.com\/buy-windows-rdp\">VPSLake Windows RDP hosting<\/a>.<\/li>\n\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">Step 1: Choose and check the new port<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Check the existing listener first so you do not move RDP onto a port already used by another service.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Open <strong>Windows PowerShell \u2192 Run as administrator<\/strong> and run this block. Replace <code>3390<\/code> with your chosen port before continuing.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>$RdpKey = 'HKLM:\\SYSTEM\\CurrentControlSet\\Control\\Terminal Server\\WinStations\\RDP-Tcp'\n$CurrentPort = (Get-ItemProperty -Path $RdpKey -Name PortNumber).PortNumber\n$NewPort = 3390\n[pscustomobject]@{ CurrentRdpPort = $CurrentPort; ProposedRdpPort = $NewPort }\nGet-NetTCPConnection -LocalPort $NewPort -ErrorAction SilentlyContinue | Select-Object LocalAddress,LocalPort,State,OwningProcess<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">The first line of output should show the current port, normally <code>3389<\/code>. The final command should return no rows; if it shows a listener, pick another port and run the check again. Windows&#8217; dynamic client port range commonly begins at <code>49152<\/code>, so do not blindly choose a number from that range just because it is high.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Step 2: Back up the RDP registry key<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">The listening port is stored as a registry value, so export that key before changing it.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Run this in the same elevated PowerShell window:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>$RdpKey = 'HKLM\\SYSTEM\\CurrentControlSet\\Control\\Terminal Server\\WinStations\\RDP-Tcp'\n$BackupPath = Join-Path ([Environment]::GetFolderPath('Desktop')) 'RDP-Tcp-backup.reg'\nreg.exe export $RdpKey $BackupPath \/y\nGet-Item $BackupPath | Select-Object FullName,Length<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">You should see <code>The operation completed successfully.<\/code> followed by a file on the administrator&#8217;s desktop. Microsoft documents the same listening-port registry location in its <a href=\"https:\/\/learn.microsoft.com\/en-us\/windows-server\/remote\/remote-desktop-services\/remotepc\/change-listening-port\" target=\"_blank\" rel=\"noopener\">Remote Desktop listening-port procedure<\/a>.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Step 3: Allow the new port through Windows Firewall<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Create the firewall exception before restarting RDP; this keeps the new listener reachable as soon as the service comes back.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">First identify the network profile used by the server&#8217;s active adapter:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Get-NetConnectionProfile | Select-Object InterfaceAlias,NetworkCategory,IPv4Connectivity<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">For an internet-facing VPS, the value is often <code>Public<\/code>. Use the exact <code>NetworkCategory<\/code> returned by your server in <code>$FirewallProfile<\/code> below. The two rules cover TCP and UDP because modern RDP can use both transports.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>$NewPort = 3390\n$FirewallProfile = 'Public'\n$TcpRule = \"RDP custom TCP $NewPort\"\n$UdpRule = \"RDP custom UDP $NewPort\"\nNew-NetFirewallRule -DisplayName $TcpRule -Direction Inbound -Action Allow -Protocol TCP -LocalPort $NewPort -Profile $FirewallProfile -Description 'Remote Desktop custom listening port'\nNew-NetFirewallRule -DisplayName $UdpRule -Direction Inbound -Action Allow -Protocol UDP -LocalPort $NewPort -Profile $FirewallProfile -Description 'Remote Desktop custom listening port'<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">The commands should create two enabled inbound allow rules. If the VPS provider exposes a separate perimeter firewall or security-group setting, allow the same TCP and UDP port there as well. The <a href=\"https:\/\/learn.microsoft.com\/en-us\/powershell\/module\/netsecurity\/new-netfirewallrule?view=windowsserver2025-ps\" target=\"_blank\" rel=\"noopener\">New-NetFirewallRule reference<\/a> explains the profile, protocol, and address filters used here.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">For a private administration network, tighten the rule instead of accepting every source. Add <code>-RemoteAddress TRUSTED_IP_OR_CIDR<\/code> to each command, using an administrator workstation address or an approved network such as <code>203.0.113.0\/24<\/code>.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Step 4: Change the RDP port and restart Windows<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Write the new number to <code>PortNumber<\/code>, then reboot so the Remote Desktop service binds to it.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>$RdpKey = 'HKLM:\\SYSTEM\\CurrentControlSet\\Control\\Terminal Server\\WinStations\\RDP-Tcp'\n$NewPort = 3390\nSet-ItemProperty -Path $RdpKey -Name PortNumber -Value ([int]$NewPort)\nGet-ItemProperty -Path $RdpKey -Name PortNumber | Select-Object PortNumber<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Expected output:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>PortNumber\n----------\n      3390<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Do not close your current session until the firewall rules are in place and you have recorded the new port. Restart the server when ready; the command will terminate the current RDP session:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Restart-Computer -Force<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">If you prefer the graphical route, open <strong>Windows key + R \u2192 regedit<\/strong>, then browse to <strong>HKEY_LOCAL_MACHINE \u2192 SYSTEM \u2192 CurrentControlSet \u2192 Control \u2192 Terminal Server \u2192 WinStations \u2192 RDP-Tcp<\/strong>. Open <code>PortNumber<\/code>, select <strong>Decimal<\/strong>, enter the new value, select <strong>OK<\/strong>, and restart the server. You still need to create the matching firewall rules from Step 3.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Verify the new RDP endpoint<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">After the reboot, use the server console if necessary and confirm that the registry and TCP listener agree:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>$NewPort = 3390\n$RdpKey = 'HKLM:\\SYSTEM\\CurrentControlSet\\Control\\Terminal Server\\WinStations\\RDP-Tcp'\nGet-ItemProperty -Path $RdpKey -Name PortNumber | Select-Object PortNumber\nGet-NetTCPConnection -LocalPort $NewPort -State Listen | Select-Object LocalAddress,LocalPort,State,OwningProcess<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">The port value should be <code>3390<\/code>, and the listener should report <code>Listen<\/code>. Next, test from a different computer, not from the server itself:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Test-NetConnection -ComputerName SERVER_IP -Port 3390<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Replace <code>SERVER_IP<\/code> with the public address or DNS name. A successful result includes:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>ComputerName     : SERVER_IP\nRemotePort       : 3390\nTcpTestSucceeded : True<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Open the RDP client with the port appended to the address:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>mstsc.exe \/v:SERVER_IP:3390<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">You can also enter <code>SERVER_IP:3390<\/code> in the <strong>Computer<\/strong> field of <strong>Remote Desktop Connection<\/strong>. Leave the original RDP rules alone until this new connection succeeds; changing the registry means nothing is listening on <code>3389<\/code>, but those rules may still be useful for other services or a rollback.<\/p>\n\n\n\n<aside class=\"vl-element vl-cta-banner\" aria-label=\"Need a Windows VPS?\">\n\t<div class=\"vl-cta-banner__content\">\n\t\t<p class=\"vl-cta-banner__eyebrow\">Secure Windows hosting<\/p>\n\t\t<h3 class=\"vl-cta-banner__title\">Need a Windows VPS?<\/h3>\n\t\t<p class=\"vl-cta-banner__text\">Get administrator access for RDP, firewall, and server configuration tasks.<\/p>\n\t<\/div>\n\t<a class=\"vl-cta-banner__button\" href=\"\/buy-windows-rdp\" aria-label=\"View Windows VPS\">View Windows VPS<\/a>\n<\/aside>\n\n\n\n<h2 class=\"wp-block-heading\">Troubleshooting<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">The new RDP connection times out<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">The firewall profile, provider firewall, or port may be wrong. From the server console, run <code>Get-NetConnectionProfile<\/code>, confirm that <code>$FirewallProfile<\/code> matched the active category, inspect both rules with <code>Get-NetFirewallRule -DisplayName 'RDP custom*'<\/code>, and confirm the upstream firewall allows the port.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><code>TcpTestSucceeded<\/code> is <code>False<\/code>, but the registry shows the new value<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">The Remote Desktop service may not have restarted, or another firewall rule may be blocking the path. Confirm <code>Get-NetTCPConnection -LocalPort 3390 -State Listen<\/code> returns a listener; if it does not, reboot again from the console and check the <strong>Remote Desktop Services<\/strong> service in <strong>Server Manager \u2192 Tools \u2192 Services<\/strong>.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">The chosen port is already in use<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">The check in Step 1 returned another listener. Select a different unused port, update <code>$NewPort<\/code> in the firewall and registry commands, and test that number before restarting. Do not take over a port used by a web server, database, VPN, or management agent.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">PowerShell says <code>Access is denied<\/code><\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">The registry and firewall commands require elevation. Close the window, search for <strong>Windows PowerShell<\/strong>, choose <strong>Run as administrator<\/strong>, and repeat the commands with an account that is a local administrator.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Hardening<\/h2>\n\n\n\n<ul class=\"wp-block-list\">\n\n<li>Restrict the new firewall rules to trusted source IP addresses or a VPN rather than exposing RDP to the entire internet.<\/li>\n\n\n<li>Keep Network Level Authentication enabled and use strong, unique administrator credentials. A nonstandard port changes automated scan noise but does not replace authentication or access controls.<\/li>\n\n\n<li>Save the exported registry file somewhere protected, and document the new port in your server inventory and monitoring checks.<\/li>\n\n\n<li>If the migration fails, use the server console to import the backup with <code>reg.exe import \"$env:USERPROFILE\\Desktop\\RDP-Tcp-backup.reg\"<\/code>, recreate the TCP and UDP rules for <code>3389<\/code>, and reboot.<\/li>\n\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">FAQ<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">Does changing the RDP port prevent brute-force attacks?<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">It can reduce the volume of automated scans that target the default port, but it is not a security boundary. Use Network Level Authentication, source-IP restrictions or a VPN, account lockout policies, and monitoring for meaningful protection.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">What port should I use instead of 3389?<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Choose an unused TCP port between <code>1024<\/code> and <code>49151<\/code> that is not assigned to another application. Check it locally before making the change, and avoid ports reserved for services your server will host later.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Do I need both TCP and UDP firewall rules?<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Allowing both on the same custom port lets RDP use either transport when supported. TCP is required for the basic connection; if you intentionally want TCP-only access, create only the TCP rule and confirm that your RDP client works as expected.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Can I connect without changing the RDP client settings?<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">No. Add the new port to the destination, such as <code>SERVER_IP:3390<\/code>, or launch <code>mstsc.exe \/v:SERVER_IP:3390<\/code>. A client that uses only the server address will continue trying the default port <code>3389<\/code>.<\/p>\n\n\n\n<script type=\"application\/ld+json\">{\"@context\": \"https:\/\/schema.org\", \"@type\": \"FAQPage\", \"mainEntity\": [{\"@type\": \"Question\", \"name\": \"Does changing the RDP port prevent brute-force attacks?\", \"acceptedAnswer\": {\"@type\": \"Answer\", \"text\": \"It can reduce the volume of automated scans that target the default port, but it is not a security boundary. Use Network Level Authentication, source-IP restrictions or a VPN, account lockout policies, and monitoring for meaningful protection.\"}}, {\"@type\": \"Question\", \"name\": \"What port should I use instead of 3389?\", \"acceptedAnswer\": {\"@type\": \"Answer\", \"text\": \"Choose an unused TCP port between `1024` and `49151` that is not assigned to another application. Check it locally before making the change, and avoid ports reserved for services your server will host later.\"}}, {\"@type\": \"Question\", \"name\": \"Do I need both TCP and UDP firewall rules?\", \"acceptedAnswer\": {\"@type\": \"Answer\", \"text\": \"Allowing both on the same custom port lets RDP use either transport when supported. TCP is required for the basic connection; if you intentionally want TCP-only access, create only the TCP rule and confirm that your RDP client works as expected.\"}}, {\"@type\": \"Question\", \"name\": \"Can I connect without changing the RDP client settings?\", \"acceptedAnswer\": {\"@type\": \"Answer\", \"text\": \"No. Add the new port to the destination, such as `SERVER_IP:3390`, or launch `mstsc.exe \/v:SERVER_IP:3390`. A client that uses only the server address will continue trying the default port `3389`.\"}}]}<\/script>\n\n","protected":false},"excerpt":{"rendered":"How to change default RDP port on Windows Server with PowerShell, Windows Firewall, a registry backup, and a safe remote connection test from another device.","protected":false},"author":1,"featured_media":812,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"csco_singular_sidebar":"","csco_page_header_type":"","csco_page_load_nextpost":"","footnotes":""},"categories":[5,11],"tags":[38,32,37,42],"class_list":["post-811","post","type-post","status-publish","format-standard","has-post-thumbnail","category-guides","category-windows-server","tag-powershell","tag-rdp","tag-windows-firewall","tag-windows-server","cs-entry"],"_links":{"self":[{"href":"https:\/\/vpslake.com\/blog\/wp-json\/wp\/v2\/posts\/811","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/vpslake.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/vpslake.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/vpslake.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/vpslake.com\/blog\/wp-json\/wp\/v2\/comments?post=811"}],"version-history":[{"count":1,"href":"https:\/\/vpslake.com\/blog\/wp-json\/wp\/v2\/posts\/811\/revisions"}],"predecessor-version":[{"id":3041,"href":"https:\/\/vpslake.com\/blog\/wp-json\/wp\/v2\/posts\/811\/revisions\/3041"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/vpslake.com\/blog\/wp-json\/wp\/v2\/media\/812"}],"wp:attachment":[{"href":"https:\/\/vpslake.com\/blog\/wp-json\/wp\/v2\/media?parent=811"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/vpslake.com\/blog\/wp-json\/wp\/v2\/categories?post=811"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/vpslake.com\/blog\/wp-json\/wp\/v2\/tags?post=811"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}