XenDesktop

Citrix XenDesktop/XenApp 7.15 – The local host cache in action

2017-11-29
/ /
in Blog
/

The Citrix Local Host Cache feature, introduced in XenDesktop/XenApp 7.12, has some nuances that maybe better demonstrated in realtime then typed out in text.  I will do both in this article to share both a ‘step by step’ of what happens when you have a network or site database outage and what occurs as well as a realtime video highlighting the feature in action.  There are many other blogs and articles that do a great job going into the step by step details of the feature but I find seeing it in action to be very informative.

To view a video of this process, scroll to the very end, or click here.

To start, I’ve created a powershell script that simulates a user querying the broker for a list of applicaitons.

Columns are time of the response, the payload size received (in bytes) and the total time to respond in milliseconds.

As we’re querying the broker, the broker is reaching out to the database and then responding to the user with the information requested.

 

Periodically, the Citrix Config Synchronizer Service will check to ensure the local host cache database is in sync with the site database. This is an event that occurs every 2 minutes during normal operation.

To show the network connection failing, I am going to setup a continuous ping to the database server

To simulate a network failure, I’m going to use the tool clumsy to drop all packets to and from the database server.

Clicking start in clumsy immediately stops the simulated user from getting their list of applications.

 

And the ping’s now time out in their requests.

The broker has a 20 second time out that after which it will respond to requests with what it thinks is the current status. The first timed out request receives a response of “working” and then thereafter a response of “pending failed” will be returned

Around 24 seconds the broker has noticed the database has failed and has logged it’s first event, 1201, “The connection between the Citrix Broker Service and the database has been lost”

Now one-minute thirty three seconds into the failure, other Citrix services are now reporting they cannot contact the database.

Just shy of 2 minutes, the broker service has now exceeded it’s timeout for contacting the database and is in the process of switching to the local host cache. It stops the “primary broker”.

And then the Citrix High Availability Service comes active, brokering user requests.

In my simulation the amount of time it took the user to receive a response from the LHC is a little faster than the site database. The LHC response time is 80-90 milliseconds where the response time for a request that includes the site database is 90-100. This information allows us to visually see the two different modes of operation in action.

Top, site database response times – middle is the outage – bottom is LHC response times

How long does it take to “fall back” to the database when connectivity is restored?

I “Stopped” clumsy to restore our network connection and started a timer.

 

We can see the ping responses from the database immediately to verify our connection is back.

 

Almost immediately, all services have noticed that they have connectivity again, including the broker service.

However, we do not fall back immediately.

At one minute thirty three seconds the broker has switched back to the primary broker. And all services have been restored.

To watch a video of this all in action, please view here:

 

 

Read More

Citrix Storefront – Adventures in customization – Define a custom resolution for a specific application

2017-11-14
/ /
in Blog
/

Currently, Storefront does not grant the ability to define applications with specific resolutions.  In order to configure the resolution, Citrix recommends you modify the default.ica file.  This is terrible!  If you had specific applications that required specific resolutions, what are you to do?  Direct users to a variety of stores depending on the resolution required?!

Fortunately, again, we can extend StoreFront to make it so we can configure custom resolutions for different applications on the same store.  The solution is a Storefront extension I’ve already written.

The steps to set this up:

  1. Download the Storefront_CustomizationLaunch.dll.
  2. Copy the file to C:\inetpub\wwwroot\Citrix\Store\bin
  3. Edit the web.config in the Store directory and enable the extension
  4. We need to enable Header pass-through for DesiredHRES, DesiredVRES, and TWIMode in the “C:\inetpub\wwwroot\Citrix\StoreWeb\web.config” file:
  5. Lastly, add the following to the custom.js file in your StoreWeb/custom folder:
  6. And enjoy the results!  🙂

Read More

Citrix Storefront – Adventures in customization – Dynamically configure workspace control based on group membership

2017-05-07
/ /
in Blog
/

I’ve been exploring the customization capabilities of Citrix Storefront and have some exciting ideas on simplifying our deployment.  What I’d really like is to reduce our store count down to a as few stores as possible.  In our Web Interface we have multiple stores based on the non-configurable settings.  They are:

  • Workspace Control Enabled with Explicit Logon
  • Workspace Control Disabled with Explicit Logon
  • Workspace Control Enabled with Domain Passthrough authentication
  • Workspace Control Disabled with Domain Passthrough authentication
  • Anonymous site

We can’t mix and match authenticated sites and anonymous sites (right?… ?) but Citrix does offer the ability to configure Authentication methods AND Workspace Control options via their ‘Receiver Extension API’s’.

These are the API’s in question:

There isn’t really a whole lot of documentation on them and how to use them.  Richard Hayton has created the Citrix Customization Cookbook which details some examples of some of the API’s.  He has several blog articles on the Citrix website that have varying degrees of applicability.  Unfortunately, he hasn’t blogged in over a year on this topic as it feels like the situation has changed a bit with the Citrix Store API’s available as well (note: these are different!).

My target is to make it so these options can be set dynamically based on the users group membership.  If you’re a member of the group ‘workspaceControlEnabled’ you get all the settings set to true, if you’re a member of ‘workspaceControlDisabled’ you get all the settings set to false.

Seems like a pretty straightforward goal?

So I thought I’d start with something pretty simple.  I have a store with Workspace Control Enabled, with show ‘Connect and Disconnect’ buttons selected:

If I log into the site:

I see everything (as I should).

So let’s start with a simple customization.  Let’s try using the API to disable these options.  I created a totally blank script.js file and added the following lines:

Now what does our menu look like?

Awesome!  Workspace Control was disabled by script!

So I said I want to disable Workspace Control if you are a member of a specific group.  Richard Hayton actually wrote a pretty good article on creating a service to facilitate grabbing your group membership with Storefront.  Unfortunately, the download link is dead.  So I wrote another PowerShell HTTP listener that takes an input and queries AD for that user and their membership, and returns a positive value if workspace control should be enabled, or a negative value if it should be disabled.  To get it to query though, it needs a value.  The best value for this, I thought, would be the user name.

