29 November 2013

Publishing App-V Applications into XenApp 6.5

My aim with my XenApp 6.5 farm was to keep the servers as clean as possible, free from any locally installed applications.  Why so?  When PVS is delivering all of my XenApp servers, updating, patching or really, performing any maintenance on a locally installed application at some point, required a reboot of the XenApp servers.  In my XenApp 5.0 and App-V 4.6 days, I annoyingly had to bake a few applications into the vDisk in private mode for the applications to work correctly.  Now, the better virtualization available with App-V 5.x, my XenApp 6.5 servers are squeaky clean with no apps installed locally.

I currently have 2 App-V 5.0 servers providing App-V resources to my XenApp 6.5 farm.  Both servers have the Management and Publishing roles installed, however, I don't use either.  Maybe in the future, but not now.  Both servers have a 'Content' share where all of my packages are kept.  They are referenced by a DFS namespace to give App-V 5.0 some HA capability.  Since our domain doesn't support 2012 schemas (which both of my App-V servers are Server 2012 of course), replication of the content share is not possible.  That's no great drama, since I perform most of my package admin on one App-V server, which I unofficially designate as my primary box.  A simply Robocopy script will keep the 2 content shares in sync.

So why don't you use the Management and Publishing services of App-V?

Simple.  I wanted to use Powershell to manage and publish all of my applications so I had a greater degree of control.  Rather than issue a generic publish refresh on a target XA server, using the add-appvclientpackage and publish-appvclientpackage cmdlets gave me much better control of adding and publishing an application.  So I turned to Powershell to script up the required actions.

What's going on here?

This script is actually initiated by another Powershell script responsible for starting the necessary Citrix services to join the XenApp farm after a reboot.  I'll get to that script in a minute.

The idea being, when used in conjunction with the XenApp script, that a server has all of its applications added and published (using the -global switch so apps are available to the workstation, not just the user).  Once this has completed successfully, the XenApp scripts continue and the server joins the farm.  No risk of a user logging into XenApp and complaining that an application is missing because it hasn't been published.  Cool.  Less stress for me.

If there is an error with the publishing, the script stops and the required Citrix services don't start.  No users can log onto the affected servers.  Cool.  Even less stress for me.  The contents of the script is pretty simple.

Line 1 advises Powershell what to do in the event of an error.  In this case, it's simply just to stop.

Line 2 is for my benefit.  When I jump into PVS to switch a disk into private mode, I don't want App-V adding and publishing all of my applications to my private disk.  Line 2 basically checks what mode the vDisk is running where '4' means its in Shared Mode.  If $WriteCacheType is anything other than 4, the script won't run.  Line 5 checks for that.

Lines 10 through 16 is where the adding and publication happens.  Pretty straight forward.  In my environment, I use the -global switch for all publications.  Since I need the app added and published to the server BEFORE I can use XenApp to publish the app out via ICA to the user.

Line 18 through 20 creates a 'flag' to indicate the success of the script.  If the script runs without error, the Packages.Published file is created.  If it errors out, the file is NOT created.  This will serve a purpose in the XenApp start-up scripts.

XenApp Startup

Below, is the script I use to prepare my XenApp servers for production use in the farm.  It essentially does the following:

  • Checks for network connectivity
  • Checks and waits for the AppVClient service to start
  • Runs the script as above
  • If Packages.Published is found, the script starts the required IMA services and joins the farm
  • If Packages.Published is NOT found, the script flicks out an email and DOES NOT join the farm

Let's break it down!

Line 5 defines the function to wait for network connectivity.  This function will keep looping until the network interface joins the network.

Line 32 queries the AppVClient service (or any other service for that matter) to obtain it's status.  The function completes when either the service has started or the timeout value has been reached.

Line 56 begins the process of starting the adding/publishing AppV packages, followed by starting the XenApp services (based on the success of the AppV package script).

Line 65 terminates the entire script if either the AppVClient service does not start or the timeout has been reached.

Line 73 adds and publishes the AppV packages (as called from Line 56).  The function will wait for this script to finish.

Line 78 starts the XenApp services.  If Packages.Published DOES NOT exist, the script stops.  Line 82 catches this error and sends an email out to advise accordingly.

Line 87 runs a couple of generic scripts to set the Secure Ticket Authority ID and run a .bat file to start the required XenApp services.

Finally, Line 91 and 92 is what calls all of the above.  With the QueryService function, you can put whatever service you want to check for and set whatever timeout you require.  I have 120 seconds set, since this script runs at server startup which for my farm, happens at 3AM as part of their scheduled reboots, so I can afford to stretch it out a little to give the services a chance to start.

