Installing and licensing the RDS role on a non-domain joined Server 2012R2 system

System: Windows Server 2012R2

- last updated on -

About: The purpose of this document is to provide a detailed account of how the RDS role can be installed and licensed (through the retail channel, your situation may differ) on a non-domain joined (member of a workgroup) Server 2012R2, as this scenario is apparently not officially supported by Microsoft: the centralized GUI console for RDS management, called the Remote Desktop Management Services, or RDMS, requires that the administrator account that launches it be a a domain account (and so the server to a member of an Active Directory domain), otherwise it will not work. The document's instructions also ensure that the RDS deployment is reasonably hardened: RDP connections are secured via the use of NLA and encryption (optimally with a root CA-issued certificate, otherwise with a self-signed one, automatically generated by the RDS).

How-to: There are two ways of achieving the goal, either by using the CLI or by using the GUI; they are detailed below. Both paths assume that you are logged in with the Administrator account and both have a Prerequisites section, which is provided only in the CLI form (note that you must always go through the Prerequisites section before continuing on to the CLI or GUI sections).

Prerequisites

- run the below commands from an elevated Powershell console:

#set the hostname
(get-wmiObject -namespace root\CIMv2 -class Win32_ComputerSystem).rename("%enterHostnameHere%") | out-null

#set the FQDN suffix
set-itemProperty -path HKLM:\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters -name "NV Domain" -value "%subdomain.domain.tld%"

#append primary DNS suffix (and derivatives) to DNS requests -- should already be set, but it's better to make sure
set-itemProperty -path HKLM:\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters -name UseDomainNameDevolution -value 1

#allow Remote Desktop connections to the system
(get-wmiObject -namespace root\CIMv2\TerminalServices -class Win32_TerminalServiceSetting).setAllowTSConnections(1) | out-null

#set the RDP security layer to SSL (TLSv1.2)
(get-wmiObject -namespace root\CIMv2\TerminalServices -class Win32_TSGeneralSetting).setSecurityLayer(2) | out-null

#set the RDP encryption level to High -- no WMI method was found to work, so we'll go instead with modifying the registry directly
#(given the subsequent reboot, this should work just fine)
set-itemProperty -path "HKLM:\SYSTEM\CurrentControlSet\Control\Terminal Server\WinStations\RDP-Tcp" -name MinEncryptionLevel -value 3

#enable enforcement of NLA-only connections
(get-wmiObject -namespace root\CIMv2\TerminalServices -class Win32_TSGeneralSetting).setUserAuthenticationRequired(1) | out-null

#reboot in order to activate the changes
restart-computer

- you are all done with the prerequisites

CLI

- open an elevated Powershell console
- run the below commands within it:

#install the Remote Desktop Session Host and Remote Desktop Licensing roles on the system (including the management tools for the Licensing role)
install-windowsFeature -name RDS-RD-Server,RDS-Licensing -includeManagementTools -restart
#note: the system might automatically reboot in order to finish the role deployment

#set up and activate the (local) Licensing Server
$licSrv = get-wmiObject -namespace root\CIMv2 -class Win32_TSLicenseServer
$licSrv.FirstName = "%your first_name%"
$licSrv.LastName = "%your last name%"
$licSrv.CountryRegion = "%your country of residence%"
$licSrv.Company = "%your company's name"
$licSrv.put() | out-null
invoke-wmiMethod -class Win32_TSLicenseServer -name ActivateServerAutomatic -namespace root\CIMv2 | out-null

#enable the per-user licensing mode for the License Server
(get-wmiObject -namespace root\CIMv2\TerminalServices -class Win32_TerminalServiceSetting).changeMode(4) | out-null

#set the system's licensing server to be the local Licensing Server
(get-wmiObject -namespace root\CIMv2\TerminalServices -class Win32_TerminalServiceSetting).setSpecifiedLicenseServerList("$env:computername") | out-null

#install a License Key Pack (such as a 5-CAL RDS retail license)
(get-wmiObject -namespace root\CIMv2\TerminalServices -class Win32_TSLicenseKeyPack).installRetailPurchaseKeyPack("%license_key--see_the_NOTE_below%") | out-null
*note on the license key: it must be provided without the hyphens (so the 5 groups of 5 characters each, delimitated with '-' characters, will be provided as a continuous string of 25 alphanumeric characters; don't forget to enclose the resulting string in quotes)
**example: "aaaaa-bbbbb-ccccc-ddddd-eeeee" must be provided as "aaaaabbbbbcccccdddddeeeee" - the full command will look as below:
(get-wmiObject -namespace root\CIMv2\TerminalServices -class Win32_TSLicenseKeyPack).installRetailPurchaseKeyPack("aaaaabbbbbcccccdddddeeeee") | out-null

- you should be all done at this point

Note: Pinch of salt warning - the above steps have never been fully tested, since the installation of the CALs has not been possible in the environment used to compile the steps, so the mileage may vary.

GUI

- install the required RDS roles and tools

- activate the licensing server and install CALs

- you should be all done at this point

Note: Pinch of salt warning - the GUI steps are written from memory, mainly, so I'm not sure how close they follow the actual wizards, the actual mileage may vary.

Notes on the 'CLI' and 'Prerequisites' sections: the easiest way of using these sections is to copy/paste those commands which do not require any editing into a Powershell console and to use a text editor for those commands which include the %your_input_here% type of string, and so do require editing; in that case, you must replace the %string% (including the % characters) with the required/needed value and then copy/paste the resulting command into the console.

For instance, (get-wmiObject -namespace root\CIMv2 -class Win32_ComputerSystem).rename("%enterHostnameHere%") | out-null would be pasted in Powershell, after editing it in Notepad, as: (get-wmiObject -namespace root\CIMv2 -class Win32_ComputerSystem).rename("TestServer01") | out-null

References:

  1. https://ryanmangansitblog.com/2013/10/30/deploying-a-rdsh-server-in-a-workgroup-rds-2012-r2/
  2. hands-on testing (the installation of License Packs/CALs still needs reviewing)
  3. various other sources, which I've misplaced/forgot for now, but will hopefully manage to add here at some point