Citrix provides a function to get the username and I can then pass it to my webservice, test for group membership and return whether Workspace Control (WSC) should be enabled or disabled.

I wrote my first bit of code and it crashed immediately.  I simply entered it straight into my script.js.

In order to trace the error, you simply enter “#-tr” to the end of your store URL:

and allow pop-ups.  A new tab will open allowing you to follow the ‘flow’ of Storefront as it executes its commands.  Mine crashed at:

“get username data:”

And it makes sense why it crashed there.  I haven’t even logged in yet so it has no idea who or how to get the username so it looks like Storefront just returns the login page.  We need to call our functions after logging in.

Citrix provides the following event-based functions we can hook into:

Notifications of progress

preInitialize(callback)
postInitialize(callback)
postConfigurationLoaded()
postAppListLoaded()

Note that during these calls, the UI may be hidden in native Receivers, so it is not safe to show UI
For APIs passing a callback, you MUST call the callback function, though you may delay calling it until code of your own has run.

beforeLogon(callback)

Web browsers only. Called prior to displaying any logon dialogs. You may call ‘showMessage’ here, or add your own UI.

beforeDisplayHomeScreen(callback)

All clients, called prior to displaying the main UI. This is the ideal place to add custom startup UI.
Note that for native clients, the user may not have logged in at this stage, as some clients allow offline access to the UI.

afterDisplayHomeScreen()

All clients, called once the UI is loaded and displayed. The ideal place to call APIs to adjust the initial UI, for example to start in a different tab.

So the question becomes, when does each of these get called?  We are only interested in the ones after you login.  To determine this, I hooked into each one and just did a simple trace command and then refreshed my browser to the login screen.

This is where I stopped:

And trace tab results:

These 4 stages are called before the user logs on so they are of no use to me:

preInitialize
postInitialize
postConfigurationLoaded
beforeLogon

The order of the other 3 after logon:

beforeDisplayHomeScreen
postAppListLoaded
afterDisplayHomeScreenStage

Before adding my code to the post-logon event functions I just added it back -plain jane- and rerun with a trace:

What I found is these extensions appear to have a fixed entry order point.  The workspace control extensions cannot be called after “beforeDisplayHomeScreen” stage.  If you do not call the workspace control extensions before the callback on the ‘beforeDisplayHomeScreen’ function you will be unable to control the setting.  The trace log in my screenshot for these extensions will always occur at this point in time regardless if you actually set it in ‘preInitialize, postInitialize, postConfigurationLoaded, or beforeLogon’.  And if you attempt to set it in either of the two later functions it will not log anything and your code has no effect.  So the only point in time where I can take the username and set these values are in the event function beforeDisplayHomeScreen.

<Digress>

During the course of my testing this feature I had thought about adding a button that would allow you to toggle this feature ‘enabled or disabled’ on your own whim.  But it appears once you call the Extension it’s a one and done.  I also discovered that it appears you must set the workspace control feature early in the process.  If I set it in postAppListLoaded or afterDisplayHomeScreen nothing happened.  To be fair, I do not know how to reinitialize the menu, maybe that would allow it to kick in dynamically…?  I guess that’s for further exploration on another day…

</Digress>

Ok, so we’ve found the one and only functional place we can execute our code.  So I added it.

 

The result?  Nothing.  Nothing happened.

Well, that’s not entirely true.

I’ve highlighted in yellow/orange my “getUsername” function.  We can see on line 35 we get into the function.  And on line 67 it is successfully finding and returning my name.  But the problem is that it’s getting that information after the point in time that we can set the WSC features (highlighted in blue — line 60-62).

I found that using ajax for this command and attempting to use async was causing my failure.  I understand it’s bad practice to do synchronous commands, especially in javascript as they will lock the UI while executing, but, thus far it’s the only way I know to ensure it gets completed in the proper order.  I am really not a web developer so I don’t know what’s the proper technique here to send a couple ajax requests that only blocks at the specific point in time that WSC kicks in…  Or find a way to redraw the menu?  But for the purposes of getting this working, this is the solution I’ve chosen to go with.  I’m wide open to better suggestions.  The real big extension that would be an issue is the ‘webReconnectAtStartup’.  This feature will reconnect any existing sessions you have and the way that Citrix currently implements it, they want it run as soon as the UI is displayed.  This makes some sense as that’s the whole point.  You don’t want to wait around after logging in some indeterminate or random amount of seconds for your session to reconnect…  But, this issue can be alleviated.  Citrix actually offers a way to implement this feature yourself via the Store API so we could implement our own custom version of this function that would get all your sessions and reconnect them…

Which could just leave building the menu as something that could be moved back to async if I can figure out how to rebuild it or build it dynamically…

Anyway, that maybe for another day.  For today, the following works for my purpose.

This is my custom/script.js file that I finished from this blog post:

 

Here is the LDAP_HttpListener.psm1

Lastly, the scheduled task to call the listener:

 

 

 

 

Read More

Citrix Storefront – Pass URI parameters to an application

2017-05-01
/ /
in Blog
/

In my previous post, I was exploring taking URI parameters and passing them to an application.

The main issue we are facing is that Storefront launches the ica file via an iframe src.  When launching the ica via this method the iframe does a simple ‘GET’ without passing any HEADER parameters — which is the only (documented) way to pass data to Storefront.

What can I do? I think what I need to do is create my own *custom* launchica command.  Because this will be against an unauthenticated store we should be able remove the authentication portions AND any unique identifiers (eg, csrf data).  Really, we just need the two options — the application to launch and the parameter to pass into it.  I am NOT a web developer, I do not know what would be the best solution to this problem, but here is something I came up with.

My first thought is this needs to be a URL that must be queried and that URL must return a specific content-type.  I know Powershell has lots of control over specifying things like this and I have some familiarity with Powershell so I’ve chosen that as my tool of choice to solve this problem.

In order to start I need to create or find something that will get data from a URL to powershell.  Fortunately, a brilliant person by the name of Steve Lee solved this first problem for me.

