Managing Remote Desktop services (aka Terminal services) using Windows PowerShell

Managing Remote Desktop services (aka Terminal services) using Windows PowerShell

Rate This
  • Comments 10

Hello everyone,

We are pleased to announce that the Beta release of Windows server 2008 R2 supports managing Remote Desktop services using PowerShell.  You can now configure and manage all RDS role services and components using PowerShell.  For example, below are few management tasks that you can now do with PowerShell

1.       View and edit configuration settings of Remote Desktop server

2.       Publish RemoteApp applications

3.       Configure License Server

4.       Create and configure a Remote Desktop server farm

5.       Configure and assign virtual IP addresses to either sessions or applications

6.       Create and manage RDV (VDI) pools

7.       Create and manage Gateway Resource Access & Client Access policies

Of course there is a lot more that you can do with Windows PowerShell. Install the beta release of Windows Server 2008 R2 and give this feature a try. As always, we are eager to hear what you think and it is important that you let us know what you like and don’t like as early as possible.

Read further to understand RDS PowerShell in detail.

Remote desktop services PowerShell

Once you install the Remote Desktop services role, a PowerShell provider gets installed. This Provider (we’ll call it RDS provider in the rest of this post) allows you to view and manage the configuration of all role services and components of Remote Desktop Services.

 Think of RDS Provider as something similar to file system provider and registry provider, IIS Provider. You view, navigate and work with RDS provider as you would with any of the other providers.

 Working with RDS PowerShell

To get started, first install the Remote Desktop services role and then launch RDS PowerShell.

Step 1: Install Remote Desktop services role

RDS PowerShell is installed when you install the Remote Desktop services role. You can install the Remote Desktop services role using Server Manager. 

Step 2: Launch RDS PowerShell

Right click on Start Menu -> All Programs -> Administrative Tools -> Remote desktop services -> ‘Remote Desktop Services PowerShell’ and select ‘Run as Administrator’.

Once you click on this link, you’ll see a PowerShellPowerShell window with the prompt set to RDS drive. There it is – the RDS provider for you.

You’d notice that once you issue the dir command, you see a view that has the following six columns.

Name: Name of the Container/Setting

Type: Type of Item. There are three possible values for Type – Container (Node), Integer, or String. Container (Node) denotes a Container Item, and Integer and String denote Settings. You can only CD into container items. Containers represent a setting group or a logical entity whereas Settings represent configuration settings. For example, roles such as RDS andConnection broker, and entities such as Connection Objects and RemoteApps are represented as Containers, while server drain mode is represented as a setting

CurrentValue: Value set to the Item (applicable only toItems of ‘Integer’ or ‘String’ Type)

GP: Indicates whether an Item is controlled by group policy or not

PermissibleValues: Possible values that a Setting Item can have

PermissibleOperations:  Operations (cmdlets) that can be performed on the Item

Users can select which columns are displayed by using the Format-table cmdlet. For example  Get-Item * | format-table -Property Name, CurrentValue displays only Name and CurrentValue columns. Alternatively you can use dir * | ft -Property N*,C* to achieve the same result. 

You can also customize the default view. More on this in a later post.

How to get help?

One of the salient features of PowerShell is that it makes it easy to get information and help on a particular aspect. That advantage is retained in RDS Provider as well. There is a property called Description associated with every Item which succinctly describes what a particular setting does.

For example PS RDS:\RDSConfiguration> get-item .\DrainMode| fl displays information about the DrainMode item. You can also change the default view to always display the Description column.

Now, let’s look at few examples.

Example 1: Set RDP encryption level

Step 1: View current encryption level

PS RDS:\RDSConfiguration\Connections\RDP-Tcp\SecuritySettings> dir .\EncryptionLevel | fl

Step 2: Set value of EncryptionLevel item to desired value

PS RDS:\RDSConfiguration\Connections\RDP-Tcp\SecuritySettings> Set-Item .\EncryptionLevel 2

Example 2: Specify License servers that a Remote Desktop server will use

Step 1: View the current list of License Servers in use

PS RDS:\RDSConfiguration\LicensingSettings\SpecifiedLicenseServers> dir

Step2: View the list of license servers registered with the domain controller.

PS RDS:\RDSConfiguration\LicensingSettings\RegisteredLicenseServers> dir

