Welcome to MSDN Blogs Sign in | Join | Help

Announcing the Remote Desktop Protocol Performance Improvements in Windows Server 2008 R2 and Windows 7 white paper

With the growing trend toward desktop virtualization, it is Microsoft’s goal to provide enterprises with a flexible model for centralized computing, whereby the broadest range of client devices can help securely access company data and applications from any location on the network.

As with Remote Desktop Services in Windows Server 2008 R2, virtual machine-based desktop virtualization faces increasing performance challenges when enterprises attempt to use this technology to support a globally distributed workforce. A key consideration of performance relates to Remote Desktop protocol efficiency which continues to present an issue for bandwidth constrained environments. This limitation can manifest itself by limiting the number of users who can access virtualized desktops (user density) over available bandwidth, and with a degraded user experience. Remote Desktop Protocol (RDP) 7.0, similar to previous RDP versions, provides a competitive experience for low bandwidth (e.g. 56 Kbps) connections. After bandwidth requirements, network latency is the second fundamental challenge for customers and partners that wish to deploy virtualized desktops for a broad range of end-users and applications.

With the release of the Windows Server® 2008 R2 and Windows® 7 operating systems, RDP 7.0 is even more feature-rich than its predecessors—enabling new remoting functionality such as accelerated bitmap rendering, multi-media redirection streaming, and network topology awareness. In short, RDP 7.0 is better able to support today’s ever increasingly complex and rich multi-media environment.

To improve the user experience when connecting over high latency networks, RDP 7.0 added “client hint” functionality. “Client hint” can be enabled by using the Remote Desktop Connection (RDC) 7.0 client UI to set the connection speed on the Experience tab.

image

image

The same setting can be configured via .rdp files by selecting WAN (10 Mbps or higher with high latency) or Satellite (2 Mbps–16 Mbps with high latency) with connection type:i:5 or connection type:i:3 respectively.

As these features become integrated into the enterprise environment, it is important to analyze and understand their impact on enterprises’ current network infrastructure and end-user experience. The Remote Desktop Protocol Performance Improvements in Windows Server 2008 R2 and Windows 7 white paper details RDP features and the potential for improvements to usability and the quality of the end-user remoting experience, as well as system deployment metrics.

Note: You should not interpret the performance characteristics presented in the white paper as benchmark measurements that all systems can support. Only empirical testing on the target system can provide an accurate benchmark of your specific scenario.

Check out the RDS Partner Page Refresh

Remote Desktop Services partners are very important to the RDS team. We’ve had a partner page up for a long time, but wanted to refresh it to better show what our partners do and what value they add to the RDS platform, as well as help you find the resources you want. Today, I’d like to announce the kickoff of the updated site.

Four of our partners (so far) have put together free offerings for this site. In addition, we have several other partners working on limited version downloads that will be included on our site over the upcoming months. In alphabetical order:

· Desktopsites has created a limited version of their Konect management tools that allow you to manage heterogeneous Terminal Services/Remote Desktop Services deployments from a central console. For thirty days, the free version allows you to manage settings for two users across multiple servers; at the thirty-day mark, the trial becomes a limited-version for two users with no expiration.

· Ericom has created a limited version of their PowerTerm WebConnect for Windows Server 2008 R2. This solution provides centralized application publishing, simplified configuration management, real-time monitoring, logging, and control.

· Immidio has created a Resource Kit (note, this is separate from the Resource Kits offered by Microsoft) that contains several utilities useful for both administrators and users. My favorite is the one that remotes the display of the battery-life SysTray icon, so that if you’re working on a virtual machine (VM) or full-desktop session from an unplugged laptop, you won’t be taken unawares when the battery dies.

· RES Software has a management tool for controlling which applications users can view from a desktop. Their freeware version of PowerFuse not only hides application icons that users don’t have permission to use, but it locks them down so that they can’t be launched from the command line or Windows Explorer.

For more details, stop by and visit our new partner page. If you have suggestions for additional tools that you feel would help you with your RDS deployments for VDI or session virtualization, make a note on this blog and do check back often as we will continually be adding new case studies and product offerings from our partners.

VIDEO: How to Install MS VDI on as Single Server using Windows 7 Guests

People have asked us how easy it is to install a complete MS VDI solution and how many servers does it take.  I’ve created a video to showcase that you can setup a complete solution including backend, broker, and web publishing to provide virtualized clients on a single physical Windows Server 2008 R2 box.  This sample uses Windows 7 for the guest.     The complete 16 minute video is at http://www.microsoft.com/showcase/en/us/details/fbaf6f70-45fd-4c81-be70-6d276d54776b

To learn more about Microsoft VDI:

http://technet.microsoft.com/en-us/library/dd647502(WS.10).aspx (step-by-step guides)

http://social.technet.microsoft.com/Profile/en-US/?user=RemoteDesktopServices&sp=tng (scripts)

Posted by termserv | 6 Comments

How to detect RDS-specific application compatibility issues by using the RDS Application Compatibility Analyzer

The Remote Desktop Services (RDS) Application Compatibility Analyzer is a runtime program analysis tool that enables administrators and users to determine the compatibility of an application with a Remote Desktop Session Host (RD Session Host) server before deploying it. The tool provides a summary of incompatible behaviour between the RD Session Host server and an application, and provides recommendations for deploying the application on an RD Session Host server. The RDS Application Compatibility Analyzer uses the LUA (Least Privileged User Account) Predictor technology, which is part of Microsoft Application Verifier.

This blog post describes how to:

  1. Install the RDS Application Compatibility Analyzer
  2. Run an application in the RDS Application Compatibility Analyzer
  3. Test an application for RDS compliance
  4. Debug info and blog feeds
  5. Filter noise, detailed stack trace, and logging
  6. Interpret RDS Application Compatibility Analyzer logs

1. Installing the RDS Application Compatibility Analyzer

The RDS Application Compatibility Analyzer installer can be found at https://connect.microsoft.com/tsappcompat/Downloads.

The Application Verifier must be installed before the RDS Application Compatibility Analyzer is launched. The recommended version (3.5) of Application Verifier can be found at [X64] [X86]. On 64-bit operating systems, the RDS Application Compatibility Analyzer needs both 32-bit and 64-bit versions of Application Verifier. If Application Verifier is not installed, or the installed Application Verifier version is less than 3.5, the RDS Application Compatibility Analyzer will point to the Application Verifier 3.5 download location. If the installed Application Verifier version is greater than 3.5, the tool does not prompt for Application Verifier. However, we recommend that you uninstall the latest version of Application Verifier and install Application Verifier 3.5. Microsoft .NET Framework 3.5 is also required to run the tool. The tool can be run on a client or server operating system. It does not require that the RD Session Host role service be installed.

2.Running an application in the RDS Application Compatibility Analyzer

A. From the UI:

1. Click Start, point to All Programs, and then click RDS Application Compatibility Analyzer.

image001

2. On the App Info tab, in the Target Application box, enter the directory location of the target application’s executable file or use the Browse function.

