XenDesktop 7 – Environment Test Service

If you’ve had a chance to review the XenDesktop 7 PowerShell SDK documentation, you might have noticed a few new snap-ins that provide the site interactions for the new services included with XenDesktop 7 (as part of the FlexCast Management Architecture). These new snapins are the designated as V1 on the cmdlet help site, and include StoreFront, Delegated Admin, Configuration Logging, Environment Tests, and Monitoring.

Out of these new services, the Environment Test Service sounds the most appealing to me, as it provides a framework to run pre-defined tests and test suites against a XenDesktop 7 site. However, I found that the SDK documentation didn’t provide much/any guidance on using this snap-in, so I thought I’d share a quick rundown on the meat of this new service, along with some sample scripts using the main cmdlets.

The most basic function of this service is to run predefined tests against various site components, configurations, and workflows. As of XD7 RTM, there are 201 individual TestID’s, which can be returned by running the Get-EnvTestDefinition cmdlet:

TestId 
------ 
Host_CdfEnabled 
Host_FileBasedLogging 
Host_DatabaseCanBeReached 
Host_DatabaseVersionIsRequiredVersion 
Host_XdusPresentInDatabase 
Host_RecentDatabaseBackup 
Host_SchemaNotModified 
Host_SnapshotIsolationState 
Host_SqlServerVersion 
Host_FirewallPortsOpen 
Host_UrlAclsCorrect 
Host_CheckBootstrapState 
Host_ValidateStoredCsServiceInstances 
Host_RegisteredWithConfigurationService 
Host_CoreServiceConnectivity 
Host_PeersConnectivity 
Host_Host_Connection_HypervisorConnected 
Host_Host_Connection_MaintenanceMode...

The tests are broken down into several functional groups that align with the various broker services, including Host, Configuration, MachineCreation, etc, and are named as such. For example, the test to verify that the site database can be connected to by the Configuration service is called Configuration_DatabaseCanBeReached.

Each test has a description of it’s function, and a test scope that dictates what type of object(s) can be tested. Tests can be executed against components and objects in the site according to the TestScope and/or TargetObjectType, and are executed by the service Synchronously or Aynchronously, depending on their InteractionModel. You can view all of the details about a test by passing the TestID to the Get-EnvTestDefinition cmdlet; for example:

PS C:> Get-EnvTestDefinition -TestId Configuration_DatabaseCanBeReached

Description : Test the connection details can be used to 
 connect successfully to the database.
DisplayName : Test the database can be reached.
InteractionModel : Synchronous
TargetObjectType : 
TestId : Configuration_DatabaseCanBeReached
TestScope : ServiceInstance
TestSuiteIds : {Infrastructure}

TestSuites are groups of tests executed in succession to validate groups of component, as well as their interactions and workflows. The Get-EnvTestSuite cmdlet returns a list of test suite definitions, and can be used to find out what tests a suite is comprised of. To get a list of TestSuiteIDs, for example, you can run a Get-EnvTestSuite | Select TestSuiteID, which returns all of the available test suites:

TestSuiteId 
----------- 
Infrastructure 
DesktopGroup 
Catalog 
HypervisorConnection 
HostingUnit 
MachineCreation_ProvisioningScheme_Basic 
MachineCreation_ProvisioningScheme_Collaboration 
MachineCreation_Availability 
MachineCreation_Identity_State 
MachineCreation_VirtualMachine_State 
ADIdentity_IdentityPool_Basic 
ADIdentity_IdentityPool_Provisioning 
ADIdentity_WhatIf 
ADIdentity_Identity_Available 
ADIdentity_Identity_State

Each of these suites can be queried using the same cmdlet, and passing the -TestSuiteID of the suite in question. Let’s take DesktopGroup as an example:

PS C:\> Get-EnvTestSuiteDefinition -TestSuiteId DesktopGroup

TestSuiteId         Tests 
-----------                  ----- 
DesktopGroup   Check hypervisor connection, Check connection maintenance mode, Ch...