What he created is a Powershell module that creates a HTTP listener than waits for a request. We can take this listener and modify it so it listens for our two variables (CTX_Application and NFuseAppCommandLine) and then returns a ICA file.  Since this is an unauthenticated URL I had to remove the authentication feature of the script and I added a function to query the real Storefront services to generate the ICA file.

So what I’m envisioning is replacing the “LaunchIca” command with my custom one.

 

This is my modification of Steve’s script:

And the command to start the HTTP listener:

Eventually, this will need to be converted to a scheduled task or a service.  When running the listener manually, it looks like this:

 

I originally planned to use the ‘WebAPI’ and create a custom StoreFront, but I really, really want to use the new Storefront UI.  In addition, I do NOT want to have to copy a file around to each Storefront server to enable this feature.  So I started to wonder if it would be possible to modify Storefront via the extensible customization API’s it provides.  This involves adding javascript to the “C:\inetpub\wwwroot\Citrix\StoreWeb\custom\script.js” and modifying the “C:\inetpub\wwwroot\Citrix\StoreWeb\custom\style.css” files.  To start, my goal is to mimic our existing functionality and UI to an extent that makes sense.

The Web Interface 5.4 version of this web launcher looked like this:

When you browse to the URL in Web Interface 5.4 the application is automatically launched.  If it doesn’t launch, “click to connect” will launch it for you manually.  This is the function and features I want.

Storefront, without any modifications, looks like this with an authenticated store:

So, I need to make a few modifications.

  1. I need to hide all applications that are NOT my target application
  2. I need to add the additional messaging “If your application does not appear within a few seconds, click to connect.” with the underlined as a URL to our launcher.
  3. I want to minimize the interface by hiding the toolbar.  Since only one application will be displayed we do not need to see “All | Categories   Search All Apps”
  4. I want to hide the ‘All Apps’ text
  5. I want to hide “Details”, we’re going to keep this UI minimal.

The beauty of Storefront, in its current incarnation, is most of this is CSS modifications.  I made the following modifications to the CSS to get my UI minimalized:

This resulted in a UI that looked like this:

So now I want to remove all apps except my targeted application that should come in a query string.

I was curious if the ‘script.js’ would recognize the URI parameter passed to Storefront.  I modified my ‘script.js’ with the following:

Going to my URL and checking the ‘Console’ in Chrome revealed:

Yes, indeed, we are getting the URI parameters!

Great!  So can we filter our application list to only display the app in the URI?

Citrix offers a bunch of ‘extensions’.  Can one of them work for our purpose?  This one sounds interesting:

Can we do a simple check that if the application does not equal “CTX_Application” to exclude it?

The function looks like this:

Did it work?

Yes!  Perfectly!  Can we append a message to the application?  Looking at Citrix’s extensions this one looks promising:

Ok.  That warning sucks.  My whole post is based on StoreFront 3.9 so I cannot guarantee these modifications will work in future versions or previous versions.  Your Mileage May Vary.

So what elements could we manipulate to add our text?

Could we add another “p class=storeapp-name” (this is just text) for our messaging?  The onAppHTMLGeneration function says it is returned when the HTML is generated for an app, so what does this look like?

I added the following to script.js:

And this was the result in the Chrome Console:

So this is returning an DomHTMLElement.  DOMHTMLElements have numerous methods to add/create/append/modify data to them.  Perfect.  Doing some research (I’m not a web developer) I found that you can modify the content of an element by this style command:

This results in the following:

We have text!

Great.

My preference is to have the text match the application name’s format.  I also wanted to test if I could add a link to the text.  So I modified my css line:

The result?

Oh man.  This is looking good.  My ‘click to connect’ link isn’t working at this point, it just goes to google, but at least I know I can add a URL and have it work!  Now I just need to generate a URL and set that to replace ‘click to connect’.

When I made my HTTPListener I purposefully made it with the following:

The reason why I had it set to share the url of the Citrix Store is the launchurl generated by Storefront is:

The full path for the URL is actually:

So the request actually starts at the storename.  And if I want this to work with a URL re-write service like Netscaler I suspect I need to keep to relative paths.  So to reach my custom ica_launcher I can just put this in my script.js file:

and then I can replace my ‘click to connect’ link with:

The result?

The url on the “click to connect” goes to my launcher!  And it works!  Excellent!

Now I have one last thing I need to get working.  If I click the ‘Notepad 2016 – PLB’ icon I get the regular Storefront ica file, so I don’t get my LongCommandLine added into it.  Can I change where it’s trying to launch from?

Citrix appears to offer one extension that may allow this:

Huh.  Well.  That’s not much documentation at all.

Fortunately, a Citrix blog post came to rescue with some more information:

Hook APIs That Allow Delays / Cancellations

doLaunch
doSubscribe
doRemove
doInstall

On each of these the customization might show a dialog, perform some checks (etc) but ultimately should call ‘action’ if (and only if) they want the operation to proceed.

This extension is taking an object (app).  What properties does this object have?  I did a simple console.log and examined the object:

Well, look that that.  There is a property called ‘launchurl’.  Can we modify this property and have it point to our custom launcher?

I modified my function as such:

The result?

A modified launchurl!!!!

Excellent!

And launching it does return the ica file from my custom ica_launcher!

Lastly, I want to autolaunch my program.  It turns out, this is pretty simple.  Just add the following the script.js file:

Beautiful.  My full script.js file looks like so:

And that’s it.  We are able to accomplish this with a Powershell script, and two customization files.  I think this has a better chance of ‘working’ across Storefront versions then the SDK attempt I did earlier, or creating my own custom Storefront front end.

Read More

Citrix StoreFront – Experiences with Storefront Customization SDK and Web API

2017-04-24
/ /
in Blog
/

Our organization has been exploring upgrading our Citrix environment from 6.5 to 7.X.  The biggest road blocks we’ve been experiencing?  Various nuanced features in Citrix XenApp 6.5 don’t work or are not supported in 7.X.