3. On the App Info tab, in the Parameters box, enter parameters for the application, if applicable.

4. Ensure that the RDSAnalyzerService is up and running. Select or clear the Launch Elevate check box as appropriate.

5. Click Launch.

B. From the command-line (batch mode and no UI):

The RDS Application Compatibility Analyzer can be run in a batch mode (without UI). This feature makes it easier to deploy it to multiple users seamlessly without using the user interface, which can be intrusive. Following are the supported command-line options:

1. Tsa.exe /? : This pops up a dialog box which lists all the command-line options.

2. Tsa.exe <logfilename>: This opens an already created log file for analysis.

3. Tsa.exe –l <logfilename> <Application> <"parameters to the application">: This launches the application with given parameters, and logs are stored in the log file. No UI is displayed in this case. For log analysis, run “Tsa.exe <logfilename>”; this opens an already created log file for analysis.

3. Testing an application for RDS compliance

When an application is launched by using the RDS Application Compatibility Analyzer, the RDS Application Compatibility Analyzer monitors the application’s actions while it is running and waits for the application to be closed. The RDS Application Compatibility Analyzer waits for all child processes created by the application to exit before it starts to load the log file. Sometimes a certain child process might still be running even after the main application process has exited. In that case, you can either manually find and terminate that child process, or use the Refresh Log button to manually load the log file.

The RDS Application Compatibility Analyzer then generates and parses a log for the application, which might take some time to complete. After the log has been generated and parsed, click any tab (File, Registry, INI, Token, Privilege, Namespace, Other Objects, Process) to view specific issues found by the RDS Application Compatibility Analyzer in that category.

Use the following procedure to detect issues:

image003

Run application as a standard user versus run as elevated:

The Launch Elevate check box controls whether the application that you selected will run as an administrator or as a standard user (without administrator-level user rights and Windows privileges). The option that you select will impact the types of UAC problems that the RDS Application Compatibility Analyzer detects.

If the RDS Application Compatibility Analyzer launches the application as a standard user, there will be many errors related to ACCESS_DENIED issues. These errors occur due to the application running with reduced user rights and privileges. Many applications terminate at the first unexpected error. In this case, you will find only one error with each execution of the application.

If the RDS Application Compatibility Analyzer launches the application as an administrator, it predicts errors that result from the application’s successful access attempts. In this case, you will find most of the application errors because the application did not stop at the first error. Certain classes of errors may distort the analysis. For example, if an application performs a COM registration during initialization, that application may behave correctly after running the RDS Application Compatibility Analyzer because the COM object was already registered. The application might generate a false-negative reading from the RDS Application Compatibility Analyzer indicating that the application will behave correctly with the application.

4. Debugging info and blog feeds

Debug info:

The Debug Info tab shows commands executed by the tool and their success or failure status. The Repro button on the Debug Info tab helps to analyze actions done during the repro period. For example, if the user wants to analyze logs for a specific action, he/she can start the repro by clicking Repro and perform the action, and then stop the repro by clicking Stop Repro. In this case, the actions performed during the repro period will be analyzed.

Blog feeds:

On the Blog Feeds tab, you can add RSS feed URLS that will be used to search blog posts for related problems. Following are the steps to add RSS feed URLS:

1. On the Blog Feeds tab, select the Enable Blog Feeds check box.

2. In the Feed URL box, type the RSS feed URL, and then click Add New Feed.

3. Select the feed URL by selecting the Blog Feed URL check box, and then click Update.

Updated RSS feeds are used for finding similar problems posted in blog feeds. To view related problems for an error from blog posts, enable the Show RSS Feeds option. This option can be enabled on the View tab by selecting Show RSS Feeds under Detailed Information. When this option is enabled, the lower-left panel of the RDS Application Compatibility Analyzer displays the blog post that is related to the selected error.

5. Filtering noise, detailed stack trace, and logging

Image002

Filter noise:

Noise filtering can be enabled or disabled by using the Filter Noise option. The tool filters noise by using a filter file in xml format. The noise filter file can be loaded or exported by clicking Load Noise Filter File or Export Noise Filter File on the Options menu. Logging for a specific API call can be filtered by adding a node to the noise filter file. For example, to filter the RegOpenKeyExA call for the registry key Internet Settings, add the following node to the noise filter file and then load the noise filter file:

<avrf:logEntry Time="9/09/2009 9:09:09 AM" LayerName="LuaPriv" StopCode="0" Severity="any"> <avrf:formatmessage>(\REGISTRY\MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Internet Settings) (RegOpenKeyExA) </avrf:formatmessage>
<avrf:IsNoise>true</avrf:IsNoise>
</avrf:logEntry>

Detailed stack trace:

Detailed stack trace can be enabled by selecting the option Show More Details in StackTrace. This will show additional stack frames that are related to the SUA but not the application being diagnosed. Debug information for other applications can be filtered by selecting the Only Display Records With Application Name In StackTrace option. The tool captures the first 32 stack frames, so enabling this option might filter out real issues if a call stack is deeper than 32 frames.

If the Detailed Information option on the View menu is enabled, when an issue on any individual tab is selected, the lower-left panel of the RDS Application Compatibility Analyzer displays all related records from the log file. The lower-right panel will display the detailed information for the selected record, including a detailed message and the stack trace.

Logging:

The tool categorizes logging into errors, warnings, and information. By default, logging is done for warnings and errors. Logging for warnings, errors, and information can be enabled or disabled on the Options menu by selecting Logging.

6. Interpreting RDS Application Compatibility Analyzer logs

The tool categorizes processed logs onto different tabs. Found issues are categorized by severity levels Warnings and Problems. The focus should be only on Problems unless you are trying to pinpoint a problem source. One key thing to understand about a Problem is that the tool has detected that a non-RDS-compatible API call has been made by the application, but this call itself can be a part of a condition in the application. So Problems are potential problems and need to be analyzed to interpret them correctly. The tool highlights potential problems in an application that might not always manifest. It is essential to understand this to correctly interpret and use the results effectively.

The following table shows details about each tab in the RDS Application Compatibility Analyzer GUI:

Tab

Details

File / Registry

Lists file system and registry access issues (for example, an application attempting to write to a file or a registry key under HKLM that normally only administrators can access). Applications create various registry entries, folders and files during installation. Usually the application files are created in an application repository (typically the “Program Files” directory) and the registry entries are created in HKLM and HKCU hives. User data files are created within the user profile folder (%userprofile%). Application shortcuts are created within the user profile as well. Most application installations are designed for a single-user client system and this could cause problems in the Remote Desktop Services environment. Installation can be broadly divided into two parts:

1. Installation activities: The application should create all common application files, libraries and registry entries at installation.

· The application should not create files and registries that contain user-specific data that is not needed by other users at this stage.

· The application should store user shortcuts or any truly common files that will be used by all users (typically read-only files with common application settings or database/repository files) in the All Users stores (%allusersprofile% for data and %public% for shortcuts, desktop content, etc.).

· Files and registry entries stored in locations that need privileged access can cause problems when they are used by a non-administrative user.