Step 3: add a License server to SpecifiedLicenseServers list

The simplest way to add a license server is to use new-item and specify the name of the license server that you want to add.

PS RDS:\RDSConfiguration\LicensingSettings\SpecifiedLicenseServers> New-Item -name ls.contoso.com

You can use the below command to add all license servers from the registered license server list to specified license server list.

PS RDS:\RDSConfiguration\LicensingSettings\SpecifiedLicenseServers> dir ..\RegisteredLicenseServers | new-item –force

Example 3: Join a Remote Desktop server to a Session Broker farm

 

PS RDS:\RDSConfiguration\ConnectionBrokerSettings> Set-Item MemberOfFarm 1 -FarmName testFarm -sessionbroker contoso-sb-test  -CurrentRedirectableAddresses 65.52.65.53

 

Example 4: Add a RemoteApp

 

PS RDS:\RemoteApps\PublishedApplications> New-Item -Name "IExplore" -ApplicationPath "c:\Program Files\Internet Explorer\iexplore.exe" -ApplicationName "Internet Explorer" -ShowInPortal 1

These are just few examples that demonstrate the various possibilities.  Almost all configuration tasks related to RD server configuration, RemoteApp, Gateway, License server, and RDV can now be performed using the RDS provider.

Also, the true potential of RDS Provider is realized when writing a script to

1.       chain multiple configuration activities together

2.       perform configuration on multiple servers

One scenario that best demonstrates the above is the creation of RD server farms. The script shown as a example at the end of this post takes a list of servers and applications as input and creates a RD server farm and creates RemoteApp on all of the servers.  Create two text files, one with a list of servers and another with a list of app paths (you can use paths with shell variables such as %windir%) and pass the names of these files as input to this script.

Since this script makes use of PowerShell remoting, before you execute the script make sure you have enabled PowerShell remoting (run Enable-PSRemoting from an elevated PowerShell Windows to enable remoting.).  

Of course this is a very rudimentary script – you can augment it easily with advanced and specific functionality to suit your needs.  Also, in our opinion, one of the important advantages of RDS provider is that one doesn’t need to be a programmer to be able write such scripts as CreateRDFarm. All one needs to know is basic PowerShellPowerShell scripting.

I hope you are as excited as we are about the possibilities that this opens up. Do let us know what you think. Also, keep watching this space for more scripts that you can put to use.

 

Appendix: Sample script

 

#Windows PowerShell script to create a RD Server farm.

 

if ($args[0] -eq $null -or $args[1] -eq $null -or $args[2] -eq $null ){

      Write-Host "Insuffecient parameters.`nUsage: CreateRDFarm.ps1 SessionBroker Farmname <File containing list of RDS servers> <File containing Applications to publish>"

      exit

}else{

      $sb = $args[0]

      $farmname = $args[1]

}

 

$rdsarr = get-content $args[2]

if ($rdsarr -eq $null){

      Write-Host "$args[2] cannot be read or is empty.`nUsage: CreateRDFarm.ps1 SessionBroker Farmname <File containing TS servers> <File containing Applications to publish>"

      exit

}

 

if ($args[3] -eq $null){

      Write-Host "No file containing Apps Servers specifed. TS Remote Apps will not be published.`nUsage: CreateFarm.ps1 SessionBroker Farmname <File containing TS servers> <txt file containing Applications to publish>.`n Farm creation will continue" -ForegroundColor yellow

}else{

      $apparr = get-content $args[3]

      if ($apparr -eq $null){

      Write-Host "$args[3] cannot be read or is empty.`nUsage: CreateRDFarm.ps1 SessionBroker Farmname <File containing TS servers> <File containing Applications to publish>"

}

}

 

# Check whether session broker service is running on the remote machine

 

$sbservice = Get-Service -ComputerName $sb -Name Tssdis

if( $sbservice.status -ne "Running"){

Write-host "Session Broker service is not running on $sb. Exiting farm creation"

exit

}

 

 

if ($rdsarr[0] -eq $null){

      Write-Host "No TS Server specified. Atleast one TS Server need to be specified.`nUsage: CreateFarm.ps1 SessionBroker Farmname TS1 TS2 ..."

      exit

}

 

#create a run space to run remote commands on the Session Broker server

$sb_remotesession = New-PSSession -ComputerName $sb

 

