Cloud Service RDP Configuration not available via portal

 

 

<Update March 2, 2015>

The ability to modify RDP plugin settings via the portal has been restored. I will leave this blog post up since the password encryption portion can still be valuable for people setting up RDP outside of the Visual Studio tools.

</Update>

 

 

There are 2 ways to enable RDP for a PaaS cloud service – via the CSPKG using the RemoteAccess plugin, or via the portal (or Powershell or REST API) using an extension. There was a recent change to the management portal that disabled the ability to configure the plugin style RDP settings after deployment. The error you get is:

“Failed to launch remote desktop configuration.”

And if you click Details you get:

“Remote Desktop is enabled for this deployment using the RemoteAccess module, which is specified in the ServiceDefinition.csdef file. To allow configuring Remote Desktop using the management portal, remove the RemoteAccess module and update the deployment. Learn More.”

image

image

    

The best solution is to remove the RDP plugin from the package, rebuild the package, and redeploy. This will let you enable RDP via the portal after deployment and manage the configuration in the portal. This also provides a more reliable RDP experience since this shifts the RDP functionality from a static feature in your CSPKG to an extension that can be managed and upgraded by the Azure guest agent. To disable RDP in your package you can right-click the cloud service project, select ‘Configure Remote Desktop’ and then uncheck the ‘Enable connections for all roles’ option.

image

 

However, modifying and then redeploying the package is not always a viable solution. For the scenarios where you want to update the configuration of an existing service you can use the following steps to manually update the configuration.

 

Download the configuration

Download the configuration and save a local .CSCFG file. You can do this via the portal or Powershell.

To do this from the portal go to the Configure tab and click Download:

image

To do this from Powershell run:

$deployment = Get-AzureDeployment -ServiceName <servicename> – Slot <slot>

([xml]$deployment.Configuration).Save("c:\temp\config.cscfg")

 

Update the configuration setting

Open the .CSCFG file you saved, make any necessary changes, and then save the .CSCFG.

*See below for how to modify the password.

 

Upload back to the portal

Upload the modified .CSCFG file back to the portal and wait for the configuration change to complete.

To do this from the portal go to the Configure table and click Upload:

image

To do this from Powershell run:

Set-AzureDeployment -Config -ServiceName <servicename> -Configuration "c:\temp\config.cscfg" –Slot <slot>

 

Updating the password

Updating settings such as the expiration date or username is easy, but updating the password is more difficult. The RDP password is encrypted using a user-provided certificate that is uploaded to the cloud service. If you are making these RDP changes on the computer that already has that certificate in the cert store (ie. from the dev/deploy machine) then getting a new encrypted password is pretty straightforward:

  1. Open a ‘Windows Azure Command Prompt’
  2. Execute:
  3. csencrypt encrypt-password -copytoclipboard –thumbprint <thumbprint_from_CSCFG>
  4. Paste the new password into the AccountEncryptedPassword setting in the .CSCFG

If you don’t have the certificate in the local computer’s cert store you can download it and generate a new encrypted certificate using Powershell:

# Download the cert
$cert = Get-AzureCertificate -ServiceName <servicename> -Thumbprint <thumbprint_from_CSCFG> -ThumbprintAlgorithm "SHA1"

# Save the cert to a file
"-----BEGIN CERTIFICATE-----" > "C:\Temp\rdpcert.cer"
$cert.Data >> "C:\Temp\rdpcert.cer"
"-----END CERTIFICATE-----" >> "C:\Temp\rdpcert.cer"

# Prompt for the new password
$password = Read-Host -Prompt "Enter the password to encrypt"

#Load the certificate
[System.Reflection.Assembly]::LoadWithPartialName("System.Security") | Out-Null
$cert = New-Object System.Security.Cryptography.X509Certificates.X509Certificate2("c:\temp\rdpcert.cer")
$thumbprint = $cert[0].thumbprint
$pass = [Text.Encoding]::UTF8.GetBytes($password)

# Encrypt the cert
$content = new-object Security.Cryptography.Pkcs.ContentInfo -argumentList (,$pass)
$env = new-object Security.Cryptography.Pkcs.EnvelopedCms $content
$env.Encrypt((new-object System.Security.Cryptography.Pkcs.CmsRecipient($cert)))

# Write the new password to a file and load the file
write-host "Writing encrypted password, cut/paste the text below the line to CSCFG file"
[Convert]::ToBase64String($env.Encode()) > "c:\temp\encrypted_password.txt"
Invoke-Item "c:\temp\encrypted_password.txt"