While user-specific files and registries must be created in the user’s hive, the application should not do this at install time because these files and registries will be available only to the installing user. The application should do this after installation. Most of the RDS-specific problems occur because of user-specific deployment:

· Any registry entries made in HKCU at installation are available only to the user installing the software, who is usually the administrator. When another user then tries to use that application, these entries would not be available to that user.

· Similarly any data files created within the installing user’s user profile would not be available when the application is executed by another user.

2. Post-installation activities: The application should create all user-specific data files, registry entries, etc. after installation. This can usually be triggered by user-logon or the first run of the application.

· Common scripts and definitions created after installation can be stored in the common and public files as discussed above.

· These scripts can be executed at first run of the application by a particular user to create files and registry entries for that user. This ensures that every user creates and owns their own user-specific data in their user profile that is isolated from all other users. Microsoft Windows Installer supports creating per-user scripts that can be leveraged for this purpose.

INI

Lists WriteProfile APIs issues. WriteProfile APIs were originally used for 16-bit Windows but are still popular in some modern applications.

Token

Lists access token checking issues. If an application explicitly checks for the Builtin\Administrators security identifier (SID) in a user’s access token, the application most likely will not work for a standard user.

Privilege

Lists privilege issues. For example, if an application explicitly enables SeDebugPrivilege, it will not work for a standard user.

Name Space

Lists issues that are caused when an application creates system objects (e.g. events, memory mappings) in restricted namespace. Applications that have this error will not work for a standard user.

Other Objects

Lists issues related to accessing objects other than files and registry keys. The following are some generic recommendations for applications working in a concurrent user environment:

· All objects, such as pipes, ports, shared libraries, and components, must be isolated per session or locked for exclusive access for modification as per application scenarios. To avoid data corruption, concurrent writes by multiple instances should not be allowed.

· The application should not use a fixed port number for listening or a pipe name for an application, but rather have a unique identifier for each instance.

Process

Lists issues related to process elevation. On Windows Vista®, if an application uses the CreateProcess API to launch an executable that requires elevation, the application will not work for a standard user.

Publish RD Gateway on an ISA server using a script

The Remote Desktop Gateway (RD Gateway, formerly known as TS Gateway) ISA configuration script helps ease the process of setting up an ISA server for RD Gateway supported scenarios such as the RD Gateway-ISA core scenario and the RD Gateway-ISA OTP scenario. The script runs on the ISA server and completely eliminates the need to configure the ISA server through wizards. Instead, users can create web listeners and web publishing rules through the command line. Additionally, the script can validate existing web publishing rules and web listeners. In the event that issues are discovered with them, the script provides a list of warnings and errors to the user. The script is supported on ISA server 2004 and later versions. It can be used to publish Windows Server 2008 and higher versions of RD Gateway. This script, along with information on its usage, can be found here.

Customizing RD Gateway authentication and authorization schemes

Imagine that you are responsible for managing Remote Desktop Services at Woodgrove Bank. Woodgrove Bank has recently approved a new authentication vendor and you must upgrade all edge services -- including Remote Desktop Gateway (RD Gateway) – to support this new authentication service. How can you integrate the new authentication service with RD Gateway?

The RD Gateway 2008 R2 server platform enables you to integrate custom authentication schemes using the pluggable authentication and authorization (PAA) framework. PAA provides your authentication vendor an interface for developing and integrating custom authentication and authorization plug-ins to the RD Gateway platform. For more details, please refer to the following article hosted on the code gallery: https://code.msdn.microsoft.com/Release/ProjectReleases.aspx?ProjectName=rdsdev&ReleaseId=3745

Virtual Desktop Pool

Scenario

The two virtual machine deployment scenarios supported by the Microsoft VDI solution are: 1) Virtual desktop pool and 2) Personal virtual desktops. These two scenarios present two different models of assigning virtual machines to end users. This post explains the virtual desktop pool scenario.

Assignment

A virtual desktop pool temporarily assigns a virtual machine to the user. The Remote Desktop Connection Broker (RD Connection Broker) automatically makes this assignment without any prior assignment configuration. The user–to-virtual-machine assignment is removed as soon as the user logs off. Since there is no permanent assignment of a virtual machine in a virtual desktop pool to a user, as long as there is a virtual machine available in the pool, one will be assigned to the user. It is a misconfiguration to assign a virtual machine in a virtual desktop pool to a user as if it were a personal virtual desktop. When a user makes a connection to such a personal desktop which is part of a virtual desktop pool, the connection will fail and a target mismatch event is logged by RD Connection Broker.

Access

A virtual desktop pool is a group of identically configured virtual machines on a Remote Desktop Virtualization Host (RD Virtualization Host) server. Users can access the virtual machines in a pool through RemoteApp and Desktop Connection or RD Web Access. When a user clicks on the Virtual Desktop pool icon, RD Virtualization Host prepares a pre-created virtual machine from this virtual desktop pool for a remote RDP connection. A virtual machine can be a member of only one virtual desktop pool. All virtual machines in a virtual desktop pool are identically configured; a user sees the same virtual desktop regardless of which virtual machine in the virtual desktop pool the user connects to. Since a user might be connected to a different virtual machine in the virtual desktop pool each time he logs on, it is recommended to use roaming profiles and folder redirection to centrally manage user settings and data. Please refer to the link for more details:

http://blogs.msdn.com/rds/archive/2009/06/02/user-profiles-on-windows-server-2008-r2-remote-desktop-services.aspx

Load Balancing

To assign a virtual machine from a virtual desktop pool a Hyper-V server which has the least number of running virtual machines is chosen and a virtual machine belonging to this virtual desktop pool is selected. A random selection is made if two or more Hyper-V servers have the same number of running virtual machines. ISVs can enhance the inbox solution by implementing their own load balancing algorithm. Please refer to the link for more details:

http://msdn.microsoft.com/en-us/library/dd401684(VS.85).aspx

http://blogs.msdn.com/rds/archive/2008/09/25/ts-session-broker-extensibility-part-2.aspx

Disconnected VMs

When a user disconnects from a virtual machine in a virtual desktop pool, the user will be redirected to his disconnected VMs the next time he logs back. However, when a user logs off from the virtual machine, the virtual machine can be configured to rollback (refer to the links at the end on how to set up a virtual desktop pool to find details on this) to a state determined by an administrator. Since a user might be connected to a different virtual machine in the virtual desktop pool each time he logs on, it is recommended to use roaming profiles and folder redirection to save user state.

Installation

A virtual desktop pool can span multiple Hyper-V servers with each server possibly having virtual machines from multiple virtual desktop pools. The 3 supported guest operating systems inside a virtual machine are –Win7, Vista SP1 and SP2 and XP SP2 and SP3. For details on the specific versions of these software please refer to the following link - http://technet.microsoft.com/en-us/library/cc794868(WS.10).aspx

For details on how to set up a virtual desktop pool, please refer to:

Technical Library

Microsoft Download Center