One thing you’ll notice with the results of this cmdlet is that the list of tests are truncated, which is a result of the default stdout formatting in the PowerShell console. For that reason, my preferred method of looking at objects with large strings (ie descriptions) in PowerShell, is to view them in a graphical ISE (PowerGUI is my preference) and explore the objects in the ‘Variables’ pane.

For example, if you store the results of  Get-EnvTestSuiteDefinition -TestSuiteId DesktopGroup into a variable ($dgtest) in PowerGUI, each Test object that comprises the test suite can be inspected individually:

The DesktopGroup EnvTestSuite object

The DesktopGroup EnvTestSuite object

To start a test task, use the Start-EnvTestTask, passing the TestID or, alternatively, the TestSuiteID, and a target object (as needed). For example:

PS C:> Start-EnvTestTask -TestId Configuration_DatabaseCanBeReached

Active : False
ActiveElapsedTime : 11
CompletedTests : 1
CompletedWorkItems : 11
CurrentOperation : 
DateFinished : 9/16/2013 11:33:31 PM
DateStarted : 9/16/2013 11:33:20 PM
DiscoverRelatedObjects : True
DiscoveredObjects : {}
ExtendedProperties : {}
Host : 
LastUpdateTime : 9/16/2013 11:33:31 PM
Metadata : {}
MetadataMap : {}
Status : Finished
TaskExpectedCompletion : 
TaskId : 03f5480d-68e8-410a-9da4-5e65d96ac393
TaskProgress : 100
TerminatingError : 
TestIds : {Configuration_DatabaseCanBeReached}
TestResults : {Configuration_DatabaseCanBeReached}
TestSuiteIds : {}
TotalPendingTests : 1
TotalPendingWorkItems : 11
Type : EnvironmentTestRun

Once you know what tests there are, what they do, and what types of results to expect, health check scripts can easily be created using this service. Combinations of tests and test suites can, and should, be leveraged as needed to systematically validate XenDesktop 7 site components and functionality.

I plan on using these cmdlets to some extent in SiteDiag, and expect to get some good use out of this new service in the field. I’m interested to hear from anyone else who’s started using this snap-in, and if they’ve come up with any useful scripts.

Advertisements

NetScaler Gateway VPX v10.1 with StoreFront v2.0 – Encrypt and Theme!

I just finished up on a XenApp 6.5 upgrade where I replaced a single 2008R2 server running a DMZ’d CSG v3.2 SSL-proxied Citrix Web Interface v5.3 ‘Direct’ site with a NetScaler Gateway 10.1 Access Gateway virtual server and a StoreFront v2.0 Store.

This post is meant to share some tips on setting up and customizing a Citrix Receiver <> NetScaler Gateway <> StoreFront deployment. Before I get into the thick of it, I thought I’d share the following high-level topology of the environment I was working with:

XenApp65_SharedHostedDesktopDelivery

This scenario consists of WAN-connected Citrix Receivers accessing the XenApp farm via a NetScaler Gateway Access Gateway VPN fronted StoreFront Store. The NetScaler Gateway Access Gateway virtual server provides AD-auth via an LDAP Authentication policy, and replaces the SSL-Proxied ICA & HTTP traffic that the Secure Gateway server previously handled (EOL’d since ‘06!, yet running on Win2008R2??). The NG-AG virtual server also acts as the landing page for web browsers, and as such has it’s own visual style that can (and SHOULD) be customized. Receiver connections are passed through to the Store virtual directory, and all other connections (web browsers) are directed to the StoreWeb virtual directory.

One major consideration I found in this topology is that if your StoreFront ‘Store’ is not SSL-encyrpted, Citrix Receiver for Windows 3.1 and later will not work without tweaking a few client-side registry values (see CTX134341), even though the NetScaler Gateway session is encrypted. That said, a resultant consideration of securing the StoreFront site is that you need to be sure that the NetScaler trusts the StoreFront server’s SSL certificate.