This brings me to this post and an example of the difficulties we are facing, my exploration of solutions to this problem, and our potential solution.

In Citrix Web Interface 5.1+ you can create a URI with a set of application launch parameters and those parameters would be passed to the application.  This is detailed in this Citrix article here (CTX123998).  For us, these launches occur with a Site (WI5.4 terminology) or Store (Storefront terminology) that allows anonymous (or unauthenticated) users.

By following that guide and modifying your Web Interface you can change one of your sites so that it accepts launch parameters.  You simply enter a specific URI in your browser, and the application would launch with said parameters.  An example:

http://bottheory.local/Citrix/XenApp/site/launcher.aspx?CTX_Application=Citrix.MPS.App.XenApp.Notepad&LaunchId=1263894298505&NFuse_AppCommandLine=C:\Windows\WindowsUpdate.log

This allows you to send links around to other people and they can click to automatically launch an application with the parameters specified.  If you are really unlucky, your org might document this as an official way to launch a hosted application and this actually gets coded into certain applications.  So now you may have tens of local apps utilizing this as an acceptable method to launch a hosted application.  For an organization, this may be an acceptable way to launch certain hosted applications since around ~2008 so this “feature”, unfortunately, has built up quite a bit of inertia.

We can’t let this feature break when we move to StoreFront.  We track the number of launches from these hosted applications and it’s in the hundreds/thousands per day.  This is a critical and well used feature.

So how does this work in Web Interface and what actually happens?

URI substitution and launch process

The modifications that you apply add a new ‘query’ to the URI that is picked up.  This ‘query’ is “NFuse_AppCommandLine” and the value it is equal to (“C:\Windows\WindowsUpdate.log” in my example) is passed into the ICA file.

The ICA file, when launched, will pass the parameter to a special string “%**” the is set on the command line of the published application.  This token “%**” gets replaced by the parameter specified in the ICA which then generates the launch string.  This string is executed and the result is the program launches.

Can we do this with Storefront?  Well, first things first, is this even possible with XenApp/XenDesktop 7.X?  In order to test this I created an application and specified the special token.

I then generated an ICA file and manually modified the LongCommandLine to add my parameter.  I then launched it:

 

Did it work?

Yes, it worked.

Success!  So XenApp/XenDesktop 7.X will substitute the tokens with the LongCommandLine in the ICA file.  Excellent.  So now we just need Storefront to take the URI and add it to the LongCommandLine.  Storefront does not do this out of the box.

However, Citrix offers a couple of possible solutions to this problem (that I explored).

StoreFront WebAPI
StoreFront Store Customization SDK

What are these and how do they work?

StoreFront Web API

This API is billed as:

“Write a new Web UI or integrate StoreFront into your own Web portal”

We are going to need to either modify Storefront or write our own in order to take and parameters in the URI.  I decided to write our own.  Using the ApiExample.html in the WebAPI I added the following:

This looks into the URI and allows you to get the value of either query string.  In my example I am grabbing the values for “CTX_Application” and “NFuse_AppCommandLine”.

I then removed a bunch of the authentication portions from the ApiExample.html (I’ll be using an unauthenticated store).  In order to automatically select the specified application I added some javascript to check the resource list and get the launch URL:

There is a function within the ApiExample.html file that pulls the ICA file.  Could we take this and modify it before returning it with the LongCommandLine addition?  We have the NFuse_AppCommandLine now.

It turns out, you can. You can capture the ICA file as a variable and then using javascripts ‘.replace’ method you can modify the line so that it contains your string.  But how do you pass the ICA file to the system to launch?

This is how Citrix launches the ICA file in the ApiExample.html:

It generates a URL then sets it as the src in the iframe.  The actual result looks like this:

The ICA file is returned in this line:

When we capture the ICA file as a variable the only way that I’ve found you can reference it is via a blob.  What does the src path look like when do that?

Ok, this looks great!  I can create an ICA file than modify it all through WebAPI and return the ICA file to the browser for execution.  Does it work?

Yes and no. 🙁

It works in Chrome and Firefox, but IE doesn’t auto-launch.  It prompts to ‘save’ a file.  Why?  IE doesn’t support opening ‘non-standard’ blobs.  MS offers a method called “msSaveOrOpenBlob” which you can use instead, and this method then prompts for opening the blob.  This will work for opening the ICA file but now the end user requires an extra step.  So this won’t work.  It needs to be automatic like its supposed to be for a good experience.

So WebAPI appears to offer part of the solution.  We can capture the nFuse_AppCommandLine but we need to get it to LongCommandLine.

At this point I decided to look at the StoreFront Store Customization SDK.  It states it has this ability:

Post-Launch ICA file—use this to modify the generated ICA file. For example, use this to change ICA virtual channel parameters and prevent users from accessing their clipboard.

That sounds perfect!

StoreFront Store Customization SDK

The StoreFront store customization SDK bills one of its features as:

The Store Customization SDK allows you to apply custom logic to the process of displaying resources to users and to adjust launch parameters. For example, you can use the SDK to control which apps and desktops are displayed to users, to change ICA virtual channel parameters, or to modify access conditions through XenApp and XenDesktop policy selection.

I underlined the part that is important to me.  That’s what I want, exactly!  I want to adjust launch parameters.

To start, one of the tasks that I need is to take my nFuse_AppCommandLine and get it passed to the SDK.  The only way I’ve found to make this happen is to enable ‘forwardedHeaders‘ in your web.config file.

With this, you need to set your POST/GET Header on your request to Storefront to get this parameter passed to the SDK.  Here is how I setup my SDK:

Install the “Microsoft Visual Studio Community Edition” on a test StoreFront server.

 

Download the StoreCustomizationSDK and open the ‘Customization_Launch’ project file:

 

Right-click ‘Customization_Launch’ and select ‘Properties’.

 

Modify the Outpath in Build to the “%site%\bin” location.  This is NOT the %site%Web, but just the %site%.

Open the LaunchResultModifer.cs

 

Set a breakpoint somewhere in the file.

Build > Build ‘Customization_Launch’