Deploying Virtual Desktop Pools by Using Remote Desktop Web Access Step-by-Step Guide (http://go.microsoft.com/fwlink/?LinkId=147906)

Deploying Virtual Desktop Pools by Using Remote Desktop Web Access Step-by-Step Guide (http://go.microsoft.com/fwlink/?LinkId=147907)

Deploying a Virtual Desktop Pool by Using RemoteApp and Desktop Connection Step-by-Step Guide (http://go.microsoft.com/fwlink/?LinkId=154802)

Deploying a Virtual Desktop Pool by Using RemoteApp and Desktop Connection Step-by-Step Guide (http://go.microsoft.com/fwlink/?LinkId=154803)

RemoteApp and Desktop Connection Feed Extensibility

In our earlier blog post, we introduced RemoteApp and Desktop Connections to enable users to have their RemoteApp and Desktop icons integrated on their Windows 7 start menu.  RemoteApp and Desktop Connections works with this new feature of Remote Desktop Web Access (RD Web Access)--the RemoteApp and Desktop Connection feed. This RemoteApp and Desktop Connection feed provides significant extensibility to partners and customers in presenting remote resources in various ways. The connection feed feature contains information about published remote resources (e.g. RDP files and their associated icon and image files) in a software-parsable XML format.

On Remote Desktop Web Access (RD Web Access) Server, there are two URLs available to serve the connection feed. You need to choose one depending on the extensibility scenario.

  1. “/rdweb/pages/webfeed.aspx” URL:
    This URL is used for RD Web Access website extensibility. You can create a new web page similar to the RD Web Access default webpage. Below are some of the features that are possible by using this URL
    • Branding or customizations for your customers or organization.
    • Visually sorting or segregating remote resource types (e.g. RemoteApp and Remote Desktop resources).
    • Filtering remote resources at display time (for example, additional filtering apart from RemoteApp filtering ).
    • Silverlight-based webpage for a rich user experience.

By using this connection feed URL

  • There is no need to write a custom authentication mechanism because the webpage runs within the RD Web Access web application.
  • It is easier to support Single Sign On for launching remote resources. In a future post, we will cover on how to enable SSO.
  1. “/rdweb/feed/webfeed.aspx” URL:
    This URL can also be used to provide extensibility and is more flexible than the above URL. In addition to above feature set, below are some of the other features that are possible by using this URL:
    • Creating new client applications similar to RemoteApp and Desktop Connections for downlevel windows clients and for thin clients.
    • Creating new web portal similar to RD Web Access, not just a webpage alone.
    • Integrating remote resource presentation with your existing web portal.

By using this connection feed URL

    • Client applications get an authentication cookie that will not expire. This can be used for easier automatic updates without re-prompting user for credentials.

Here is a sample connection XML containing information about remote resources:

<?xml version="1.0" encoding="utf-8"?>

<ResourceCollection PubDate="2009-07-09T17:57:30.323Z" SchemaVersion="1.1" xmlns="http://schemas.microsoft.com/ts/2007/05/tswf">
  <Publisher LastUpdated="2009-07-09T17:57:12.588625Z" Name="Remote Desktop Services Default Connection" ID="Contoso" Description="">
    <Resources>
      <Resource ID="60fb077b94a241a473cf982140337213e4d93177" Alias="mspaint" Title="Paint" LastUpdated="2009-07-09T17:57:12.588625Z" Type="RemoteApp" ExecutableName="mspaint.exe">
        <Icons>
          <IconRaw FileType="Ico" FileURL="/RDWeb/Pages/rdp/mspaint032x32.ico" />
          <Icon32 Dimensions="32x32" FileType="Png" FileURL="/RDWeb/Pages/rdp/mspaint032x32.png" />
        </Icons>
        <FileExtensions />
        <HostingTerminalServers>
          <HostingTerminalServer>
            <ResourceFile FileExtension=".rdp" URL="/RDWeb/Pages/rdp/Contoso-mspaint.rdp" />
            <TerminalServerRef Ref="Contoso" />
          </HostingTerminalServer>
        </HostingTerminalServers>
      </Resource>
    </Resources>
    <TerminalServers>
      <TerminalServer ID="Contoso" Name="Contoso" LastUpdated="2009-07-09T17:57:12.588625Z" />
    </TerminalServers>
  </Publisher>
</ResourceCollection>

The bolded attributes in the connection provide information about the remote resources. The schema file for the connection is located at %windir%\schemas\tsworkspace\tswf.xsd in Windows Server 2008 R2 or on a Window 7 client machine.

Website extensibility: Using the connection to create a new web page

Following is a code sample in C# (ASP.NET) on how to use the connection to create a new web page as demonstrated at PDC 2008. This code sample uses a connection at the “/rdweb/pages/webfeed.aspx” location. Below are the steps that need to complete in creating the new web page.

  1. In Page PreInit, check for user authentication. If the user is not authenticated, redirect the request to the login page.
  2. In Page Load, get the connection by calling Server.Execute on the webfeed.aspx page.
  3. Parse the connection XML to get information on the remote resources. Use this information to present remote resources in your customized way.
  4. Replace the default.aspx at %windir%\Web\RDWeb\Pages\en-US folder with this newly created page. This webpage will run inside the RD Web Access web application using an out-of-the box authentication mechanism.

Notes on this sample code:

  1. It does not show how to enable RemoteApp and Desktop Connection’s Single Sign On feature.
  2. It does not show how to differentiate the page content between the admin and a regular user.
  3. It assumes that application locale is en-US.
<%@ Page Language="C#" Debug="false" Trace="false" %>

<% @Import Namespace="System.IO" %>
<% @Import Namespace="System.Collections.Generic" %>
<% @Import Namespace="System.Web.Configuration" %>
<% @Import Namespace="System.Xml" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<script language="C#" runat="server">
    protected void Page_PreInit(object sender, EventArgs e)
    {
        AuthenticationMode eAuthenticationMode = AuthenticationMode.None;
        AuthenticationSection objAuthenticationSection = ConfigurationManager.GetSection("system.web/authentication") as AuthenticationSection;

        if (objAuthenticationSection != null)
        {
            eAuthenticationMode = objAuthenticationSection.Mode;
        }

        if (eAuthenticationMode == AuthenticationMode.Forms)
        {
            if (HttpContext.Current.User.Identity.IsAuthenticated == false)
            {
                // User is not logged in, so redirect the request to login page.
                Response.Redirect("login.aspx?ReturnUrl=" + Request.FilePath);
            }
        }
    }

    protected void Page_Load(object sender, EventArgs e)
    {
        try
        {
            string connectionXml;

            // Execute the handler for webfeed.aspx in the context of current request 
            // and capture output connectionXml.
            using (StringWriter stringWriter = new StringWriter())
            {
                // This new web page is running under the same web application, and 
                // with using existing authentication.
                // So We need run the Server.Execute to get the connection Xml.
                HttpContext.Current.Server.Execute("..//webfeed.aspx", stringWriter);
                connectionXml = stringWriter.ToString();
            }

            // Set current reponse content type
            Response.ContentType = "text/HTML";

            //Strip out the BOM (U+FEFF)
            connectionXml = connectionXml.Trim();

            // Sample code to parse the connection xml. Instead of parsing the connection xml, we can also use XSL transformations directly to display the remote resources
            List<ConnectionResourceInfo> listConnectionResourceInfos = GetConnectionResourceInfo(connectionXml);

            dataListResources.DataSource = listConnectionResourceInfos;
            dataListResources.DataBind();

            labelStatus.Text = "Connection Resources : " + listConnectionResourceInfos.Count;
        }
        catch (Exception ex)
        {
            labelStatus.Text = "Error occurred ~ " + ex.Message;
        }
    }

    private String GetAbsolutePath(string relativePath)
    {
        return String.Format("{0}://{1}{2}", Request.Url.Scheme, Request.Url.Host, relativePath);
    }

    // Parse the XML file for demo purpose. In this function we are not using all 
    // the xml information available, just the title and resource's image file path.
    private List<ConnectionResourceInfo> GetConnectionResourceInfo(string connectionXml)
    {
        List<ConnectionResourceInfo> listConnectionResourceInfos = new List<ConnectionResourceInfo>();
        XmlDocument xmlDocument = new XmlDocument();

        // Load the connection xml string
        xmlDocument.LoadXml(connectionXml);

        XmlNamespaceManager xmlNamespaceManager = new XmlNamespaceManager(xmlDocument.NameTable);
        xmlNamespaceManager.AddNamespace("tswf", "http://schemas.microsoft.com/ts/2007/05/tswf");

        // Get the list of Resource elements
        XmlNodeList xmlNodeList = xmlDocument.SelectNodes("/tswf:ResourceCollection/tswf:Publisher/tswf:Resources/tswf:Resource", xmlNamespaceManager);

        // For each resource get the title and image file relative path
        for (int i = 0; i < xmlNodeList.Count; i++)
        {
            ConnectionResourceInfo connectionResourceInfo = new ConnectionResourceInfo();

            connectionResourceInfo.Title = xmlNodeList[i].Attributes["Title"].Value;

            XmlNode xmlNodeIcon32 = xmlNodeList[i].SelectSingleNode("tswf:Icons/tswf:Icon32", xmlNamespaceManager);

            // Convert the image's relative path to ablosute path
            connectionResourceInfo.ImageFilePath = GetAbsolutePath(xmlNodeIcon32.Attributes["FileURL"].Value);

            listConnectionResourceInfos.Add(connectionResourceInfo);

            // Here you would want to retrieve any other XML information you
            // want for each resource from the connection
        }

        return listConnectionResourceInfos;
    }

    protected void SignOut_Click(object sender, EventArgs e)
    {
        //Redirect the request to logoff page
        Response.Redirect("LogOff.aspx");
    }

    // Entity class to hold connection resource info, for now it contains only the resource title, and its image path
    private class ConnectionResourceInfo
    {
        private string title;
        private string imageFilePath;

        public string Title
        {
            get { return title; }
            set { title = value; }
        }

        public string ImageFilePath
        {
            get { return imageFilePath; }
            set { imageFilePath = value; }
        }
    }
</script>

<html>
<head id="Head1" runat="server">
    <meta http-equiv="CONTENT-TYPE" content="TEXT/HTML; CHARSET=UTF-8">
    <meta http-equiv="CACHE-CONTROL" content="NO-CACHE">
    <meta http-equiv="PRAGMA" content="NO-CACHE" />
    <title>New RD Web Access</title>
</head>
<body>
    <form id="form1" runat="server">
    <div>
        <asp:Button ID="btnSignOut" runat="server" Text="SignOut" OnClick="SignOut_Click" />
        <br />
        <asp:Label ID="labelStatus" runat="server" Text=""></asp:Label>
        <br />
        <asp:DataList ID="dataListResources" runat="server" RepeatDirection="Horizontal"
            RepeatColumns="4" BorderColor="black" CellPadding="1" BorderWidth="1" ItemStyle-BorderWidth="1">
            <ItemTemplate>
                <asp:Image ID="ResImage" ImageUrl='<%# DataBinder.Eval(Container.DataItem, "ImageFilePath") %>'
                    runat="server" /><br />
                <%# DataBinder.Eval(Container.DataItem, "Title") %>
            </ItemTemplate>
        </asp:DataList>
    </div>
    </form>
</body>
</html>

The sample page will appear as below.

image

Customized client applications: Using the connection to create a new client application

Following is a code sample in C# on how to use the connection to create a client application. This code sample uses the connection at the “/rdweb/feed/webfeed.aspx” location.

  1. Send request to the connection URL page with auto-redirect enabled along with user credentials. The connection URL uses cookie-based authentication, so this initial request sent to the connection URL will be redirected to the login page. The login page, which uses Windows-based authentication, responds with the authentication cookie. The supplied user credentials in the request will be used in RemoteApp filtering.
  2. Cache the authentication cookie for all subsequent requests. The cookie will not expire, so you can also reuse the same cookie for easy automatic connection updating without prompting the user for credentials.
  3. Send the request to the connection URL with the authentication cookie, and get the connection XML in response.
  4. Parse the connection XML, and download subsequent resource files and their associated icon and image files.
using System.IO; 
using System.Net;
using System.Web.Security;

private void GetConnectionContents()
{
    System.Diagnostics.ConsoleTraceListener trace = new System.Diagnostics.ConsoleTraceListener();

    //RemoteApp and Desktop Connections uses HTTPS to connect to the server. 
    //In order to connect properly, the client operating system must trust the SSL certificate of the RD Web Access server. 
    //Also, the server name in the URL must match the one in the server’s SSL certificate

    // User credentials to access the connection. Fill in <username>, <password>, <domainname> with your user credentials.
    NetworkCredential networkCredential = new NetworkCredential("<username>", "<password>", "<domainname>");            

    //This URL will generally be of this form.  Fill in <servername> with your server’s name
    string connectionUrl = "https://<servername>/rdweb/feed/webfeed.aspx";            

    string formsAuthenticationCookie = GetFormsAuthenticationCookie(connectionUrl, networkCredential, trace);

    string connectionXml = GetConnectionXml(connectionUrl, formsAuthenticationCookie, trace);

    //Fill in your code to parse the connection, and to download resource files and associated icon & image files. Use earlier cache cookie for authentication. 
}

private string GetFormsAuthenticationCookie(string connectionUrl, NetworkCredential networkCredential, System.Diagnostics.ConsoleTraceListener trace)
{
    //
    // Request connection page is protected by Forms Authentication Cookie. So making a request to that page will be redirected to login page
    // The login page is
    //
    trace.Write("Requesting : " + connectionUrl);
    HttpWebRequest httpWebRequest = (HttpWebRequest)WebRequest.Create(connectionUrl);
    CredentialCache credentialCache = new CredentialCache();
    credentialCache.Add(new Uri(connectionUrl), "Negotiate", networkCredential);
    httpWebRequest.Credentials = credentialCache;
    httpWebRequest.AllowAutoRedirect = true;

    HttpWebResponse httpWebResponse = (HttpWebResponse)httpWebRequest.GetResponse();

    if (httpWebResponse.StatusCode == HttpStatusCode.OK)
    {
        trace.Write("Response: 200 ");
        trace.WriteLine(httpWebResponse.StatusCode);
    }
    else
    {
        trace.Fail("Response status is " + httpWebResponse.StatusCode + ". Expected was OK");
    }

    trace.WriteLine("Response will be the Forms Authentication Cookie");
    trace.WriteLine("");

    string formsAuthenticationCookie;

    using (StreamReader streamReader = new StreamReader(httpWebResponse.GetResponseStream()))
    {
        formsAuthenticationCookie = streamReader.ReadToEnd();
        streamReader.Close();
    }

    trace.WriteLine("formsAuthenticationCookie " + formsAuthenticationCookie);

    return formsAuthenticationCookie;
}

private string GetConnectionXml(string connectionUrl, string formsAuthenticationCookie, System.Diagnostics.ConsoleTraceListener trace)
{
    //
    // Request connection page
    //
    trace.Write("Requesting : " + connectionUrl);
    HttpWebRequest httpWebRequest = (HttpWebRequest)WebRequest.Create(connectionUrl);

    httpWebRequest.CookieContainer = new CookieContainer();

    //
    // Set Froms Authentication Cookie
    //
    httpWebRequest.CookieContainer.Add(new Cookie(FormsAuthentication.FormsCookieName, formsAuthenticationCookie, "/", httpWebRequest.RequestUri.Host));

    // Get response
    HttpWebResponse httpWebResponse = (HttpWebResponse)httpWebRequest.GetResponse();

    if (httpWebResponse.StatusCode == HttpStatusCode.OK)
    {
        trace.Write("Response: 200 ");
        trace.WriteLine(httpWebResponse.StatusCode);
    }
    else
    {
        trace.Fail("Response status is " + httpWebResponse.StatusCode + ". Expected was OK");
    }

    trace.WriteLine("Response will be the connectionXml");
    trace.WriteLine("");

    string connectionXml;

    using (StreamReader streamReader = new StreamReader(httpWebResponse.GetResponseStream()))
    {
        connectionXml = streamReader.ReadToEnd();
    }

    trace.WriteLine("connectionXml " + connectionXml);

    return connectionXml;
}

As shown above, RemoteApp and Desktop Connection provides an easy way to customize the standard look and feel of RD Web Access or to present remote resources in new ways.

RemoteApp for Hyper-V

Today, we want to talk about a little known feature in Windows Server 2008 R2 that could be described as RemoteApp for Hyper-V. Like Microsoft RemoteApp, it allows users to access a specific hosted application remotely, as opposed to the entire desktop. With RemoteApp, the application runs in the context of a server session; however, RemoteApp for Hyper-V enables remote access to an application running in a Hyper-V VM.

With the advent of Windows 7, some enterprise customers were facing application compatibility issues with line-of-business applications that were specifically written for Windows XP and would not work on Windows 7.

One obvious way to resolve this issue is to run those incompatible applications in Windows XP Mode, a new feature that is available in certain Windows 7 SKUs and which simplifies migration to the new OS by allowing legacy XP applications to seamlessly run in their own context within a Windows 7 environment. Windows XP mode has specific hardware, OS and memory requirements. While this solution works well on newer machines with hardware virtualization support, the hardware requirements for XP mode might be prohibitive for some older PCs.

RemoteApp for Hyper-V allows users to remotely access Windows XP applications from their Windows 7 desktop with no additional hardware requirements.

  • SKU support: RemoteApp for Hyper-V is supported on the following SKUs running as the guest OS:
    • Windows XP SP3: Professional
    • Windows Vista SP1 and above: Enterprise and Ultimate
    • Windows 7: Enterprise and Ultimate

Here are some examples of applications that will benefit from this feature:

    • Applications that are compatible only with Windows XP SP3
    • Applications that can run on Windows Server 2003, but not Windows Server 2008 or Windows Server 2008 R2
    • Applications that are supposed to be run only on a data center server for data security or compliance reasons

To use this feature, a user connects remotely from a client computer to the VM-hosted application. To host the applications, an administrator sets up a virtual machine with a guest OS on a Hyper-V server hosting the virtual machine.

The client computer must run Windows 7, but the guest OS on the virtual machine can run Windows XP SP3, Windows Vista (with SP1 and above) or Windows 7. For a guest OS running Windows XP SP3, an update is required; for a guest OS running Windows Vista SP1 or above, another update is needed.

  • So, how can an administrator deploy this?

There are two ways in which RemoteApp for Hyper-V can be deployed. The first way is the stand-alone scenario, in which all the administrator needs to do is set up a Hyper-V server with virtual machines running a client OS (for example, Windows XP SP3). The administrator would then set up the application and create RDP files that launch this application. A user can connect to the application via a simple Remote Desktop connection using the RDP file.

Here’s how this setup would look:
RemoteApp on HyperV -setup1

While this is a simple setup that an administrator can use to pilot the RemoteApp for Hyper-V, it offers no extra efficiency or ability to load balance. One serious drawback of this method is that since only one user can connect to an application at a time, one user connecting to multiple virtual machines effectively blocks out other users.

To get around this problem, the recommended way to install RemoteApp for Hyper-V is over a complete VDI farm or personal virtual desktop setup, including setting up the RD Connection Broker role. An administrator would still need to perform the same manual steps of setting up the application and creating an RDP file, but there are significant advantages to going through the RD Connection Broker. An obvious one is load balancing. In addition, there is increased efficiency, simply because when a user is connected to a virtual machine, all applications launched by that user are redirected to the same virtual machine. Only one user can connect to applications running on a particular virtual machine at a time.

One single user cannot block out an entire farm by holding onto different virtual machines on it at the same time. Until a user’s virtual machine is terminated, redirection is always to the same VM. RD Connection Broker ensures that a user connected to a VM stays connected until logged out.

Here’s how the second setup scenario described above would look (running from a Windows XP SP3 farm, for instance):
RemoteApp on HyperV-setup2

Hosting applications in a farm of virtual machines running Windows XP SP3 is a simple way to give multiple people on the domain access to the applications. There is no security filtering for applications on a virtual machine farm. All domain users who have access to the farm will have access to the applications.

If an administrator wants to give only a specific user access to an application, the application should be hosted on a personal desktop. In all cases--farms or personal desktops--an administrator only needs to create an RDP file and hand it over to a user, either via a network share or email.

RemoteApp for Hyper-V is a basic but powerful platform capability which was designed with advanced administrators in mind who are willing to do the manual configuration steps to enable an environment that includes remote access to VM-hosted applications. It serves also as an extensibility point for our RDS partner ecosystem who may want to take advantage of this infrastructure capability and provide additional value-add to RDS customers by streamlining the configuration and expanding the usability and manageability of it. For example, with additional code, it is possible to integrate the RDP files with Remote Desktop Web Access.

Related links:

Update package for Windows XP SP3:

http://www.microsoft.com/downloads/details.aspx?FamilyID=2f376f53-83cf-4e5b-9515-2cb70662a81b&displaylang=en

Update package for Windows Vista SP1 or above:

http://www.microsoft.com/downloads/details.aspx?familyid=097B7478-3150-4D0D-A85A-6451F32C459C&displaylang=en

Deploying Windows Vista or Windows XP as the guest operating system in a Virtual Machine

Overview

The purpose of this post is to help an Administrator configure a Windows Vista or Windows XP operating system in a virtual machine for a Remote Desktop Services Virtual Desktop Infrastructure (VDI) deployment.

This post is an addendum to the Step 2: Installing and Configuring the Virtual Machine section for the following Step-by-Step guides published in Microsoft ®TechNet:

  1. Deploying Virtual Desktop Pools by Using Remote Desktop Web Access Step-by-Step Guide.
  2. Deploying Virtual Desktop Pools by Using RemoteApp and Desktop Connection Step-by-Step Guide.
  3. Deploying Personal Virtual Desktops by Using Remote Desktop Web Access Step-by-Step Guide.
  4. Deploying Personal Virtual Desktops by Using RemoteApp and Desktop Connection Step-by-Step Guide.

Additional Steps required to support Windows Vista and Windows XP

The following steps need to be completed before the Configure the virtual machine for Remote Desktop Services section in the guides mentioned above.

  1. Choose supported operation system: Install the supported version of the Windows Vista or Windows XP as the guest operating system. The following link contains the reference to the list of various supported versions of Windows Vista or Windows XP.
  2. Install Integration Services component: Follow the instructions here at Step 4: To install the integration services on the virtual machine.
  3. Only for Windows XP: Install PowerShell package: Follow the instructions here to install this package. This step is not needed if you are using VBS script for configuring the guest operating systems.

    The following steps need to be completed before moving on the Step 3 in the guides mentioned above.
  4. Only for Windows XP: Restart the Windows XP machine.

Additional Resources

  1. Configure Guest OS for Microsoft VDI using Powershell: http://gallery.technet.microsoft.com/ScriptCenter/en-us/bd2e02d0-efe7-4f89-84e5-7ad70f9a7bf0
  2. Configure Guest OS for Microsoft VDI using VB Script: http://gallery.technet.microsoft.com/ScriptCenter/en-us/68462b23-0890-4dbd-95b6-8de5763e4f68)
    Note: If you choose to use the VB Script to automate configuring the settings, then you can skip Step# 3 in the section above.

Windows Server 2008 R2 Haiku Contest

The Windows Server team is running a Haiku contest for Windows Server 2008 R2.  Come up with the best Haiku, and you could win a Home Entertainment System.  See http://www.r2haiku.com/ to enter.

Maybe Remote Desktop Services will provide your inspiration!

Posted by termserv | 0 Comments

Personal Virtual Desktops

With Windows Server 2008 R2 we support two VDI deployment scenarios: virtual desktop pools and personal virtual desktops. The two scenarios present two different models of assigning virtual machines to end users: shared and dedicated. This blog post describes personal virtual desktops.

What is a personal virtual desktop? - A personal virtual desktop is a virtual machine hosted on a Remote Desktop Virtualization Host (RD Virtualization Host) server and assigned to a user. Unlike a virtual desktop pool, where a virtual machine can be configured to rollback the changes when a user logs off, a personal virtual desktop retains all changes made by the user.

How do you assign a personal virtual desktop? - The Remote Desktop Connection Broker Manager (RD Connection Broker Manager) can be used to assign an unassigned virtual machine to a user. The assignment is stored in Active Directory. The assignment stays intact even after the user logs off from his or her assigned personal virtual desktop. An administrator can reassign a personal virtual desktop or make changes to the assignment through RD Connection Broker Manager.

How do you access and log off from a personal virtual desktop? - Users can access their assigned personal virtual desktops through RemoteApp and Desktop Connections or RD Web Access. When a user clicks on the personal virtual desktop icon, Microsoft VDI solution prepares a pre-assigned virtual machine for a remote RDP connection. Whether the user has logged off or has a disconnected session he is assigned the same virtual machine each time.

Can a personal virtual desktop be made part of a virtual desktop pool? – No. It is a misconfiguration to add a virtual machine designated as a personal virtual desktop to a virtual desktop pool if the goal is to allow only the assigned user to access that virtual machine. When the designated user makes a connection to his personal virtual desktop which is now part of a virtual desktop pool, the connection will fail and a type mismatch event will be logged.

What is the cost of ownership of personal virtual desktops compared to virtual desktop pools? - Since there is a one-to-one mapping between a virtual machine and a user in the personal virtual desktop scenario, the initial cost and overall cost of ownership of a personal virtual desktop is higher than in the virtual desktop pool scenario in which virtual machines are shared between users.

How many personal virtual desktops can be assigned per user? – One. ISVs can extend the inbox solution and provide users access to more than one personal virtual desktop. Refer to: http://msdn.microsoft.com/en-us/library/dd401684(VS.85).aspx

Can the same Hyper-V server be used to deploy personal virtual desktops and virtual machines from virtual desktop pools? – Yes. It is not required to have personal virtual desktops isolated from virtual desktop pools.

For details on how to set up personal virtual desktops, refer to:

Technical Library

Microsoft Download Center

Deploying Personal Virtual Desktops by Using Remote Desktop Web Access Step-by-Step Guide (http://go.microsoft.com/fwlink/?LinkId=147909)

Deploying Personal Virtual Desktops by Using Remote Desktop Web Access Step-by-Step Guide (http://go.microsoft.com/fwlink/?LinkId=147908)

Deploying Personal Virtual Desktops by Using RemoteApp and Desktop Connection Step-by-Step Guide (http://go.microsoft.com/fwlink/?LinkId=154801)

Deploying Personal Virtual Desktops by Using RemoteApp and Desktop Connection Step-by-Step Guide (http://go.microsoft.com/fwlink/?LinkId=154800)

RemoteApp and Desktop Connection Management Extensibility for provisioning apps via RD Web Access

Earlier, we described publishing in Windows Server 2008 R2 and how RDP resources can be published by using the RemoteApp and Desktop Connection Management service to users in RD Web Access. This blog post describes the third-party extensibility support available in the RemoteApp and Desktop Connection Management service, and how third parties (Enterprises or ISVs) can leverage it to publish any resources (RDP or non-RDP) in Windows Server 2008 R2.

The RemoteApp and Desktop Connection Management service, which is part of the RD Connection Broker role service, is a new publishing feature in Windows Server 2008 R2. By default, the following three plug-ins are provided in the service:

  • LegacyTS plug-in: Aggregates RemoteApp programs from Remote Desktop Session Host servers.
  • VMFarm plug-in: Aggregates virtual desktop pools.
  • MyDesktop plug-in: Provides the user with the assigned personal domain desktop.

All three plug-ins provide only RDP files, in the following scenarios:

  • RDP files for RemoteApp programs
  • RDP files for virtual desktops in virtual desktop pools
  • RDP files for per-user assigned virtual desktops

In order to provide RDP or non-RDP files in any scenario other than the ones described above, you can write a plug-in to provide the list of resources, register it with the RemoteApp and Desktop Connection Management service, and display the resources in RD Web Access. For example, if you want to serve several different files (for example, some hand-crafted RDP files and some .osd (app-v) files that are on a physical drive on the machine running the RemoteApp and Desktop Connection Management service), you can write a simple plug-in that will aggregate the files from the location and pass them on to the service, which will then pass them on to RD Web Access. As a result, users will be able to access these files via the web page.

Writing a third-party plug-in

Create a DLL that implements the ItsPubPlugin COM interface as described here: http://msdn.microsoft.com/en-us/library/dd401684(VS.85).aspx

  • HRESULT  mySamplePlugin::GetResourceList(LPCWSTR userID, __out LONG *pceAppListSize, __deref_out_ecount(*pceAppListSize)pluginResource ** resourceList)
    
        typedef struct {
            WCHAR alias[256];
            WCHAR name[256];
            [string, unique] WCHAR *resourceFileContents;
            WCHAR fileExtension[24];
            WCHAR resourcePluginType[256];
            boolean isDiscoverable;
            long resourceType;
            unsigned long pceIconSize;
            [size_is(pceIconSize)] byte *iconContents;
            unsigned long pcePluginBlobSize;
            [size_is(pcePluginBlobSize)] byte *blobContents;
        } pluginResource;

 

This interface is the one that the RemoteApp and Desktop Connection Management service will call into, when a user request comes in, to get the list of resources.

  • STDMETHODIMP mySamplePlugin::GetResource(LPCWSTR alias, LONG flags, __out pluginResource * resource)

This interface is a placeholder and does not need to be implemented. You can simply return E_NOTIMPL.

  • STDMETHODIMP mySamplePlugin::GetCacheLastUpdateTime(__out unsigned long long * lastUpdateTime)

This interface is called by the RemoteApp and Desktop Connection Management service to get the last cache updated time. If you don’t plan to implement caching, returning the current system time in Windows File Time format for the lastUpdateTime will indicate to the service that it needs to call the GetResourceList function (discussed above) to get the latest list of resources, instead of using its cache. However, this is not the recommended way of implementing the plug-in because this will cause RD Web Access to not use its cache, which will cause more data to be transferred across the network and slow user response time. The recommended way to implement this routine is to return the latest time that a resource has changed.

  • STDMETHODIMP mySamplePlugin::get_pluginName(__deref_out BSTR * pVal)

This interface is used to get the plug-in name.

  • STDMETHODIMP mySamplePlugin::get_pluginVersion(__deref_out BSTR * pVal)

This interface is used to get the plug-in version.

  • STDMETHODIMP mySamplePlugin::ResolveResource(     __RPC__out DWORD *resourceType,
        __RPC__out_ecount_full_string(256) wchar_t resourceLocation[ 256 ],
        __RPC__out_ecount_full_string(256) wchar_t endPointName[ 256 ],
        __RPC__in_string wchar_t *userID,    __RPC__in_string wchar_t *alias)
     

This interface is used by the Remote Desktop Connection Broker service to resolve which virtual desktop is assigned to the user. It is not essential to have this implemented, and you can simply return E_NOTIMPL, unless you plan to have a custom implementation for providing the Personal Domain Desktop functionality.

Registering the third-party plugin:

After you have written the plug-in, complete the following steps:

  1. Register the plug-in.
    regsvr32 mySamplePlugin.dll
  2. Create the following registry entries:
    1. Create a sub-key under HKLM\software\Microsoft\Windows NT\CurrentVersion\TerminalServer\Centralized Publishing\ with the CLSID of the mySamplePlugin
    2. Create a DWORD under HKLM\software\Microsoft\Windows NT\CurrentVersion\TerminalServer\Centralized Publishing\{mySamplePlugin-CLSID} called IsEnabled and set it to 1. (Setting it to 0 is equivalent to disabling the plugin)
  3. The publishing service will pick up the registry changes automatically and restart the publishing service, or you can restart the publishing service manually by using the following command:
    net stop tscpubrpc & net start tscpubrpc

After completing these steps, you are finished creating the third-party plug-in. When a client connects, in addition to the enabled default plug-ins, the publishing service will also aggregate the applications provided by your own plug-in and display them in RD Web Access. Note that this will work only for the RD Web Access scenario. In order to make extensibility work in the RemoteApp and Desktop Connections scenario so that you can download the published applications onto your Start menu, you must complete some additional steps, which will be covered in the next post.

Per User CAL Reporting Script

We have introduced a script to help the administrators tracking the usage trend of Windows Server 2003 Terminal Server (TS) Per User (PU) client access licenses (CALs), total usage of Windows Server 2008 TS PU CALs (including expired), and the usage of Windows Server 2008 TS PU CALs for a list of specified domains.

The major scenarios addressed by the script includes the following -

  1. For a Windows Server 2003 TS, this script helps the administrators tracking the users logged in to a TS in PU licensing mode over a period of time.
  2. For a Windows Server 2008 TS or a Windows Server 2008 R2 Remote Desktop Session Host Server (RDSH), this script helps the administrator tracking both valid & expired PU CALs.
  3. For a license server running Windows Server 2008 or Windows Server 2008 R2, this script enables administrators to generate PU CAL usage details for a list of specified domains.
  4. For a license server running Windows Server 2008 or Windows Server 2008 R2, while generating the PU CAL usage report for a list of specified domains, even if one or more of the domains in the list is unreachable, this script will still report the usage for all the reachable domains.

For more detailed information, download the Per User Report Generation script from here. The batch script to execute the Per User Report Generation script periodically for a Windows Server 2003 TS is available at here.

Announcing the launch of Remote Desktop Services Script Center to ease management

Hi everyone. We have published scripts to help simplify Remote Desktop Services management—including Virtual Desktop Infrastructure (VDI) management. You can download these scripts from the Remote Desktop Services page on Script Center.

Here are some of the Remote Desktop Services management scripts that are available now:

Virtual machine management

Configure Guest OS for VDI (can be run as GP start-up script)

Virtual machine assignment management

Bulk assign virtual machines to users or pools

List VM assignment information

Infrastructure setup: RD Connection Broker cluster creation and management

Manage RD Connection Broker cluster (create, add nodes)

Update RD Connection Broker configuration across nodes in a cluster

Troubleshooting: Configuration verification

Others

Monitor sessions

Generate usage report

Deploy RemoteApp programs to the Start menu by using RemoteApp and Desktop Connection

Please visit the Script Center and try these scripts, and then let us know what you think. You can provide feedback either through the Comments section or the Discussion feature in Script Center.

You can also upload your scripts to Script Center. Click Upload on the right side of the Script Gallery home page and follow the simple process.

We’ll update this post when additional scripts are available. Keep watching this space.

More Posts Next page »
 
Page view tracker