To do this you need to install any of the StoreFront server’s certificate chain certs on the NetScaler (here’s a good Citrix blog on the topic) and make sure the Access Gateway session policy profile’s ‘Web Interface Address’ uses the same name that the StoreFront server’s certificate was issued to, and that the NetScaler can resolve the name via DNS. The other pieces of getting this setup working are pretty easy, thanks mostly in part to the foolproof NetScaler Gateway setup wizard (eDocs link), and StoreFront’s ‘Add NetScaler Gateway Appliance’ wizard (eDocs). As long as your SSL is working properly, this is a fairly painless install.

Once I got the site up and running, I immediately wanted to customize the NetScaler Gateway VPN web interface to make it look like the StoreWeb site that browser users are redirected to. Out of the box, the NG-AG site is themed with the old (boring) CAG visual style, which is themed to look like the old WI 5.0-5.3 black & blue sites. Since this page is proxying and for the StoreFront site, is makes for a very awkward, time-machinish, experience to login to the black and blue site, and land in StoreFront’s newer green bubble land!

I didn’t look hard to find Jeff Sani’s blog article that I’ve referenced many times before, which provides step-by-step instructions on applying the StoreFront look and feel to a NetScaler’s Access Gateway. After running through this, I decided to change the the logo and background, and referenced Terry D’s blog on customizing a StoreFront site by way of custom CSS. I used WinSCP and PuTTY to make the changes, and pretty quickly had a nice looking landing page to front the StoreFront Store:

CustomLandingPage

I then did the same on the StoreFront server using NotePad++, and was able to give the customer a customized and consistent look and by adding the following custom.style.css to the c:\inetpub\wwwroot\Citrix\StoreWeb\contrib folder of the StoreFront server:

body { background-image: url("custom.jpg");
  background-color: #262638;}
#credentialupdate-logonimage, #logonbox-logoimage 
{ background-image: url("custom.png");
  width: 180px;
  height: 101px;
  right: 63%;}
#.myapps-name 
{ font-weight: bold; color: #000; }

CustomStoreFrontWeb

Well, that’s about all the time I have for today. I hope someone finds this post helpful in producing a functional, and visually consistent, NetScaler Gateway fronted StoreFront deployment!

Exploring ShareFile’s ‘StorageZones’ Services

I was looking for more information on what makes a ShareFile StorageZone ‘tick’, and couldn’t find much that got into the nuts and bolts of this great feature. This post is intended to share some general information about the various StorageZones controller services, including their basic functionality, and some hidden configuration settings.

For the scope of this post, I’m going to focus on the three Windows services that are installed as part of a StorageZone v2.1 Controller. Each service is installed off the root of the IIS site as follows:

  • File Cleanup Service – Citrix\StorageCenter\SCFileCleanSvc\FileDeleteService.exe
  • File Copy Service – Citrix\StorageCenter\SCFileCopySvc\FileCopyService.exe
  • Management Service – Citrix\StorageCenter\s3uploader\S3UploaderService.exe

In each of these directories are the service’s .NET .config file, which can be modified to enable logging, and adjust hidden configuration settings. For example, if you open FileDeleteService.exe.config, you’ll see the following XML by default:

<?xml version="1.0"?>
<configuration>
   <appSettings>
       <add key="ProducerTimer" value="24"/> <!--Time interval in hours-->
       <add key="DeleteTimer" value="24"/> <!--Time interval in hours-->
       <add key="DeleteTimer" value="24"/> <!--Time interval in hours-->
       <add key="Period" value="7"/> <!--No. of days to keep data blob in active storage after deletion-->
       <add key="logFile" value="C:\inetpub\wwwroot\Citrix\StorageCenter\SC\logs\delete_YYYYMM.log"/>
       <add key="enable-extended-logging" value="0"/>
       <add key="BatchSize" value="5000"/></appSettings>
<startup><supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0"/></startup></configuration>

As you might have guessed, setting enable-extended-logging  to 1 will enable verbose logging after the service is restarted, writing to the specified logFile path. This setting is the same for the other services, and can come in handy when troubleshooting issues with a StorageZone.

In order to really understand what these services were doing, I decided to poke through the source code by decompiling the services’ assemblies using a free utility called DotPeek. Here’s a summary of what I found for each service’s functionality within a StorageZone Controller.

File Cleanup Service (FileDeleteService)

The name says it all here, as this service’s sole responsibility is managing data deletion from the storagezone storage repository. Since all of the data stored by ShareFile is in BLOB format, deleting a file through the ShareFile front-end doesn’t actually delete it from the storage; it simply ‘de-references’ the data, and marks it as ‘expired’.

This ‘expired’ data will remain in the storage repository until it’s ‘cleaned up’ by the File Cleanup Service. This is why if you look at a folder’s recycle bin, you’ll see the files are still listed and available for recovery until the configurable cleanup period lapses (7 days by default).

Citrix recommends configuring this cleanup period to match the backup schedule of your storage device so that data is removed shortly before or after they’re backed up. This design also allows for data to be recovered even if it’s not in the recycle bin, by using the “Recover Files” function in the StorageZone section of ShareFile’s Admin page.

Here are the .config extended settings for this service, along with their default values:

  • ProducerTimer = 24 Time interval in hours 
  • DeleteTimer = 24  Time interval in hours
  • Period = 7 Number of days to keep data in active storage after deletion

File Copy Service (SCFileCopySvc)

This service is what allows the StorageZones controller to communicate with ShareFile’s cloud infrastructure (by way of the ShareFile API), and allows users to upload and download files directly to and from a customer’s on-premise storage.

When a file is uploaded, ShareFile’s servers connect to the controller through this service to initiate an HTTP(S) POST request, allowing the data to be stored directly to the StorageZone. The service also converts files to and from the ShareFile’s proprietary format, converting files to BLOB data for uploads, and converting BLOB data back to the original file for downloads.

The service also has a configurable timer value (the default is 10 seconds key=”CopyTimer” value=”10000″ ) that controls how often retries are attempted for jobs that previously failed due to connectivity issues.

Management Service (S3Uploader)

Last but not least, the poorly named Management Service, which only really ‘manages’ transferring files to and from Amazon’s S3 cloud storage service. This service uses Amazon’s AWS SDK for .NET to take care of the data transfer, and is what allows you to migrate data to and from ShareFile’s storage, and the StorageZone.

There are a couple of configurable settings for this service as well; here they are with their default values:

  • httpMethod = https Transport method; secure or non-secure
  • HeartBeat-Interval = 5 Interval in minutes
  • Recovery-Interval = 3600 Interval in seconds

Well, I hope this post is useful for anyone who is using, or planning on using, ShareFile’s StorageZones feature. Feel free to share any other insights or thoughts in the comments!

XenDesktop Session Launch Hypervisor Interactions

I got an email recently asking if I knew whether or not a XenDesktop site takes a hosting unit’s load or availability into consideration when brokering session launch requests, especially reconnects to desktops that were ‘In Use’ when a host goes down. This question was posed in the context of Desktop Groups with catalogs that are spread across multiple hosting units.

The simple answer to this question is no. XenDesktop’s interactions with the hypervisor (via the Hypervisor Abstaction Layer) were always intended to be used for power action/status, and MCS/PVS related cloning activities. When a XenDesktop site selects a ‘worker’ to fulfill a session launch request, it only looks at the worker’s registration status, and not that of the host that the worker guest VM is running on.

That said, the selection process for the next available worker is determined via stored procedures. To find out what the ‘next available’ worker is going to be in a XenDesktop 5.x site, you can run following T-SQL against the database, specifying the Desktop Group UID in the first line:

declare @DesktopGroupUid int = 1
declare @Readiness int = 3
declare @Uid int

 update Top(1) chb_State.Workers
 set @Uid = W.Uid
from chb_State.Workers W
            with (readpast,
                  index(IX_Workers_DesktopGroupUid_Usage_DynamicSequence))
         where DesktopGroupUid = @DesktopGroupUid
           and LaunchReadiness >= @Readiness
           and SinBinReleaseTime is null;select * from chb_State.WorkerNames
where Uid = @Uid
go

This script will return the name of the machine that the site will use to satisfy the next pooled-random session launch request to the specified desktop group, and doesn’t care what’s going on with the hosting unit where the worker lives. The site is only concerned with the worker’s registration state, and could care less if the power state of the VM is On, Off, or Unknown, much less does it care about the load of the hosting unit where that machine is running.

To that point, if a worker continues to register when a hosting unit connection becomes inaccessible (vCenter is down, but not the ESX host, for example), the desktop will still be available for session launch, but not for power management. This scenario can cause problems, such as ‘tainted’ workers that don’t get powered off after use, and end up in the unfortunate sounding ‘SinBin’. This process is only temporary, and is only corrected after the machine is rebooted by the XenDesktop site (check out the CTX article I wrote for more info).

As far as a scenario where a session was ‘In Use’ when the host goes down, the broker reaper site service will eventually clean up the failed worker when the ‘DDC Ping’ times out (controlled by the ‘HeartbeatPeriodMs’ value on the DDC running the reaper service). So, by default, you could potentially get into a situation where reconnects for ‘In Use’ session will keep selecting the failed worker until the reaper cleans it up. While this shouldn’t take longer than 5 minutes with the default heartbeat value, it may cause problems if there are frequent outages or service interruptions between geographically dispersed datacenters.

To work around the ~5 minute functionality gap of hosting unit availability awareness, as it relates to session launch anyways, one could easily trigger a XenDesktop PoSH script in the event of an outage (and the reverse when the outage is recovered) to toggle the ‘maintenance mode’ flag on any workers on a failed host. I’d like to hope that the XenDesktop product team has at least considered the potential for expanding the site’s visibility into the status of a guest VM’s host, and would love to see ‘smarter’ brokering logic such as thing in future releases.

XenDesktop 7 – First Thoughts

Citrix hosted an amazing event last week, and outlined a distinct roadmap of their 2013 strategy. They placed a strong emphasis on mobility with some updates to their Zenprise acquisition (XenMobile, aka Worx), and announced the first implementation of Project Avalon in the form of ‘XenDesktop 7’. Since I’ve spent a lot of time with XenDesktop (both IMA and Storm based) and XenApp, I thought I’d share my general impression of XenDesktop 7 as it relates to achieving the goals set forth by Avalon.

First off, the unification of XenDesktop and XenApp was a necessary evil based on Citrix’s decision to combine the management and provisioning of  ‘desktops’ & ‘servers’ (SBC and VDI) within the same console. Through what Citrix is calling the ‘FlexCast Management Architecture’ (Storm+RDS), they are replacing ‘IMA’, which was used for all versions of XenApp, as well as XenDesktop versions prior to Rhone (Barossa, Sonoma, Rioja, Bordeaux, Medoc, etc.).

This change is a great move in terms of farm design, scalability, and stability. In my opinion, the Storm framework is easier to install, troubleshoot, and support than IMA (written in .NET, readable database, excellent SDK, better logging, etc), and should be familiar to anyone who has worked with XenDesktop 5.x. The site is just as dependent on availability of the central database as in XD5 (no local host cache), which means no zones, data collectors, or any other sort of ‘master’ server (the database is the master). All of the same ICA/HDX functionality is still there (plus any new additions), as is the policy engine and brokering functionality.

I’m not too fond of the licensing model which provides published Windows client OS in the least expensive edition, whereas Windows server OS requires a more expensive license. I suppose that’s representative of Citrix choosing to call Excalibur XenDesktop instead of XenApp, though I never really thought of this distinction since I assumed it was called XenDesktop because they used the Storm site architecture (now called FMA). I’m also concerned about feature parity with XenApp, and am sure there will be more than a few features that either don’t live up to XenApp, or just aren’t there yet.

At the end of the day I’m excited about XenDesktop 7, as it provides an easier product to sell. There’s no more worrying about whether or not you need to publish apps from Windows client or server OS (besides the licensing), and all of the management and provisioning (except for Provisioning Services :)) is done in a central console. The new Director looks fantastic, and the refreshed Studio is much more responsive and elegant than that of XenDesktop 5. Also, my SiteDiag tool (Site Checker v2.0) was designed to run on the Excalibur tech preview, and I’ll be sure to get it working for XenDesktop 7 once its released.

I get the feeling that the rest of the Citrix community is generally as excited about XenDesktop 7 as I am, but I guess we’ll see how it plays out once we start implementing it!

XML Broker Health Check

I saw an interesting question in the Citrix support forum today, and thought I’d share. Scott Curtsinger asked the following:

Does anyone know what the easiest way is to check the health of the XML service on XenDesktop 5.6? I’m seeing a lot of information on the web for XenApp but not very much for XenDesktop beyond leveraging devices like a NetScaler.

My first instinct is that this could easily be done via PowerShell, so I did a quick search and found this blog post by Jason Pettys. I also found this great article on working with the Citrix XML service, and quickly put together the following script which I tested against my XenDesktop 5.6 XML broker:

$url = "http://localhost/scripts/wpnbr.dll"
$parameters = '<?xml version="1.0" encoding="utf-8"?><!DOCTYPE NFuseProtocol SYSTEM "NFuse.dtd"><NFuseProtocol version="5.1"><RequestCapabilities></RequestCapabilities></NFuseProtocol>'
$http_request = New-Object -ComObject Msxml2.XMLHTTP
$http_request.open('POST', $url, $false)
$http_request.setRequestHeader("Content-type", "text/xml")
$http_request.setRequestHeader("Content-length", $parameters.Length)
$http_request.setRequestHeader("Connection", "close")
$http_request.send($parameters)
$http_request.statusText
$http_request.responseText

Running this script in PowerShell on my XML broker returned the following list of capabilities, which is a good indication that the XML broker is up and running:

<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE NFuseProtocol SYSTEM "NFuse.dtd"> <NFuseProtocol version="5.1"> <ResponseCapabilities> <CapabilityId>separate-credentials-validation</CapabilityId> <CapabilityId>multi-image-icons</CapabilityId> <CapabilityId>launch-reference</CapabilityId> <CapabilityId>user-identity</CapabilityId> <CapabilityId>full-icon-data</CapabilityId> <CapabilityId>full-icon-hash</CapabilityId> <CapabilityId>accepts-client-identity-for-power-off</CapabilityId> <CapabilityId>session-sharing</CapabilityId> </ResponseCapabilities> </NFuseProtocol>

This simple script lays a nice foundation to perform XML broker health checks via PoSH. I then took the script a little bit further to test some other XML requests:

param($server, $port)
if ($port){$port = 80}
$creds = Get-Credential
$domainuser= $creds.UserName.Split('\')
$domain = $domainuser[0]
$user = $domainuser[1]
[String]$pw = [Runtime.InteropServices.Marshal]::PtrToStringAuto([Runtime.InteropServices.Marshal]::SecureStringToBSTR($creds.Password))
$nwINFO = Get-WmiObject -ComputerName $env:COMPUTERNAME Win32_NetworkAdapterConfiguration | Where-Object { $_.IPAddress -ne $null }
$ip = $nwINFO.IPAddress
$fqdn = $nwINFO.DNSHostName
$xmlcreds = '<Credentials><UserName>' + $user + '</UserName><Password encoding="cleartext">' + $pw + '</Password><Domain Type="NT">' + $domain + '</Domain></Credentials>'
$envelope = '<?xml version="1.0" encoding="utf-8"?><!DOCTYPE NFuseProtocol SYSTEM "NFuse.dtd"><NFuseProtocol version="5.1">'
$clienttype = '<ClientType>ica30</ClientType>'
$clientdetails = '<ClientName>' + $env:COMPUTERNAME + '</ClientName><ClientAddress addresstype="dot">' + $ip[0] + '</ClientAddress>'
function request ($parameters)
{
 $http_request = New-Object -ComObject Msxml2.XMLHTTP
 $http_request.open('POST', $url, $false)
 $http_request.setRequestHeader("Content-type", "text/xml")
 $http_request.setRequestHeader("Content-length", $parameters.Length)
 $http_request.setRequestHeader("Connection", "close")
 $http_request.send($parameters)
 $http_request.statusText
 $http_request.responseText
}
$url = "http://" + $server + ":" + $port + "/scripts/wpnbr.dll"
$capabilities = request ($envelope + '<RequestCapabilities></RequestCapabilities></NFuseProtocol>')
if (!$capabilities[1].contains('error'))
{
 $testcreds = request ($envelope + '<RequestValidateCredentials>' + $xmlcreds + '</RequestValidateCredentials></NFuseProtocol>')
 if (!$testcreds[1].contains('bad'))
 {
 $appdatareq = request ($envelope + '<RequestAppData><Scope traverse="subtree"></Scope><DesiredDetails>rade-offline-mode</DesiredDetails><ServerType>all</ServerType>' + $clienttype + '<ClientType>content</ClientType>' + $xmlcreds + $clientdetails + '</RequestAppData></NFuseProtocol>')
 $app = $appdatareq[1] -split "<FName>"
 $app = $app[1] -split "</FName>"
 $launchreq = request ($envelope + '<RequestAddress><Name><AppName>' + $app[0] + '</AppName></Name>' + $clientdetails + '<ServerAddress addresstype="dns-port"></ServerAddress>' + $xmlcreds + $clienttype + '</RequestAddress></NFuseProtocol>')
 $launchreq
 }
}

This script takes the server and port, prompts for the credentials that you’re testing (password is sent in clear text), and sends a RequestCapabilities request, followed by RequestValidateCredentials, RequestAppData, and RequestAddress requests. To avoid dependencies on NFuse.dtd, I used a -split on the XML results of the RequestAppData results to get the ‘friendly name’ of the first application returned by RequestAppData, which I used for the RequestAddress post.

From here I’m going to develop a C# service that can monitor the XML service, though I’d like to figure out how to encode the password into the ‘ctx1’ format so that I’m not sending it in clear text.

Citrix ‘Local App Access’ Explained

I wanted to share some details on this feature that was introduced in XenApp 6.5 that I don’t think many people are aware of, even though the changes that were introduced to support it affect anyone using Reciever 3.X, XenDesktop 5.5+, and XenApp 6.5. In this post I’m going to attempt to explain the basic functionality that ‘Local App Access’ (LAA) provides, and the basics of how it works.

If any of you are familiar with RES software, they’ve been providing a platform agnostic ‘Reverse Seamless’ functionality for some time via their Virtual Desktop Extender product. Here’s a short video that gives you a good idea of what the challenges reverse seamless aims to solve:

As you can see, the purpose of a ‘reverse seamless’ window is to give users the ability to run local application windows within a remote desktop session. In XenApp 6.5 and XenDesktop 5.5+, this functionality is built-in by way of processes running on the client (redirector.exe) AND server (revseamlesslauncher.exe & vdaredirector.exe) that enumerate, launch, and handle local windows within a published desktop session.

The easiest way to see this functionality in action is to follow the steps listed in the Quick Start Guide for Local App Access and Integrating Local User Applications in XenApp 6.5. The gist of it is that published desktops that are presented using the Citrix ‘Desktop Viewer’, can be ‘Local App Access’ enabled by setting an ICA parameter, and allowing the virtual channel on the client side, which is disabled by default.

Once everything is configured and the ‘Local App’ shortcut is available on the desktop, you should be able to double click the LAA application to run it seamlessly within the published desktop session. The reason that the ‘Desktop Viewer’ is required is that it’s responsible for managing the Z-order of the LAA app within the seamless published desktop window.

The way that Citrix is able to present ‘reverse seamless’ windows is not that different from how they present regular ‘seamless’ windows, which is by injecting API hooks into all client side processes, which allows them to inject the necessary identifiers for Desktop Viewer to be able to detect and handle the window within the ICA session.

Another major feature included with LAA is the ability to redirect URLs to the local internet browser which is automatically launched as a reverse seamless window by way of an IE browser helper object that’s installed on both the client and server. This is useful for instances where a local browser can overcome challenges of screen painting, such as rich media that can’t otherwise be redirected, or security/location nuances that require the browser to be running on the client endpoint device.

I hope this brief rundown of LAA was useful, definitely let me know if you have any trouble getting it to work in your environment.