Ensure the build was successful:

If you get an error message:

Just ignore it.  We’re compiling a library and not an executable and that’s why you get this message.

Now we connect to the debugger to the ‘Citrix Delivery Services Resources’.  Select ‘Attach to Process…’

Select the w3wp.exe process whose user name is ‘Citrix Delivery Services Resources’.  You may need to select ‘Show processes from all users’ and click ‘ Attach.

Click ‘Attach’.

Browse to your website and click to launch an icon:

Your debugger should pause at the breakpoint:

And you can inspect the values.

At this point I wasn’t interested in trying to re-write the ApiExample.html to get this testing underway, I instead used PowerShell to submit my POST’s and GET’s.  Remember, I’m using an unauthenticated store so I could cut down on the requests sent to StoreFront to get my apps.  I found a script from Ryan Butler and made some modifications to it.  I modified it to remove the parameters since I’m doing testing via hardcoding 🙂

Executing the powershell script and examining a custom variable with breakpoint shows us that our header was successfully passed into the file:

Awesome!  So can we do something with this?  Citrix has provided a function that does a find/replace of the value you want to modify.  To enable it, we need to add it the ICAFile.cs:

Browse to ICAFile.cs

 

At this point we can use the helper methods within the IcaFile.cs.  To do so, just add “using Examples.Helpers;” to the top of the file:

I cleaned out the HDXRouting out of the file, grabbed the nFuseAppCMDLine header, and then returned the result:

The result?

Success!  We’ve used the WebAPI and the StoreFront Customization SDK to supply a header, modify the ICA file, and return it with the value needed!  The ICA file returned works perfectly!  Ok, so I’m thinking this looks pretty good right?!  We just need to get the iframe to supply a custom header when the src gets updated.

Except I don’t think it’s possible to tag a custom header when you update a src in an iframe.   So then I started thinking maybe I can use a cookie!  If I can pass a cookie into the Storefront Customization SDK I could use that instead of the header.  Unfortunately, I do not see anyway to query a custom cookie or pass a custom cookie into the SDK.  Citrix appears to have (rightfully!) locked down Storefront that this doesn’t seem possible.  No custom cookies are passed into the httpcontext (that I can see).

So all this work appears to be for naught (outside of an exercise on how one could setup and customize Storefront).

 

But what about the Storefront feature “add shortcuts to websites“?

Although doing that will allow to launch an app via a URL, it doesn’t offer any method to pass values into the URL.  So it’s a non-starter as well.

Next will be a workaround/solution that appears to work…

Read More

Citrix Netscaler 11.1 Unified Gateway and a non-working Citrix HTML5 Receiver

2016-12-06
/ /
in Blog
/

We setup a Citrix Unified Gateway for a proof of concept and were having an issue getting the HTML5 Receiver to connect for external connections.  It was presenting an error message: “Citrix Receiver cannot connect to the server”.  We followed this documentation.  It states, for our use case:

What would probably help is having a proxy that can parse out all websocket traffic and convert to ICA/CGP traffic without any need of changes to XA/XD. Netscaler Gateway does exactly this… …NetScaler Gateway also doesn’t need any special configuration for listening over websockets…

Connections via NetScaler Gateway:

…When a gateway is involved, the connections are similar in all Receivers. Here, Gateway acts as WebSocket proxy and in-turn opens ICA/CGP/SSL native socket connections to backend XenApp and XenDesktop. …

…So using a NetScaler Gateway would help here for ease of deployment. Connection to gateway is SSL/TLS and gateway to XenApp/XenDesktop is ICA/CGP….

And additional documentation here.

WebSocket connections are also disabled by default on NetScaler Gateway. For remote users accessing their desktops and applications through NetScaler Gateway, you must create an HTTP profile with WebSocket connections enabled and either bind this to the NetScaler Gateway virtual server or apply the profile globally. For more information about creating HTTP profiles, see HTTP Configurations.

Ok.  So we did the following:

  1. We enabled WebSocket connections on Netscaler via the HTTP Profiles
  2. We configured Storefront with HTML5 Receiver and configured it for talking to the Netscaler.

And then we tried launching our application:

We started our investigation.  The first thing we did was test to see if HTML5 Receiver works at all.  We configured and enabled websockets on our XenApp servers and then logged into the Storefront server directly, and internally.  We were able to launch applications without issue.

The second thing we did was enable logging for HTML5 receiver:

To view Citrix Receiver for HTML5 logs

To assist with troubleshooting issues, you can view Citrix Receiver for HTML5 logs generated during a session.

  1. Log on to the Citrix Receiver for Web site.
  2. In another browser tab or window, navigate to siteurl/Clients/HTML5Client/src/ViewLog.html, where siteurlis the URL of the Citrix Receiver for Web site, typically http://server.domain/Citrix/StoreWeb.
  3. On the logging page, click Start Logging.
  4. On the Citrix Receiver for Web site, access a desktop or application using Citrix Receiver for HTML5.

    The log file generated for the Citrix Receiver for HTML5 session is shown on the logging page. You can also download the log file for further analysis.

This was the log file it generated:

The “Close with code=1006” seemed to imply it was a “websocket” issue from google searches.

 

The last few events prior to the error are “websocket” doing…  something.

I proceeded to spin up a home lab with XenApp and a Netscaler configured for HTML5 Receiver and tried connecting.  It worked flawlessly via the Netscaler.  I enabled logging and took another look:

So there is a lot of differences but we focus on the point of failure in our enterprise netscaler we see it seems to retry or try different indexes (3 in total, 0, 1 and 2).

So there is a lot of evidence that websockets seem to be culprit.  We have tried removing Netscaler from the connection picture by connecting directly to Storefront and HTML5 receiver works.  We have configured both Netscaler and Storefront (with what we think) is a correct configuration.  And still we are getting a failure.

I opened up a call to Citrix.

It was a fairly frustrating experience.  I had tech’s ask me to go to “Program Files\Citrix\Reciever” and get the receiver version (hint, hint, this does not exist with HTML5).  I captured packets of the failure “in motion” and they told me, “it’s not connecting to your XenApp server”.  — Yup.  That’s the Problem.