Since using the above, I know I can get consistent results and a great user experience.  Servers which have an issue with publishing apps, do not join the farm.  Only 100% correctly configured servers will be able to provide applications and resources to users.  No more unexpected phone calls on Monday morning from users!  That's a big WIN!


19 November 2013

Citrix Web Interface 5.4 NewsTicker

In our organization, we have an increasing number of Thin Clients replacing some ageing PC's.  These Thin Clients only have access to Citrix for their applications and resources.  Normally, in the event of major issues or outages, we could communicate via email to all affected users to advise them of such issues.  (Except...if email was offline...that's another problem for another day!).  However, in the case of a Thin Client, what if the user(s) were unable to access their apps or resources due to an issue within XenApp?

My solution?  A NewsTicker for the Web Interface portal.  This way, I can provide information to users about anything I want without the user launching a desktop or published app.


For this, I used jQuery News Ticker, a handful of .png files, a text editor or WYSIWYG editor and some time.  Here, you will find the necessary source files to download as a .zip, which contains pretty much everything you need.  From there, its just a matter of adjusting the relevant files to your liking and placing them in the correct folders on your Web Interface.


***Prior to any modifications on the Web Interface, ensure you have a backup of all files and folders for the site you are modifying.  If anything goes wrong, one can usually restore the Web Interface by returning the file/folders to their original state.***

First off, download and extract the required files.  The extracted files and folders will already be structured.  All you need to do it copy/replace the contents of the files starting at C:\inetpub\wwwroot\gateway\{yoursite}.  A breakdown of the files are:

  • app_data\include\tabPaneHead.inc - Include file to present the ticker and provide content on the WI portal.  Ideally, replace this file last, once you are sure all other files are in place.
  • media\*.png - Image files for the ticker.
  • site\clientscripts\*.js - jQuery 1.8.3 and the jQuery News Ticker.
  • site\clientscripts\*.css - CSS Style sheets for the news ticker itself.
  • ticker.aspx - Page for further information for users.
It is suggested to place ticker.aspx on a publicly accessible web host.  This allows for both Web Interface authenticated users and Access Gateway authenticated users to access the content.  Basically, whatever works best for you.

How to update and add content

To update the content, only tabPageHead.inc and ticker.aspx need to be updated.  I have both of these files locally on my PC and simply use a batch file to copy those files to the Web Interface servers when ready.


This is pretty simple to modify.  The content that appears in the news ticker sits in the "news-container" div. 

  • src="../media/INFORMATION.png" - Replace this with any of the other informational label .png files according to the type of alert.
  • onclick="window.open('http://url.com/ticker.aspx#bookmark) - Specify the url of the ticker.aspx page.  After the hash, specify the bookmark that you will create below in the ticker.aspx page.
  • No current alerts - Of course, replace this with any text of your choosing pertaining to the alert.
Save the file.


This page has 4 cells:  td.InformationCell, td.Content, td.Date, td.ContentBody.  Generally, the only style that you would need to change is that of the td.InformationCell using any of the following styles to represent the type of alert:

  • .InformationCell
  • .WhatsNewCell
  • .OutagesCell
  • .CurrentIssuesCell
Replace the text in the td.InformationCell to the text you require.  The text in the td.Content should ideally be the same text you enter in the tabPaneHead.inc file.  Create a bookmark here and specify the bookmark after the ticker.aspx# as above in tabPaneHead.inc.  Save the file.

That's it!

To deploy the ticker, make the ticker.aspx page available on a web server and over-write the tabPaneHead.inc file on the Citrix Web Interface(s).  If all goes well, after refreshing your portal session, you should see a neat little news ticker rotating through you're newly created alerts.

Since there are only a handful of files required to make the news ticker work, troubleshooting should be fairly simple.  In most cases, tweaking the CSS to correctly display the ticker is needed.

Yes, I know some of the code within the CSS and .aspx pages isn't awesome.  But I don't design web pages for a living...some may call it a hack-job.  But hey, in the end, it gives me the results I need!

Hit me up if you have any questions.

15 November 2013

XenApp 6.5, App-V 4.6/5.0 and FTA's

I had been running XenApp 6.5 with App-V 4.6 for a few months prior to App-V 5.0 being released.  As it turns out, App-V 5.0 and it's connection groups greatly assisted me with resolving an integration issue between Microsoft Office 2010 and a few other apps.


So needless to say, App-V 5.0 was placed into production.  However, File Type Associations (FTAs) were curiously not being applied from the App-V 5.0 package.  Keep in mind, I was logging into an XA 6.5 server with a pre-existing user account and one which had previously logged into an XA 6.5/App-V 4.6 server.  After deploying Microsoft Office 2010 to the farm with App-V 5.0, I was bombarded with calls from users who were unable to open, for example, a .docx file....since there was no associated application.

