Yes, You Need IT Certifications

Certifications are often lambasted as “worthless pieces of paper” and “experience is more important.” But for some people, certifications are more important than experience.

A substitute for experience

Newcomers to the IT world face the classic problem: how do you get experience without a job? Sure, you can tinker around on your own time, but how do you prove that experience? That’s where certifications come in.

Certifications show a prospective employer that you care enough and have the initiative to spend your own time and money to become a better IT professional. You might have tons of experience with IT as a hobby. But how do you prove that?

With a piece of paper.

Certifications get you hired

They are what get your resume looked at, instead of being tossed into the shredder by HR.

They are what get you the interview.

They are the tie-breaker between you and that other equally qualified person who doesn’t have a cert.

If you have a stack of certifications under your belt, you’re going to be a step ahead of the naysayers who think certifications are a joke, a scam, or a racket.

Certifications mean higher pay

My first IT certification was the CompTIA A+ in 2002. That helped me land one very low paying job. During that time, I also got my Microsoft MCSA.

Fast-forward a few years. I got a job at a local technology reseller where I earned my Network+, Cisco CCNA, CCDA, and finally my CCNP, all within a year. Shortly after that, I was able to get a job that almost doubled my salary.

A couple years later, I got my Citrix CCA. My salary went up by 50%. It increased a few percent each year thereafter.

Oh, and I forgot to mention: no college degree.

You’re always a beginner

Even if you’ve been in the field for 20 years, you’re always a beginner when it comes to emerging technologies. You can work your tail off to get experience with the latest and greatest, but if you want to turn that experience into a raise or new position, you have to prove your skills.

When you put in your resume against someone fresh out of college – and they have that highly sought after certification and you don’t – well, you can guess who’s getting the callback.

Citrix Web Interface: Error occurred while making the requested connection

I recently ran into a bizarre issue with users not being able to launch applications from a very old Citrix Presentation Server 4.0 farm when trying to launch from Citrix Web Interface 5.4. They were getting the eminently unhelpful, “An error occurred while making the requested connection.”

The Diagnosis

In the web interface application logs, I noticed this:

An error of type IMA with an error ID of 0x80000003 was reported from the Citrix XML Service at address (servername)

And this:

The farm MyFarm has been configured to use launch references, but a launch reference was not received from the Citrix XML Service. Check that the farm supports launch references or disable launch reference requests.

The Solution

To resolve this, I modified C:\inetpub\wwwroot\Citrix\XenApp\conf\WebInterface.conf on the Web Interface servers and changed the RequireLaunchReference directive as follows:
(It was set to On)

And it worked. Supposedly, that directive must be set to Off when using Web Interface 5.4 with PS 4.0. But, I’ve been running for years with it set to On and it worked fine until recently. Another Citrix mystery.

Want more Citrix tips and tricks? Watch my Citrix NetScaler course!

7 Ways To Speed Up Citrix XenApp Logons

1. Disable unused Group Policy sections

In each of the GPOs that are applied to your servers and users, both User and Computer processing is enabled by default. Disabling unused parts of a GPO can shave some time off both logons and server booting. You can do this in the GPO properties. Just bring up the GPO in Group Policy Management Editor, right-click the policy name, and click Properties. Continue reading

Should You Use The HP Universal Print Driver or Other Third-Party Print Drivers In XenApp 6?

One of the problems that has plagued Citrix admins and engineers has been third party print drivers. All it takes is for one bad print driver to misbehave, crash the print spooler, and generate dozens of support calls from users who suddenly cannot print.

This common problem led to Citrix including the Citrix Universal Print Driver (Citrix UPD) which is compatible with many popular printers, and is much easier on the Windows print spooler. In cases where the Citrix Universal Print Driver does not play well with an application or a particular printer, the Citrix Universal Printer can be mapped into a user’s session as a virtual printer that offloads the print job to the user’s client machine, using the native or third-party print driver installed on the client machine.

Between these two wonderful gifts from Citrix, why even consider using a third-party print driver like the HP Universal Print Driver?