It seems that HTML5 is either so new (it’s not now), so simple (it’s not really), or tech’s are just poorly trained.  I reiterated to them “why does it make 3 websocket connections on the ‘bad’ netscaler? Why does the ‘good’ netscaler appear to connect the first time without issue?”  I felt the tech’s ignore and beat around the bush regarding websockets and more focus put on the “Storefront console”.  Storefront itself was NOT logging ANYTHING to the event logs.  Apparently this is weird for a storefront failure.  I suspected Storefront was operating correctly and I was getting frustrated we weren’t focusing on what I suspected was the problem (websockets).  So I put the case on hold so I could focus on doing the troubleshooting myself instead of going around in circles on setting HTML5 to “always use” or “use only when native reciever is not detected”.

Reviewing the documentation for the umpteenth time this “troubleshooting connections” tidbit came out:

Troubleshooting Connections:

In cases where you are not able to connect some of the following points might help in finding out the problem. They also can be used while opening support case or seeking help in forums:

1) Logging: Basic connection related logs are logged by Receiver for HTML5 and Receiver for Chrome.

2) Browser console logs: Browsers would show errors related to certificates or network related failures here.

  • Receiver for HTML5: Open developer tools for HDX session browser tab. Tip: In Windows, use F12 shortcut in address bar of session page.

  • Receiver for Chrome: Go to chrome://inspect, click on Apps on left side. Click on inspect for Citrix Receiver pages (Main.html, SessionWindow.html etc)

The browser may show a log?  I wish I would have thought of that earlier.  And I wish Citrix would have put that in the actual “Receiver for HTML5” documentation as opposed to buried in a blog article.

So I opened the Console in Chrome, launched my application and reviewed the results:

We finally have some human readable information.

Websocket connections are failing during the handshake “Unexpected response code: 302”

What heck does 302 mean?  I installed Fiddler and did another launch withe Fiddler tracing:

 

I highlighted the area where it tells us it’s attempting to connect with websockets.  We can see in the response packet we are getting redirected, that’s what ‘302’ means.  I then found a website that lets you test your server to ensure websockets are working.  I tried it on our ‘bad’ netscaler:

 

Hitting ‘Connect’ left nothing in the log.  However, when I tried it with my ‘good’ netscaler…

 

It works!  So we can test websockets without having to launch and close the application over and over…

 

So we started to investigate the Netscaler.  We found numerous policies that did URL or content redirection that would be taking place with the packet formulated like so.  We then compared our Netscaler to the one in my homelab and did find one, subtle difference:

The one on the left is showing a rule for HTTP.REQ.URL.CONTAINS_ANY(“aaa_path”) where the one on the right just shows “is_vpn_url”.  Investigating further it was stated that our team was trying to get AAA authentication working and this was an option set during a troubleshooting stage.  Apparently, it was forgotten or overlooked when the issue was resolved (it was not applicable and can be removed).  So we set it back to having the “is_vpn_url” and retried…

It worked!  I tried the ‘websockets.org’ test and it connected now!  Looking in the Chrome console showed:

 

Success!  It doesn’t pause on the websocket connection and the console logging shows some interesting information.  Fiddler, with the working connection, now displayed the following:

Look!  A handshark response!

 

So, to review what we learned:

  1. Connections via Netscaler to HTML5 reciever do NOT require  (but is possible) a SSL connection on each target XenApp device
  2. Connection via Netscaler work over standard port (2598/1494) and do not require any special configuration on your XenApp server.
  3. You can use ‘http://www.websocket.org/echo.html’ to test your Netscaler to ensure websockets are open and working.
  4. Fiddler can tell you verbose information on your websocket connection and their contents.
  5. The web browser’s Javascript console is perfect to look at verbose messages in HTML5.

 

And with that, we are working and happy, Good Night!

Read More

Troubleshooting Citrix Desktop Service – “The Citrix Desktop Service is starting.” and then nothing.

2015-09-21
/ /
in Blog
/

I’m troubleshooting an issue with the Citrix Desktop Service on my home lab.  I have a Citrix XenApp/XenDesktop 7.6 installation and I have setup a Server 2012 R2 box with the “/servervdi”.  Upon reboot, I see the Registration State as Unregistered.

Restarting the Citrix Desktop Service and checking the ‘Application’ Log for ‘Citrix Desktop Service’ yields only event ID 1028 – “The Citrix Desktop Service is starting.”

However, when I ‘Stop’ the Citrix Desktop Service the Application event log gives up a few more details:

Event ID 1003 – Citrix Desktop Service
The Citrix Desktop Service failed to initialize communication services required for interaction between this machine and delivery controllers. 

If the problem persists please perform a ‘repair’ install action or reinstall the Citrix Virtual Desktop Agent. Refer to Citrix Knowledge Base article CTX119736  for  further information. 

Error details: 
Failed to start WCF services. Exception ‘Object reference not set to an instance of an object.’ of type ‘System.NullReferenceException’

Unfortunately, this CTX article gives little to no details on event 1003 and is more of a shotgun attempt at solving issues as opposed to a nice, precise, surgical solution.

From the EventID 1003 we can see the Citrix Desktop Service is trying to reference WCF services and it has failed.

Citrix offers a tool called XDPing to try and diagnose issues, I ran it and had it return the following:

Googling the WCF errors with HTTP/1.1 and Error 503 results in lots of information on reconfiguring your IIS.  I’m not convinced this is the issue so I soldiered on…

When I procmon on ‘BrokerAgent.exe’ I see a few curious entires that maybe associated with ‘System.NullReferenceException‘ (aka, not found) and those are some permissions stating that access is denied to some registry keys and/or some ‘Name Not Found’ on some CLSID items.

During this capture I can see a ‘BrokerAgent.config’ file referenced.  (“C:\Program Files\Citrix\Virtual Desktop Agent\BrokerAgent.exe.config” ) Diving into it reveals some additional logging we can enable:

Verbose logging disabled by default

If we ‘enable’ the debug portions and create the C:cdsLogs folder we can get some more information on what is going wrong.

Logging Enabled

Stopping the ‘Citrix Desktop Service’, editing the .config file, creating the C:\cdslogs folder and starting the service yielded additional information.

We have a ‘COM exception’.  The nice thing about this log file is we can compare the time stamps to the procmon logs and determine what was happening when this failed.

It appears we are missing SCService64.exe from our Citrix installation.  What is ‘SCService64.exe’?  The registry tells me it’s the ‘IStackControl Type Library’.  Which matches up with the error ‘ConnectToStackControlCOMServer’.

So, it appears we need to install SCService64.exe.  I do not know why or how it went missing but I suspect we can copy it over or extract from the Citrix source files if needed.

To extract the SCService64.exe source file, we can create an administrative installation of the “TS” VDA:

msiexec /a “\x79-serversoftwareCitrixXenApp_and_XenDesktop7_6x64Virtual Desktop ComponentsTSIcaTS_x64.msi”
This makes a folder on the root of the C: called “Citrix” which installs all the files there:

I installed the Citrix VDA “WS” with /servervdi for some testing, but prior to that I had the regular “TS” VDA installed.  Perhaps some combination of my installation/uninstallation caused my issues.

Anyways, copying the SCService64.exe to the C:\Program Files (x86)\Citrix\System32 folder and restarting the ‘Citrix Desktop Service’ resulted in…

Registered, Hurray!

And what about our log file?

Previously it died around ‘Setting up ALL LaunchManager WCF service’; this time we see:

Hurray!  It continues and operates without issue.

Be sure to re-disabled the logging on the BrokerAgent.config file and restart the service because I’ve found this BA_1.log can get to become a huge file.

Running XDPing this time results in [OK] across where the errors once were.

Read More

Performance differences in Citrix HDX Thinwire Encoders

2015-09-04
/ / /

Per my previous post, changing the Citrix HDX Thinwire Encoder on the fly, we can test the performance differences in the different encoder’s Citrix provides.  I have done so by running through a demo of the Uniengine Heaven benchmark.  The demo is exactly 4 minutes and 20 seconds long.  I did a perfmon trace of the CPU %, total bytes sent in MBits/sec and the Thinwire Output in MBit/sec.

Time for some results!

Compatibility Mode (Encoder 0x0)

DeepCompressionV2Encoder (Encoder 0x1)

DeepCompressionEncoder (Encoder 0x2)
(Rollover the mouse on the next images to compare graphs)

CompatibilityMode vs DeepCompressionV2Encoder

CompatibilityMode vs DeepCompressionEncoder

DeepCompressionV2Encoder vs DeepCompressionEncoder

The cumulative totals should help us get an understanding of the differences between the encoders:

   CPU Total ThinWire Total Network Total (Mbytes)
DeepCompressionEncoder 5531.00 3693.28 540.51
DeepCompressionV2Encoder 5621.67 3684.75 539.74
CompatibilityMode 4197.54 3690.58 553.21
   CPU Total ThinWire Total Network Total (Mbytes)
DeepCompressionEncoder 98.4% 100.0% 97.7%
DeepCompressionV2Encoder 100.0% 99.8% 97.6%
CompatibilityMode 74.7% 99.9% 100.0%
Interestingly, CompatibilityMode uses 25% less CPU then either DeepCompression Encoder.  From what I see though the frames per second appears less for CompatibilityMode then the other two.
Read More

Citrix XenApp, OpenGL pass-through and Nvidia GRID cards on Amazon EC2 (G2 Instances)

2015-09-01
/ / /

I’m attempting to do a Proof of Concept (POC) for a client and one of the ideas was to utilize the Amazon EC2 cloud to provide GPU instances to the users for their applications (Maya, SolidWorks, etc.).  In order to understand how GPU sharing works, I setup my home lab to take advantage of these features first, in order to understand how it operates.

Citrix provides documentation on setting up the GPU sharing.  For my test, I’m doing this on a bare metal Citrix server.  Essentially, the notes state that OpenGL is automatically shared and enabled and special steps must be taken for DirectX, OpenCL, CUDA and Windows Server 2012.  To enable GPU sharing for XenApp for these features, the following registry file will enable these:

Windows Registry Editor Version 5.00
Windows Registry Editor Version 5.00
[HKEY_LOCAL_MACHINE\SOFTWARE\Citrix\CtxHook\AppInit_Dlls\Graphics Helper]
“DirectX”=dword:00000001
[HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Citrix\CtxHook\AppInit_Dlls\Graphics Helper]
“DirectX”=dword:00000001
[HKEY_LOCAL_MACHINE\SOFTWARE\Citrix\CtxHook\AppInit_Dlls\Multiple Monitor Hook]
“EnableWPFHook”=dword:00000001
[HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Citrix\CtxHook\AppInit_Dlls\Multiple Monitor Hook]
“EnableWPFHook”=dword:00000001
[HKEY_LOCAL_MACHINE\SOFTWARE\Citrix\CtxHook\AppInit_Dlls\Graphics Helper]
“CUDA”=dword:00000001
[HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Citrix\CtxHook\AppInit_Dlls\Graphics Helper]
“CUDA”=dword:00000001
[HKEY_LOCAL_MACHINE\SOFTWARE\Citrix\CtxHook\AppInit_Dlls\Graphics Helper]
“OpenCL”=dword:00000001
[HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Citrix\CtxHook\AppInit_Dlls\Graphics Helper]
“OpenCL”=dword:00000001

In addition to this registry file, for Server 2012, the following Group Policy object is required:

  • On Windows Server 2012, Remote Desktop Services (RDS) sessions on the RD Session Host server use the Microsoft Basic Render Driver as the default adapter. To use the GPU in RDS sessions on Windows Server 2012, enable the Use the hardware default graphics adapter for all Remote Desktop Services sessions setting in the group policy Local Computer Policy > Computer Configuration > Administrative Templates > Windows Components > Remote Desktop Services > Remote Desktop Session Host > Remote Session Environment.