foreach ($rds in $rdsarr){

 

      #add ts server to Session Broker Computers group on SB server

      $tst = $rds+"$"

      invoke-command $sb_remotesession -ScriptBlock {

      net localgroup 'Session Broker Computers'  /add $args[0] 2>$null;`

      } -ArgumentList $tst

     

      #join each ts server to sb farm.

           

            Write-Host "Joining RD server $rds to $farmname farm" -ForegroundColor magenta

           

            $rds_remotesession = New-PSSession -ComputerName $rds

 

            invoke-command $rds_remotesession -ScriptBlock { `

                  import-module RemoteDesktopServices ;`

                  $cipaddr = dir RDS:\RDSConfiguration\ConnectionBrokerSettings\RedirectableAddresses ;`

                  Set-Item RDS:\RDSConfiguration\ConnectionBrokerSettings\MemberOfFarm 1 -FarmName $args[0] -sessionbroker $args[1] -IPAddressRedirection 0 -CurrentRedirectableAddresses $cipaddr[0].Name ;`

                  }`

                  -ArgumentList $farmname,$sb

 

      #create ts remote apps

            if ($args[3] -ne $null){

 

                  foreach ($app in $apparr){

                       

                        Write-Host Publishing $app on $rds -ForegroundColor magenta

                       

                        $ind = $app.LastIndexof("\")

                        $alias = $app.SubString($ind+1,$app.LastIndexOf(".")-$ind-1)

                       

                        invoke-command $rds_remotesession -ScriptBlock { `

                        new-item -Path RDS:\RemoteApps\PublishedApplications -Name $args[0] -ApplicationPath $args[1]`

                        }`

                        -ArgumentList $alias,$app

                  }

            }

 

      #close the remote session

      Remove-PSSession $rds_remotesession

}

 

#close the sb runspace

Remove-PSSession $sb_remotesession

 

 

Shanmugam Kulandaivel
Remote Desktop Virtualization Services Team

 

Leave a Comment
  • Please add 3 and 5 and type the answer here:
  • Post
  • Managing Remote Desktop services (aka Terminal services) using Windows PowerShell Feed: Windows PowerShell

  • Hi,

    I've been trying to find a way to query a list of servers for their current Terminal Services sessions and then force a logoff for any sessions that have been inactive for a threshold time.

    Is this a supported scenario with PowerShell?

    Regards,

    Jason

  • Hi Jason,

    The session time limits for connection RDP-Tcp can be found at path : 'RDS:\RDSConfiguration\Connections\RDP-Tcp\SessionTimeLimitSettings'

    Change directory to above location.

    Say you have to set the IdleSessionLimit of 1 hour (3600000 millisecs).

    The following snippet should do it for you :

    # if 'TimeLimitPolicy' is 0(Server Override), Just set the IdleSessionLimit

    Set-Item IdleSessionLimit 3600000

    # if 'TimeLimitPolicy' is 1(User setting), Set policy to Server override and provide timelimit values

    Set-Item TimeLimitPolicy 0 -IdleSessionLimit 3600000 -ActiveSessionLimit 0 -DisconnectedSessionLimit 0

    For more information on these items check their description.

    Example: Get-Item TimeLimitPolicy | Format-List

  • @ Jason:

    If the threshold idle time is fixed, above snippet would do. Otherwise we donot currently support the following:

     1. Listing the current TS sessions

     2. Log-off sessions on need basis or with variable threshold idle time

  • Terminal services tools can be used with PowerShell to accomplish the above mentioned tasks.

    For more details on these tools visit : http://technet.microsoft.com/en-us/library/cc776289.aspx

  • In case you haven&#39;t noticed, Microsoft renamed Terminal Services as Remote Desktop Services from

  • On Windows Server 2008 R2, if I just install the Remote Desktop Virtualization role, I don't get the "Remote Desktop Services PowerShell". Is it by design?

  • Same problem here, No powershell where it should be thought I see the provider is installed when i run powershell modules from start menu->somewhere

  • OK figured out i can just launch the powershell as mentioned before and do cd RDS:

  • No more transferring of PDF documents and other workarounds just to get your documents on your remote workstation using Tsscan. It's zero configuration needed. It's fun..

    terminalworks.com/tsscan.php

Page 1 of 1 (10 items)