Since all of my applications are published globally to a XenApp server, I thought this was odd since, by default, I assumed FTAs from the package should do all of the heavy lifting.  Furthermore, publishing the package to the user (not the machine) correctly associated the FTAs for that logged in user.  Weird.  Taking this into account, I was not so keen on publishing Office 2010 to a user each time they logged in to their ICA session.

The Workaround

XenApp content redirection.  Since my first priority was to restore some functionality for the users, I went about letting XenApp take care of the FTAs for the time being.  This was simple enough to enable via the properties for the published app.  From here-on-in, XenApp would intercept the FTAs and launch the required application were applicable.  So for now, users happy.

The Problem

I was determined to let App-V 5.0 take care of the FTAs rather than XenApp intervening.  The key to my problem was existing user accounts that had previously logged into an XA 6.5/App-V 4.6 server.  These users had already had their user profiles populated with FTAs from the previous environment and as it turned out, it wasn't as straight forward as App-V 5.0 taking ownership of the FTA's.  Disabling Content Redirection simply disassociated the FTA with an application and put users back at square one.

Furthermore, logging into a XenApp 6.5/App-V 5.0 server with a NEW account, let the App-V 5.0 FTA's take straight away.  This way, I could happily switch between XenApp Content Redirection and Native FTA's at will.  Although, the prospect of deleting and recreating thousands of Citrix User Profiles was not exactly high on my agenda.  There had to be another way....and there was.

The Solution

Buried within the user profile was the UsrClass.dat file (%AppData%\Local\Microsoft\Windows).  In this file, all of the FTA's are kept for the user.  At login, this .dat file is loaded along with the typical NTUSER.dat file.  However, when mounting and browsing through the NTUSER.dat file, I couldn't find the required FTA's ANYWHERE!  Much to my delight, when I found, mounted and browsed through the UsrClass.dat file, I could see ALL of the FTAs and their existing associations to the App-V 4.6.

As a test, I located the .docx extension key within the hive and deleted it.  After dismounting, I logged in to an XA 6.5/App-V 5.0 server and voila!  App-V 5.0 has control of the FTAs.  When comparing a .doc (controlled by XA Content Redirection) and a .docx (native App-V 5.0), I could see that when Content Redirection was disabled, the .doc was inoperable whilst the .docx would happily open up Word.  If content redirection was re-enabled for both, .doc and .docx would open Word, however, this was being initiated by the XA Online-plugin.

As such, it was simply a case of configuring Citrix UPM to NOT synchronize the UsrClass.dat files at logon/off.  To prevent UPM from inadvertently loading the UsrClass.dat file, I used a straight-forward Powershell script to search for and delete all instances of UsrClass.* from the UPM profile store.

Since then, all FTA's are maintained by App-V 5.0 and function exactly as expected.


14 November 2013

Enabling HTTP streaming in App-V 5.0

One thing I found that wasn't well documented for App-V 5.0 was how to enable and allow packages to be streamed over HTTP as opposed to SMB.  Turns out, it's a lot easier than I thought.  Whilst I continue to use SMB for streaming applications, in my initial testing, I didn't see any obvious improvement in streaming my packages using HTTP.  However, read on further to see how to allow HTTP streaming for App-V 5.0 packages.

In my current setup, I have 2 Windows 2012 App-V 5.0 servers.  Both are configured as a Management and Publishing server.  However, since I publish all of my applications into XenApp 6.5 using Powershell, the only purpose of these 2 servers is to provide a content share for the Shared Content Store for the client devices.  Content is accessed from the clients using a DFS Namespace.

Please leave your comments below if you've noticed any improvement in performance when using HTTP.

Enable HTTP Streaming

Open the IIS Management console from the server that is hosting the Content Store.

Right-click the 'Default Web Site' and select 'Add Virtual Directory...'.

Add and configure the virtual directory as required, using an account that has permissions to the physical path.  I didn't require any special permissions or account here, so this was pretty straight forward.

When complete, click on the newly created virtual directory.  In the right pane, double-click 'Directory Browsing' under IIS.  Enable directory browsing.

Go back to the root of the virtual directory.  Now double-click the 'MIME Types'.  Add a new MIME Type:

Recycle the 'Default Web Site' and that's it!  At the root of your newly created virtual directory/physical path, you should see a file 'web.config'.  From here you should be able to launch your browser and browse to http://appvserver/yourcontentstore.

When adding your App-V 5.0 package to the client device using powershell, instead of using the -path switch (which would usually require an SMB share), simply add the package with:

add-appvclientpackage -url "http://appvserver/yourcontentstore/package.appv"

Good luck!