My initial setup is a Q87M-E system with a Intel 4771 and onboard graphics.  My system is setup with Windows 2012 R2 with Citrix XenApp 7.6.

Launching an ICA session to the XenApp 7.6 server results in:

 

 

We have OpenGL working, DirectX 11, and OpenCL (the onboard Intel GPU’s do not support CUDA).  So we have a full, working implementation of GPU sharing in a ICA session on a XenApp server.

But the onboard Intel graphics card will not get the me the performance I want.  I had a Nvidia GTX 670 video card on hand to see if I can get better 3D performance.  I installed that card in the system, installed the video drivers and checked the results.

 

Where did my OpenGL go?  Everything else is working correctly; Direct3D, CUDA, OpenCL, but not OpenGL.  My understanding from Nvidia is that OpenGL should just be ‘passed through’ by Citrix.  I know that it *does* pass-through because we, literally, just saw it with the onboard Intel GPU and the Intel drivers.

My next thought is maybe it had to do with the drivers?  Maybe if I tried the Quadro drivers?  It turns out Nvidia has released special Quadro drivers that enable OpenGL in a RDP session. Maybe if I modified the INF to add my GTX670 to these special drivers I could get OpenGL to work?

 

It did not work.  OpenGL remained disabled in RDP/ICA sessions.

Suspecting Nvidia is doing some form of detection that is disabling OpenGL (it’s probably considered a ‘pro’-feature) I acquired a Quadro FX5800 and using the *same* modified Quadro drivers, these were my results:

 

OpenGL is now working!!

Ok, so, at this point I know how to enable GPU sharing for Citrix XenApp, I know how to check and verify it’s functionality, and I know that different Nvidia cards can have OpenGL enabled or disabled but am not sure if it’s the driver that matters or the hardware.  If it’s the hardware I’m a bit surprised Intel would incorporate hardware accelerated OpenGL into ICA sessions for their consumer pieces but Nvidia would not for their discrete cards.  To *attempt* to test this I went and got the oldest driver I could find that would support a FX5800:

Sure enough, it works.

My last thought is maybe Nvidia has it hard coded somewhere to check for a string or a specific ‘type’ of video card and, if found, enable OpenGL?

My thinking is that the Nvidia drivers are doing some kind of detection and making a determination between a console session and all others.  If I’m lucky, maybe they only implemented this in their *newer* drivers, maybe after they started the RDS OpenGL acceleration…

To test this theory I went and grabbed the oldest driver I could find for my GTX 670 that would work on Windows 2012R2.  327.23.

 

Well now…  OpenGL is working.  This is interesting.  And leads evidence that OpenGL is being disabled in ICA via the driver.  I attempted to find when OpenGL *stopped* working.

331.82 –> Works, and now with OpenGL 4.4

337.88  -> Works

340.52 -> No OpenGL.  This driver (340.52) is now the first gaming driver *After* the “OpenGL on RDS release” (340.43).  It appears something on or after the 340.XX branch is disabling OpenGL in ICA sessions.

At the same time I was testing my Nvidia gaming GPU on my home lab, I was testing Amazon.  The GPU instance that Amazon provides utilize the Nvidia GRID K520 card as a vGPU.  This card is marketed as a ‘GRID Gaming‘ card.  I setup this instance with Citrix XenApp and, at the time, used the latest driver (347.70).  At the time of this testing, this was my 3rd rebuild of this instance so I went with Server 2008 because my previous 2 builds were 2012 and I was convinced I was doing something wrong.  The OS shouldn’t matter, but I’m noting it here.

347.70 –> No OpenGL (just like the gaming card):

Knowing that downgrading the gaming card’s driver worked, I installed the oldest driver I could for the K520:

320.59 –> OpenGL Works!

Just like the gaming card.  I suspect the K520 will have the same issue as the GTX 670, and that any driver after 340.XX will disable OpenGL in a ICA session.  Unfortunately, the Grid K520 appears to only have 3 drivers to chose from, 320.59, 335.35, and 347.70.  To finish this testing I will test with 335.35:

OpenGL Works!  So it appears driver 340 and newer will disable OpenGL for ICA sessions across various types of Nvidia GPU’s, but not Quadro’s..

If you want OpenGL to work on Amazon EC2 instances, you must (at the time of this writing…  hopefully Nvidia corrects this over sight for all cards – consumer and not) you must use a driver older than 340.

Read More

Citrix Seamless Flags and their impact

2015-07-23
/ / /

While investigating a performance issue with an application in our Citrix farm a curiosity was discovered when someone opened up Process Explorer and found the CPU utilization on the server was much higher than expected or reported by various monitoring tools we use.

Examining what was utilizing the CPU we found the process ‘winlogon.exe’ was consuming nearly the entire difference between Process Explorer and Task Manager.

Process Explorer allows us to dive ‘deeper’ into the process to determine the thread that is utilizing our CPU.
twi3.dll is a Citrix file.  Click ‘Module’ and getting properties gives us more information about the file and its purpose.

“Seamless 2.0 Host Agent – main component”


 Now that we have an idea of the purpose of twi3.dll is, we can being to test why it’s consuming so much CPU.  Citrix has options for modifying the behaviour of twi3.dll via “Seamless Flags”.
For our environment we had the following set:
I experimented with modifying each value to determine what the impact on the CPU on the twi3.dll threads would experience.
To that end, you can modify these values immediately and they take effect on the next session connect (but does not impact existing sessions).  With that, here were my results:
Lower numbers for CPU% are better and per user.  More CPU’s actually lower the maximum % winlogon.exe can consume, for this test it was done with a 6 core CPU.  Less CPU’s and the maximum % increases..  I imagine this is due to a thread limit or some such?  
The values that had the most impact on CPU utilization were the lowest values for the WorkerWaitInterval or WorkerFullCheckInterval followed by Disable Active Accessibility Hook.
So what does WorkerWaitInterval / WorkerFullCheckInterval do?
<