Despite the stability and compatibility of the Citrix Universal Print Driver, I have found that even it sometimes causes the Windows print spooler to crash. I’m not saying that the driver itself is at fault. There could be a problem with the data an application is sending to the print subsystem and the Citrix UPD. Regardless, the print spooler sometimes crashes and has to be restarted to restore printing on the affected XenApp server.

There are three approaches to resolving the problem of the Citrix UPD crashing the spooler-
1. Eliminate the driver itself as the cause (blame an application, an OS patch, or something else)
2. Do not map client printers into a user’s session, and instead allow them to only use the Citrix Universal Printer
3. Allow use of native or third-party print drivers

Option 1 is the most time-consuming and possibly the least rewarding because you may find that the problem actually is the driver, or an application that cannot be rewritten for whatever reason, or an OS patch that is absolutely necessary.

Option 2, forcing users to use the Citrix Universal Printer, can potentially work marvelously for small print jobs provided the user understands how to use the Universal Printer options.

Option 3, using native or third-party print drivers, makes many of us cringe. In Windows Server 2008 R2, some native HP drivers simply cannot be used. The native drivers HP gave to Microsoft to include in Windows included a bug which prevented the drivers from being used. This problem leaves the HP Universal Print Driver as the only native option for HP printers in Windows Server 2008 R2. If you have other printer brands in your environment, native drivers included with Windows will probably work. But remember that there is no guarantee that the native drivers will not crash the print spooler.

So which option is best? As usual, it depends on your environment. Despite the issues, I propose that option 3 can be a good option for XenApp 6 environments where printing is not heavy. Allowing native and third-party print drivers in addition to the Citrix Universal Printer and the Citrix UPD offers the most flexibility. The biggest problem I have seen with using the HP Universal Print driver is that it can consume the entire CPU and render the server almost useless. If users in your XenApp environment are doing a lot of printing, don’t use the HP Universal Print driver. Don’t even install it. Otherwise, test it out and see how it holds up under your workload.

If you decide to try third-party printer drivers, you don’t have to worry about these drivers crashing the print spooler thanks to the inclusion of a new feature in Windows Server 2008 R2 that allows print drivers to be isolated from the spooler. Print driver isolation works by creating a separate process, PrintIsolationHost.exe, for each session. Instead of a faulty driver crashing the spooler, it will only crash the PrintIsolationHost process, impacting only the user whose print job triggered the crash. Recovery is as simple as having the user log out and back in.

Enabling print driver isolation is easy and is done on a per-driver basis. In Windows, just launch Print Management under Administrative Tools. Right-click the driver you wish to isolate, and select “Isolated”

The change takes effect immediately and no restart of the spooler is required. While print driver isolation is a valuable and much-needed feature, it is not compatible with all print drivers. And it is absolutely not compatible with the Citrix Universal Print driver! If there were a way to isolate it without breaking printing, it would save almost everyone from having to use native or third-party print drivers.

Of course, isolating native and third-party drivers is only part of the solution. For maximum flexibility and compatibility, we need to automatically map the Citrix Univeral Printer into all user sessions, and set policies regarding the use of the Citrix UPD.

Mapping the Citrix Universal Printer to all user sessions is done through Citrix user printing policies. When it comes to how the Citrix UPD is used, we have two options. We can either disallow the use of native and third-party print drivers, and allow only the use of Citrix UPD-

Or we can allow the use of native or third-party print drivers, if present, and fallback to the Citrix UPD if native drivers are unavailable.

The beauty of this configuration is that we can use Citrix policies to control when, if, and which print drivers are allowed without having to make any modifications to the XenApp server itself. Native and third-party print drivers are installed and isolated, but we can choose to disallow them by simply modifying the Citrix user policies. If the Citrix UPD causes problems with the print spooler, we can switch over to native and third-party drivers by simply changing the policies. And as if that weren’t enough, the Citrix policies can be filtered on a per-user basis. This means one group of users can be forced to use Citrix UPD, while another group can be permitted to use native drivers! Now you can see why I chose this configuration to provide the most control and flexibility without sacrificing stability of the XenApp environment.

