How to transfer files to your Azure VM with no public open RDP port

Microsoft released Azure Bastion as a way to connect with a remote session into a virtual machine (VM) on Microsoft Azure, without needing to have the VM's port available on the internet. Now you can keep port 3389 closed in your Azure Security Group and even configure the VM without a public IP address. This is especially useful for VMs that are part of an application architecture but provide  services or data to other parts of the solution that are already inside Azure (or on-premises via a VPN connection), and the VM doesn't need to be publicly accessible – but you still need to manage it. The protocol is a common target for hacking attempts, including attempts to hijack disconnected sessions and brute-force attacks that repeatedly try to connect with incorrect user credentials. Microsoft recommends you isolate these kinds of management ports from the Internet, in our Best practices for defending Azure Virtual Machines.

Instead, the connection to your VM can be made through an Azure Bastion host via your web browser, so your local machine is only connecting on the standard HTTPS port 443. Then, the Azure Bastion host inside the same Azure virtual connects to the VM's RDP port. The downside to this is the browser-based remote session isn't capable of accessing your local computer's clipboard. That means you can't copy local files and paste them into your session to upload them to your VM, or vice versa. But wait – the native RDP client software on your Windows PC (known as MSTSC) does support clipboard access, but it's expecting that the VM will be answering connection requests via an open RDP port. What if we could somehow combine the two scenarios?

Introducing (in preview) Connecting to a VM using the native client.

With this configuration, we'll tell the native RDP client to “tunnel through” Azure Bastion, using an Azure CLI command. Let's learn how to configure it and how to use it!

The architecture of a native RDP client connection to an Azure VM via Azure Bastion.The architecture of a native RDP client connection to an Azure VM via Azure Bastion.


Your virtual machine in Microsoft Azure will not require a public IP address. You also do not need to have RDP allowed in the Azure Security Group.

Azure Network Security Group (NSG) inbound port rulesAzure Network Security Group (NSG) inbound port rules

You will however need to have RDP allowed in Windows in the VM's operating system. This is standard for connection via Azure Bastion anyway. Since we're blocking RDP at the network layer from outside of Azure and the VM only has a private IP address, only RDP connections initiated from inside Azure will be able to take advantage of this. But as a , you can add the Subnet IP address range of your Azure Bastion host in this rule, to allow only Bastion to be able to open this port on your VM.

Windows Firewall settings of the Azure VM operating system allowing RDPWindows settings of the Azure VM operating system allowing RDP

If you have an existing Azure Bastion host, you'll need to ensure it's using the Standard SKU Tier (not Basic) and there is a new checkbox to tick to allow Native client support (preview). You can access those settings from the Configuration blade of your Azure Bastion host from the Azure Portal. All Bastion hosts require a public IP address on creation, as that is how you connect to them from your local computer.


If you are creating a new Azure Bastion host, set the Tier to Standard and navigate to the Advanced tab to tick the Native client support (Preview) checkbox, before you click the Review + Create button. 


Note: If you have an existing VM but no Azure Bastion host yet, you can navigate to the VM, choose the Connect drop down menu, then select Bastion. That will bring up the Create Bastion page pre-filled with the name, resource group, virtual network and public IP address of your new Bastion host, based on the details of your existing VM. Once it has been deployed, you can then change the configuration setting to set the Tier to Standard and allow the native client support.   


On your local computer, you'll need to have Azure CLI installed from here.

If you're not familiar with Azure CLI, the installation adds Azure CLI commands that can then be used in the Windows Command Prompt, PowerShell or Windows Terminal. You won't see a new program called Azure CLI.
Note: This tunnelling capability is not supported in the Azure Cloud Shell you can run in your browser from the Azure Portal.

The connection process

Step 1: With your local command tool of choice (I use PowerShell), run the following commands to login to your Azure account and if you have more than one subscription, set the subscription where your VM is (you just need the subscription name):

az login
az account set --subscription "YourSubscriptionName"

Step 2: Next, you'll need to grab the resource ID of your VM, if you don't already know it, with the az vm list command. From the results, you want the part that starts with “/subscriptions/..” and ends with the VM name (e.g. /subscriptions/e1e10-597xyg-yyy-yyy-/resourceGroups/My-RG-01/providers/Microsoft.Compute/virtualMachines/My-VM-03).

az vm list --resource-group "YourResourceGroupName" --show-details

Step 3: Finally, you run the az network bastion rdp command, with the name of your Bastion host, the Resource Group name and your VM's resource ID:

az network bastion rdp --name "YourBastionName" --resource-group "ResourceGroupName" --target-resource-id "YourVMResourceId"

This will start the native RDP client on your local computer and make the connection to your Azure VM by tunnelling through the Bastion host. You won't be able to configure any of the usual RDP settings.

The file transfer experience

With this connection active and your RDP client showing your VM session, transferring files between your local computer and your VM is just done using copy & paste!

Possible error messages

If you try running this command in Azure Cloud Shell, you'll receive the error message “Platform is not supported for this command. Support platforms: Windows”. 

And if native client support is not enabled on your Bastion host, you'll receive the error “msrestazure.azure_exceptions.CloudError: Tunneling is disabled”


While I've written this from a Windows RDP client/ VM perspective, it also works with:
SSH to Windows or Linux (using the az network bastion ssh command)
And with non-Windows local computers and other native clients (not MSTSC), using the az network bastion tunnel command.

This feature is in preview, but we'd love to see you testing it and trying it out. Send us your feedback – how helpful is it to have native RDP support for file transfers, with the RDP port remaining closed to the Internet?

Learn more

Docs – Azure Bastion Frequently Asked Questions

MS Learn – Introduction to Azure Bastion

MS Learn – Connect to virtual machines through the Azure portal by using Azure Bastion

Azure Bastion – Connections with confidence


This article was originally published by Microsoft's Azure Blog. You can find the original article here.