Earlier I mentioned that the Citrix Universal Printer is useful for small print jobs when the user understands how to use it. Rendering larger print jobs through the Universal Printer is extremely slow, and if users are trained in its use they can end up unintentionally printing to the wrong printer. Also, the Citrix Universal Printer requires the appropriate print drivers be installed on the user’s client machine, making its universal use a potential administrative nightmare. In the future I hope to see some intelligence built into XenApp and the ICA client that automatically detects and selects the best method of printing based on the user’s unique configuration.

Citrix printing has improved tremendously over the years. One size still does not fit all, but we are getting there. Hopefully the Citrix Universal Print Server (Project Phaser) will be the silver bullet that solves printing in Citrix forever.

Use PowerShell to Find Citrix ICA Client Versions In Use On a XenApp 6 Farm

In many Citrix environments it’s common to have a large variety of ICA client versions. One thing that sometimes surprises users and IT folks alike is how much of a performance increase can be seen after upgrading an old ICA client. But how do you know which clients need upgrading?

One of the biggest challenges has been deciphering what ICA client version the cryptic “client build number” in a user’s session information translates to. Well thanks to the XenApp 6 PowerShell SDK and Get-XASession, we can easily find Citrix ICA client version information in a snap with the following script (download the script here):

# XenApp 6 Client Version Retrieval Script
# Created by Ben Piper
function convertToVersion($build) {
		6685 {"13.0"; break}30 {"12.1"; break}6 {"12.0.3"; break}6410 {"12.0"; break}142{"Java"; break}317{"3.0"; break}324{"3.0"; break}330{"3.0"; break}349{"3.0"; break}304{"MAC 6.3"; break}314{"MAC 6.3"; break}323{"MAC 6.3"; break}326{"MAC 6.3"; break}400{"MAC 7.0"; break}402{"MAC 7.0"; break}405{"MAC 7.0"; break}406{"MAC 7.0"; break}407{"MAC 7.0"; break}402{"MAC 7.0"; break}411{"MAC 7.0"; break}500{"MAC 7.1"; break}600{"MAC 10.0"; break}601{"MAC 10.0"; break}581{"4.0"; break}606{"4.0"; break}609{"4.0"; break}614{"4.0"; break}686{"4.0"; break}715{"4.2"; break}727{"4.2"; break}741{"4.2"; break}779{"4.21"; break}730{"wyse1200le"; break}910{"6.0"; break}931{"6.0"; break}961{"6.01"; break}963{"6.01"; break}964{"6.01"; break}967{"6.01"; break}985{"6.2"; break}986{"6.2"; break}1041{"7.0"; break}1050{"6.3"; break}1051{"6.31"; break}1414{"Java 7.0"; break}1679{"Java 8.1"; break}1868{"Java 9.4"; break}1876{"Java 9.5"; break}2600{"RDP 5.01"; break}2650{"10.2"; break}3790{"RDP 5.2"; break}6000{"RDP 6.0"; break}2650{"10.2"; break}5284{"11.0"; break}5323{"11.0"; break}5357{"11.0"; break}6001{"RDP 6.0"; break}8292{"10.25"; break}10359{"10.13"; break}128b1{"MAC 10.0"; break}12221{"Linux 10.x"; break}13126{"Solaris 7.0"; break}17106{"7.0"; break}17534{"7.0"; break}20497{"7.01"; break}21825{"7.10"; break}21845{"7.1"; break}22650{"7.1"; break}24737{"8.0"; break}26449{"8.0"; break}26862{"8.01"; break}28519{"8.05"; break}29670{"8.1"; break}30817{"8.26"; break}31327{"9.0"; break}31560{"11.2"; break}32649{"9.0"; break}32891{"9.0"; break}34290{"8.4"; break}35078{"9.0"; break}36280{"9.1"; break}36824{"9.02 WinCE"; break}37358{"9.04"; break}39151{"9.15"; break}44236{"9.15 WinCE"; break}44367{"9.2"; break}44376{"9.2"; break}44467{"Linux 10.0"; break}45418{"10.0"; break}46192{"9.18 WinCE"; break}49686{"10.0"; break}50123{"Linux 10.6"; break}50211{"9.230"; break}52110{"10.0"; break}52504{"9.2"; break}53063{"9.237"; break}55362{"10.08"; break}55836{"10.1"; break}58643{"10.15"; break}				
		default {$build; break}
$clientUsage = @()
foreach($session in Get-XASession -full | where {$_.state -eq "Active" -and $_.protocol -eq "Ica"}) {
	$clientUsage += new-object psobject -Property @{
		User = $session.accountname
		Workstation = $session.clientname
		Client = convertToVersion($session.clientbuildnumber)
$clientUsage | sort-object -Property Workstation | get-unique -asstring

The script makes use of build-to-version information gleaned from Nick Holmquist’s ICA Client Build List and the Citrix Client Build List thread on Citrix Forums (Thanks!). The convertToVersion function uses the PowerShell switch command to identify and then return the ICA client version based on the build number. If the key-value pair is not in the list, the build number is returned. All ICA client versions in the list have at least one decimal place to make it easy to distinguish build numbers from client versions.

How To Fix Citrix Receiver Error 2320

Recently I have seen a couple of cases where the Citrix Receiver 3 client produces the following error when trying to launch a published application:

Error number 2320
Citrix online plug-in Configuration Manager: No value could be found for (ClientHostedApps) that satisfies all lockdown requirements. The lockdown requirements in force may be conflicting.

The most salient part of the error message is in between the parenthesis. In the error message above, ClientHostedApps is a registry value that resides in two locations: HKLM\SOFTWARE\Wow6432Node\Citrix\ICA Client\Engine\Lockdown Profiles\All Regions\Lockdown\Virtual Channels\Control (on 64-bit systems: HKLM\SOFTWARE\Wow6432Node\Citrix\ICA Client\Engine\Lockdown Profiles\All Regions\Lockdown\Virtual Channels\Control) and HKCU\SOFTWARE\Citrix\ICA Client\Engine\Lockdown Profiles\All Regions\Lockdown\Virtual Channels\Control

The fix couldn’t be simpler. Just delete the value for ClientHostedApps in these locations, refresh your applications in Receiver, and you should be able to launch published applications.

Want more Citrix tips and tricks? Watch my Citrix NetScaler course!

Instantly Publishing Citrix Apps to Individual Servers Using PowerShell

Sometimes there is a need to publish an application to individual XenApp servers for baselining or troubleshooting purposes. But if you have a lot of published applications in your XenApp 6 farm, this can be a huge hassle. Thankfully PowerShell allows us to quickly and easily take our existing published applications and automatically create individually published apps for each server. We can use Worker Groups to control which servers get an individually published application. Not only that, we can organize the applications neatly by creating separate console and Client folders for each server. I wrote this script to accomplish all of the above using XenApp 6 PowerShell SDK’s powerful features:

$appFolder = "Applications"
$testfolderpath =  "Applications/Test/Single Server Test"
$sourceAppPath = "Applications/Test"	#apps in the root of this path will not be copied
$publishTo = "DOMAIN\GroupWithAccessToIndividualServers"
$targetWorkerGroup = "Main Farm Servers"
$clientFolder = "Test\Single Server Test"
$WhatIfPreference = $false		# Simulate script but do not execute any changes (will yield errors)
# Main Program
$servers = Get-XAServer -workergroupname $targetWorkerGroup
$sourceFolders = Get-XAFolder -folderpath $appFolder -recurse | where {$_ -notmatch $testfolderpath -and $_ -match $sourceAppPath -and $_ -ne $sourceAppPath}
# Create folder for each server
foreach ($server in $servers) {						
	#generate folder name for each server
	$createfolder = $testfolderpath+"/"+$server.servername
	#create folder for each server
	new-xafolder -folderpath $createfolder
	foreach ($folder in $sourceFolders) {
		#get list of apps to copy in each folder
		$appstocopy = Get-XAApplication -folderpath $folder			
		foreach ($app in $appstocopy) {
			## generate name for new app
			$newname = $app.displayname+" "+$server.servername
			$newclientfolder = $clientfolder+"\"+$server.servername
			## get existing accounts to remove			
			$accountsToRemove = ($app | Get-XAApplicationReport).accounts
			## copy application to server's folder		
			$newapp = $app | Copy-XAApplication -folderpath $createfolder
			## publish application to lone server		
			$newapp | set-xaapplication -servernames $server.servername -clientFolder $newclientFolder
			## remove existing accounts
			foreach ($account in $accountsToRemove) {
				$newapp | remove-xaapplicationaccount -Accounts $account
			## publish application to AD group
			$newapp | add-xaapplicationaccount -Accounts $publishTo
			## rename new application
			$newapp | rename-xaapplication -newdisplayname $newname						

Download the script from GitHub.

Just set the variables with what is appropriate for your environment and run the script.
The $appFolder variable is the root path of your applications (default is “Applications”)
$testfolderpath is the full path of the folder where the applications published to individual servers will be published (no trailing slash)
Set $sourceAppPath one level higher than the path of the folder containing the applications you wish to copy. The script will recurse down into child folders from this path, but will not copy applications that reside within this path.
$publishTo is a string containing the AD users or groups the newly published applications should be published to
$targetWorkerGroup is the name of the worker group containing the servers the applications will be published to
$clientFolder is the root Program Neighborhood/Client folder that the individual server folders will be created under

The once-daunting and time-consuming task of copying and modifying applications for each server can now be done automatically in a matter of minutes!

Update: It’s even easier to undo the changes made by the above script if you decide you want to scrap the newly published apps and folders and start over. Just use the following script:

$testfolderpath =  "Applications/Test/Single Server Test"
$WhatIfPreference = $false
# Main Program
(get-xaapplication -folderpath (Get-XAFolder -folderpath $testfolderpath)) | remove-xaapplication
(get-xafolder -folderpath $testfolderpath) | remove-xafolder

Using IRQbalance to Improve Network Throughput in XenServer

If you are running XenServer 5.6 FP1 or later, there is a little trick you can use to improve network throughput on the host.

By default, XenServer uses the netback process to process network traffic, and each host is limited to four instances of netback, with one instance running on each of dom0’s vCPUs. When a VM starts, each of its VIFs (Virtual InterFaces) is assigned to a netback instance in a round-robin fashion. While this results in a pretty even distribution of VIFs-to-netback processes, it is extremely inefficient during times of high network load because the CPU is not being fully utilized.

For example, suppose you have four VMs on a host, with each VM having one VIF each. VM1 is assigned to netback instance 0 which is tied to vCPU0, VM2 is assigned to netback instance 1 which is tied to vCPU1, and so on. Now suppose VM1 experiences a very high network load. Netback instance 1 is tasked with handling all of VM1’s traffic, and vCPU0 is the only vCPU doing work for netback instance 1. That means the other three vCPUs are sitting idle, while vCPU0 does all the work.

You can see this phenomenon for yourself by doing a cat /proc/interrupts from dom0’s console. You’ll see something similar to this:

(The screenshot doesn’t show it, but the first column of highlighted numbers is CPU0, the second is CPU1, and so on. The numbers represent the quantity of interrupt requests.)

If you’ve ever troubleshot obscure networking configurations in the physical world, you’ve probably run into a router or firewall whose CPU was being asked to do so much that it was causing a network slowdown. Fortunately in this case, we don’t have to make any major configuration changes or buy new hardware to fix the problem.

All we need to do to increase efficiency in this scenario is to evenly distribute the VIFs’ workloads across all available CPUs. We could manually do this at the bash prompt, or we could just download and install irqbalance.

irqbalance is a linux daemon that automatically distributes interrupts across all available CPUs and cores. To install it, issue the following command at the dom0 bash prompt:

yum install irqbalance --enablerepo base

You can either restart the host or manually start the service/daemon by issuing:

service irqbalance start

Now restart your VMs and do another cat /proc/interrupts. This time you should see something like this:

That’s much better! Try this out on your test XenServer host(s) first and see if you can tell a difference. Citrix has a whitepaper titled Achieving a fair distribution of the processing of guest network traffic over available physical CPUs (that’s a mouthful) that goes into more technical detail about netback and irqbalance.

Deploying Citrix Access Gateway VPX with Web Interface 5.4 – CAG Setup with RADIUS

Deploying CAG with Web Interface 5.4 is actually very easy, there are just some “gotchas” that you have to be ready for. This is a guide to help you avoid those snags and pitfalls that commonly occur with a CAG VPX and Web Interface integration.

I recommend getting the Citrix Access Gateway VPX Getting Started Guide and HDX Remote Access Guide with Citrix Access Gateway VPX Express if you don’t already have them. The former document contains some inaccuracies but is has some useful reference info as well. The latter takes you through the fundamental setup of the CAG VPX and gets you to the web administration console, where most of the meaty configuration will take place.

There are some assumptions I’m making with this guide since it is based on my own requirements. They are:

  • The CAG VPX has two virtual NICs, external to service external users, and internal for management and communication with the XenApp servers
  • Two logon points will be configured: One that allows user authentication to take place at the web interface, and another that uses RADIUS
  • The CAG VPX will not reside in a DMZ. If your situation requires it to reside in a DMZ, setting it up is trivial once you’ve gotten everything else working.
  • You’ve already got the CAG VPX appliance imported and running, but not configured
  • You have your web interface server setup, with no websites configured.
  • You have installed the CAG VPX license on a Citrix license server

Also, a word of warning: Configuring CAG VPX with Web Interface is like playing chess. Every move you make will affect all of your successive moves. In areas where I suspect your setup might require you to deviate from this guide, I’ll offer some pointers to help you make the right move.

Let’s get started! First, follow the Getting Started guide to configure the management interface for the CAG via the VM console. If you are unsure about a setting, just take the default by hitting Enter.

Once you have your management IP assigned, you’ll need to access the web administration console by browsing to https://[IP address]/lp/adminlogonpoint . Login with the default username and password “admin”. You’ll see a nice dashboard with two dials and some nasty looking red X’s. Click on the Management tab. This will take you to the Networking portion of the System Administration menu group.

Here, enter the CAG’s hostname as an FQDN. You’ll see a list of your network interfaces (eth0, eth1, etc.) with one of them having the management IP address you assigned. To the right, there are four checkboxes labelled Internal, External, Appliance Failover, and Management.

Moving from left to right, the interface that will be used to connect to your XenApp servers should have the Internal checkbox checked.
The interface for management should already have the Management checkbox checked.
The interface that will be receiving external requests from end users should have the External checkbox checked.

If need be, your Internal and External interfaces can be the same. Make sure your DNS servers have an entry for your Internal IP!

Under the Default Gateway section, select the interface the CAG should use to route traffic for subnets to which it is not directly connected. This will probably be your External interface. Remember, the CAG has a direct connection to the subnet your XenApp servers are on, so it doesn’t need a gateway to get to those. But it does need a gateway to get back to your external users who are connecting from the Internet!

Click Save and restart the appliance using the big Restart button on the top right.

Log back into the web administration console and browse to Management > Name Server Providers. Enter your DNS servers and DNS suffixes.

Now go to Static Routes in the System Administration menu. Do you need a static route? If you plan on putting the CAG VPX into a DMZ later, go ahead and enter your static routes. Gateways you specify for static routes will take precedence over the default gateway you specified earlier. Remember, it does not hurt to add them now.

Now Browse down a few rows to Licensing and click Configure. Select the Licensing type and Remote Server for the licensing server. Enter the FQDN or IP of your Citrix licensing server, and click Save. The CAG will attempt to grab its licenses and upon a successful retrieval, it will display them as shown:

NB: If the CAG is unable to retrieve the licenses, I recommend stopping and troubleshooting until it is able to successfully pick up the licenses. You can continue your configuration, but you will not be able to test it until the license issue is resolved.

Moving right along, click on Authentication Profiles under the Access Control menu group. It’s time to add a RADIUS authentication profile! But before you do that, you have to set up a RADIUS server. I recommend reading How to Configure Radius Authentication/Authorization on Windows 2008 for Use on Citrix Access Gateway Standard Edition. (One caveat, however: don’t perform steps 13-17 in the KB article because they’re unnecessary and will cause problems.) Click Add and enter a name for the Authentication Profile. Click New and add your RADIUS server(s) and shared secret. Leave everything under Group Authorization as-is. You’re relying on the RADIUS server to check group authorization.

Now go to XenApp or XenDesktop under Applications and Desktops and enter the IP ranges of clients that can access XenApp servers via ICA and CGP. I really don’t know why there isn’t a checkbox that allows you the equivalent of a “permit ip all”, but there isn’t.

Next, click Secure Ticket Authority. These settings are arguably the most common cause of application launch issues. Select your STA servers carefully, and make sure all your XenApp servers have unique STA ID’s! If you are running Provisioning Services and streaming XenApp, read before proceeding. Once you are sure your STA IDs are unique, click New and enter the FQDN of each XenApp server that will be providing STA services. By default, the connection type is Secure, but I’m guessing your XenApp servers are not using SSL for STA traffic, so select Unsecure. Leave everything else as-is and click Add. Note the servers you selected here, because you will need them later.

At this point you can go ahead and restart the CAG VPX appliance, because it’s now time to do some work on the Web Interface (WI) side. Log into your WI server, launch the Citrix Web Interface Management console, and create a new site.

Should we do the easy one or the hard one first? Trick question. They’re both easy! We’ll set up a site to be used with RADIUS authentication. Click Create Site under the Actions pane on the right, name the website however you wish and click Next. Select “At Access Gateway” as the point of authentication and click Next. Here you’ll be greeted with an intimidating looking Authentication Service URL field. But as I said, this is easy! Just enter https://[cag-FQDN]/CitrixAuthService/AuthService.asmx and click Next, Next. After a few moments, your site will be created.

Right-click the site in the XenApp Web Sites list and select Server Farms. Configure your XenApp servers like you normally would in WI. There is nothing here unique to CAG.

Now right-click the site again and select Secure Access. Select the only item in the list and click Edit. Change Access method to Gateway direct and click Next. Next you’ll be asked for the address of the CAG. Enter the FQDN of the CAG, and optionally enable or disable session reliability. If enabled, you can request tickets from two STAs (A word on this option: When you setup a site for Citrix Receiver, this checkbox must be unchecked. This site you are creating now cannot be used for Receiver, so don’t worry about it here if you plan to use Receiver.) Click Next.

Remember I said to note the XenApp servers you entered into the CAG VPX as your STA servers? Web Interface wants to know about these servers too. Click Add and enter the URL of the first XenApp server you entered into the CAG in the following format:

I still do not know why it doesn’t just ask for the FQDN and assume the rest like the CAG does, but that’s how it is. Do this for all STA servers you entered into the CAG, and in the same order. Check, double check, and triple check the URLs! Also optionally change the “Bypass failed servers for” option to 1 minute. Click Finish.

Are we done? Almost. The CAG should be back up now, so log back into it. Click Logon Points under Access Control and click New. Now don’t be intimidated by all the settings. We only care about four things here. Enter the name of the logon point. Select this name carefully because it is what users will have to type in to connect to the CAG. If you enter “cag-logonpoint1” then users will have to go to which just looks ugly! Under Type select Basic. In the Web Interface field, enter the URL of the web interface site you created (no trailing slash). Under Authentication Profiles, select the RADIUS authentication profile you created earlier. Finally, check the “Single sign-on to web interface” check box and click Save.

Now, we are almost ready to test. But to save ourselves from a disappointing moment of temporary CAG dysfunction, click on Secure Ticket Authority again. Do you see unique STA IDs populated next to each of your XenApp servers? If not, troubleshoot until you do. If so, it’s time to test!

Browse to the logonpoint you just created. If you named your logonpoint “test1” and your CAG’s FQDN is, browse to

Do you get an SSL certificate error? Probably so. I intentionally did not cover installing a certificate because it introduces another level of complexity into the configuration. SSL Certificates are dependent on the hostname, and the hostname you use to connect to the CAG to enumerate and launch apps has to match up with the hostname on the SSL certificate. The certificate also must be signed by a trusted certificate authority. Unless you have your own certificate authority, getting a signed certificate can be a pain. Unfortunately, connecting to CAGs using untrusted SSL certs causes a lot of problems. You may encounter some of these problems or you may not. Test anyway. If you do run into problems, the good news is that the heavy lifting of configuring the CAG is done.

Now, it’s time for a moment of truth. Once you’ve gotten a login prompt, log in with an AD account that has appropriate authorization. You may need to specify the user in UPN or down-level domain format. It depends on your AD environment, but one of those should work. If you have trouble authenticating, first check the logs on the RADIUS server to make sure the denial is not occurring there. If you continue to have issues, it’s time to get acquainted with what will become your new best friend: the CAG debug log. The CAG debug log is at your service at . Watch it for any FLEXnet or STA errors.

Once you get logged in, try launching a published app. If all goes well, you should see something like…

How To Get a Unique STA ID for each of your PVS Provisioned XenApp Servers

Citrix Provisioning Services is very nice, but it does come with a slightly annoying quirk: All of your provisioned XenApp servers end up with the same STA ID! This will cause all sorts of problems for Citrix Access Gateway, Citrix Receiver, and anything else that may depend on having unique STA IDs. The good news is that fixing this little problem is easier than you might think.

To resolve the duplicate STA ID issue, we’ll do the following:
1. Create personality strings in Provisioning Services for each XenApp server
2. Put a PowerShell script on our golden image
3. Create a startup task to execute the PowerShell script

Let’s begin:

The format of the STA ID is simple. It is “STA” followed by the MAC address of the XenApp server’s NIC. The STA ID can really be anything beginning with “STA”, so you could get creative and have “STABLEFLY”, “STANK”, “STALE”, “STARTBUTTON”, “STACKOVERFLOW”.. and the list goes on. But I recommend sticking with the MAC address because it’s unique (usually), and is easy to match up.

1. In Provisioning Services, create a personality string for each server with the Name “UID” and the String “STA001122DDEEFF”, substituting the MAC address of the server for the hex I just threw in there.
Define Personality Strings

2. Copy this PowerShell script to your scripts location on your golden image: (Note: Download the file from the above link and do not copy and paste the text below, otherwise PS will complain.)

# STA Replacement Script for Citrix Provisioned Servers
# Created 7-25-11 by Ben Piper (email:, web: )
# Get UID string
# Replace STA ID
# Restart CTXHTTP service

$stastr = get-content C:\Personality.ini | Select-String -Pattern “UID=STA”
$CtxStaConfig = Get-Content ‘C:\Program Files (x86)\Citrix\system32\CtxSta.config’ | ForEach-Object {$_ -replace ‘^UID=.+$’, $stastr}
$CtxStaConfig | Set-Content ‘C:\Program Files (x86)\Citrix\system32\CtxSta.config’
Stop-Service CtxHTTP
Start-Service CtxHTTP

3. Create a scheduled task to execute the PowerShell script at startup. Make sure the account that will be executing the script has appropriate permissions.

If you are not already running PowerShell scripts, you’ll need to set the ExecutionPolicy on your gold image to Unrestricted by issuing the cmdlet ” Set-ExecutionPolicy Unrestricted” at a PS prompt.

I recommend testing the script first on your Master Target server before deploying it farm-wide. The script will still work as long as you have a personality string defined for your Master Target server, even if the vDisk is in Private mode.