Citrix Networking for Data Center Specialist Practicum Passed

A few weeks ago I took the Citrix Networking for Data Center Specialist Practicum (1Y0-A36) exam, as part of the Citrix Partner Specialist program. Happy to say the I found out this week that I passed!

The exam didn’t feel too challenging on the whole, however I have been working with the Citrix NetScaler and CloudBridge product stack regularly for a number of years now.

Citrix Networking for Data Centre Specialist Practicum

 

What is the Citrix practicum?

The practicum provides partners the opportunity to demonstrate knowledge in one of the solution competency areas by simulating a Citrix engagement. Engineers will be provided a sample Statement of Work containing specific business and user requirements. Each person will then be given access to a lab environment to develop a solution to meet the needs outlined in order to validate their skills in a meaningful way.

Adding a Published Application to multiple Delivery Groups in XenDesktop 7.x

Although assigning a Published Application to multiple Worker Groups in XenApp 6.x was a fairly straightforward task, the same activity is not as intuitive in XenDesktop 7.x. The Citrix Product Documentation isn’t exactly crystal clear on the process either. As such, I thought I would take the opportunity to document the process here.

Firstly, I am using XenDesktop 7.1 in my example below and I haven’t found a way to do this using the GUI, so we have to use PowerShell. I haven’t validated this for 7.0 or 7.5, although I assume the process will be the same.

After creating the target Delivery Groups, the first thing to do is discover and publish the required application(s) to the first Delivery Group using the Citrix Studio Console. I suggest using this method as it is quick and easy. Alternatively PowerShell can be used to create the application. I will detail at the end of the article.

Once you have a Published Application you will need to launch PowerShell, again I find this easiest to do from the Citrix Studio Console. The following command will assign the named Published Application to the Delivery Group specified, much like you would do with XenApp 6.x and Worker Groups. This can be repeated as required.

Note: Published Applications can only be assigned to Delivery Group with a type of ‘Applications Only’ or ‘Desktops and Applications’

Add-BrokerApplication -Name "Publised App Name" -DesktopGroup "Delivery Group 1"

In addition to this a priority can also be assigned. By default the priority is 0. 0 is the highest priority. To assign a priority, use the -priority attribute as seen below. The priority can be used to either load balance the group, when both Delivery Groups have the same priority, or in failover order as the priority descends.

Add-BrokerApplication -Name "Publised App Name" -DesktopGroup "Delivery Group 1" -priority 1

To add a Published Application using PowerShell use the following Cmdlet:

Add-BrokerApplication -BrowserName "Publised App Name" -DesktopGroup "Delivery Group 1"

I hope this helps.

Custom Condition Using PowerShell to Check if an ICA Session is a Published Destkop

Recently I had a specific need to identify if a Citrix XenApp session was a published desktop using AppSense Environment Manager. AppSense Environment Manager has built-in conditions to apply to a particular published application, however I needed to know if the session was just a published desktop so this wasn’t going to work. To do this I created the following PowerShell script to be used as a custom condition. I hope this helps anyone else in a similar position.

$sessionid = query session | Select-String -Pattern ">"
$sessionid = $sessionid.ToString()
$sessionid = $sessionid.Substring(9,9)
$sessionid = $sessionid.trim()
$publishedapp = (Get-ItemProperty  HKLM:\SOFTWARE\Citrix\Ica\Session\$sessionid\connection).InitialProgram
If ($publishedapp) {exit (0)} else {exit(1)}

Customising the Citrix NetScaler Access Gateway Caxton Style Logon Page

In the Citrix world you often have to customise the default NetScaler Access Gateway Caxton style logon page. So to make life easier I have broken down the page and its components into the following sections (I’m sure other people will have already done this). I have purposefully used the same style as Andrew Morgan’s excellent article titled “Decrapifying the Citrix Web Interface (5.4)“.

Please note, this applies to the standard Citrix NetScaler theme, those using the Green Bubble theme for example will need different customisations.

Blank AG Page.png

1. The Header Logo

To remove the logo, find the css class .header_left in /images/caxtonstyle.css on lines 92-98 and add the highlighed line.

.header_left
{
width: 265px;
height: 62px;
background-image: url(/vpn/images/ctxHeader01.gif);
background-repeat: no-repeat;
display: none;
}

To change the logo to a custom one, modify the following file:

/images/ctxHeader01.gif)

Should you need to change the size of the image, don’t forget to change the width and height in the header_left style above.

2. The Header Banner

To remove the banner to the right of the logo, find the css class .header_middle in /images/caxtonstyle.css on lines 100-105 and add the highlighed line.

.header_middle
{
height: 62px;
background-image: url(/vpn/images/ctxHeader02.gif);
background-repeat: repeat-x;
display: none;
}

To change the background to a custom one, modify the following file:

/images/ctxHeader02.gif)

Should you have changed the logo height, don’t forget to change the height in the header_middle style above.

3. The Separating Banner

To remove the separating banner, find the css class .navbar in /images/caxtonstyle.css on lines 148-153 and add the highlighed line.

.navbar
{
height: 26px;
background-image: url(/vpn/images/NavBarLink.gif);
background-repeat: repeat-x;
display: none;

To change the seperating banner replace the image file below:

images/NavBarLink.gif

4. The Glow Box Top Left Corner

To change the glow box image replace the image files below:

images/LoginPaneTopLeftBorderGlow.png
images/LoginPaneTopLeftBorderGlow.gif

Please note the image file must remain the same size.

5. The Glow Box Top Edge

To change the glow box image replace the image files below:

images/LoginPaneTopMidBorderGlow.png
images/LoginPaneTopMidBorderGlow.gif

Please note the image file must remain the same size.

6. The Glow Box Top Right Corner

To change the glow box image replace the image files below:

images/LoginPaneTopRightBorderGlow.png
images/LoginPaneTopRightBorderGlow.gif

Please note the image file must remain the same size.

7. The Glow Box Left Edge

To change the glow box image replace the image files below:

images/LoginPaneCenterLeftBorderGlow.png
images/LoginPaneCenterLeftBorderGlow.gif

Please note the image file must remain the same size.

8. The Glow Box Right Edge

To change the glow box image replace the image files below:

images/LoginPaneCenterRightBorderGlow.png
images/LoginPaneCenterRightBorderGlow.gif

Please note the image file must remain the same size.

9. The Glow Box Bottom Left Corner

To change the glow box image replace the image files below:

images/LoginPaneBottomLeftBorderGlow.png
images/LoginPaneBottomLeftBorderGlow.gif

Please note the image file must remain the same size.

10. The Glow Box Bottom Edge

To change the glow box image replace the image files below:

images/LoginPaneFooterMidBorderGlow.png
images/LoginPaneFooterMidBorderGlow.gif

Please note the image file must remain the same size.

11. The Glow Box Bottom Right Corner

To change the glow box image replace the image files below:

images/LoginPaneBottomRightBorderGlow.png
images/LoginPaneBottomRightBorderGlow.gif

Please note the image file must remain the same size.

12. The Welcome Text

To change the Welcome text style, find the css class .CTX_ContentTitleHeader in /images/caxtonstyle.css on lines 213-220.

.CTX_ContentTitleHeader
{
font-family: Segoe UI, Tahoma,Verdana, Helvetica, Arial, sans-serif;
font-size: 12pt;
font-weight: bold;
margin: 0;
color: #ABABAB;
}

To change the text, find the string id “Welcome” in /resources/en.xml (or the language you require) on line 55 and edit the highlight text as required

Welcome

13. The ‘Please log on to continue’ Text

To change the Welcome text style, find the css class .CTX_ContentTitleHeader in /images/caxtonstyle.css on lines 19-24.

.CTXMSAM_LogonFont
{
font-size: 8pt;
font-family: Arial;
color: White;
}

To change the text, find the string id “Please log on to continue” in /resources/en.xml (or the language you require) line 56 and edit the highlight text as required

Please log on to continue.

14. The Secure Padlock Image

To change the image replace the image files below:

/images/LoginIcon.png

15. The ‘User name:’ Text

To change the text, find the string id “User_name” in /resources/en.xml (or the language you require) on line 57 and edit the highlight text as required.

User name:

16. The ‘Password:’ Text

To change the password text for both the primary and secondary authentication methods, find the string id “Password” and “Password2” in /resources/en.xml (or the language you require) on line 59 and 60 and edit the highlight text as required.

Password
Password 2:

17. The Log On Button

To change the log on button colour and the rollover colour, edit or replace the following files:

/images/LoginButtonGlow.gif
/images/LoginButtonGlow.png
/images/LoginButtonGlow_Long.gif
/images/LoginButtonRolloverGlow.gif
/images/LoginButtonRolloverGlow.png
/images/LoginButtonRolloverGlow_Long.gif

Note, the replace images should be of the same size, alternatively edit the highlighted lines in /images/caxtonstyle.css.

.CTX_CaxtonButton
{
	height: 28px;
	width: 75px;
	font-family: Arial, Verdana, Helvetica, Sans-Serif;
	font-size: 8pt;
	color: White;
	cursor: default;
	border: 0px;
	background-image: url("/vpn/images/LoginButtonGlow.gif");
}

To change the log on text, find the string id “Log_on” in /resources/en.xml on line 62 and edit as required.

Log On

18. The Main Page Background

To change the background colour of the main page, find the css class body in /images/caxtonstyle.css on lines 222 to 235 and edit the highlighted line.

Please note, to change the background colour for the middle section of the page see point 21.

body
{
    color: white;
    /*
    background: black url(/vpn/images/MarginGradient.gif) repeat-x top left;
	*/
    background: black repeat-x top left;
    margin: 0px;
    padding: 0px;
    font-family: Segoe UI, Tahoma,Verdana, Helvetica, Arial, sans-serif;
    font-size: 70%;
    text-align: center;
    height: 100%;
 }

19. The Citrix Logo Footer

To remove the Citrix footer logo, find the css class .watermark in /images/caxtonstyle.css on lines 114 to 121 and add the highlighed line.

.watermark
{
width: 192px;
height: 62px;
background-position:bottom center;
background-image: url(/vpn/images/CitrixWatermark.gif);
background-repeat: no-repeat;
display: none;
}

To change the logo, replace the files below:

/images/CitrixWatermark.gif

20. The Logon Box Background

To change the logon box background, replace the files below:

/images/LoginPaneCenterMidGlow.gif
/images/LoginPaneCenterMidGlow.png

21. Mid-section Background Colour

The mid-section background colour and images are layered. To change the top layer background colour for the middle section, first find the css class .carbonBoxBottom in /images/caxtonstyle.css on lines 737 to 742 and change the following highlighed line to the colour you require or edit the image file below.

/images/LoginCarbonFiberBgFooter.gif

.carbonBoxBottom {
    text-align:center;
    padding-top: 10px;
    padding-bottom: 14px;
    background: black url(/vpn/images/LoginCarbonFiberBgFooter.gif) no-repeat bottom center;
}

Should you remove the image and background colour from the css above, find the css class .mainPane in /images/caxtonstyle.css on lines 237 to 247 and change the following highlighed line to the colour you require or edit the image file below.

/images/CenterBlueBkg.jpg

.mainPane
{
    margin: 0;
    padding: 0;
    color: #FFFFFF;
    background: #003C96 url(/vpn/images/CenterBlueBkg.jpg) repeat top left;
    left:0;
    right:0;
    border-top: 2px #999999 solid;
    border-bottom: 2px #999999 solid;
}

Finally, to make the changes stick, upload the updated contents would need to copied to each respective NetScaler (HA sync doesn’t copy these files) using WinSCP to the /netscaler/ns_gui/vpn (running config) and /var/vpn/vpn (start up config). This is explained in the following Citrix articles:

After all that, you should be able to create the customised look you require for your organisation. If I have missed anything please let me know and I will update the article.

How to mount a VHD from the command line using Citrix Provisioning Services 6.x

When using versioning in Provisioning services the mount option disappears from the context menu. However, you can still mount the VHD from the command line using the following command.

cvhdmount.exe

The executable can be found in C:\Program Files\Citrix\Provisioning Services and is simple to use. Using /? will show you the usage examples, the examples do not show the .avhd format when using version but it works just the same. Just remember, only mount private disk images and DO NOT mount images that are already in use, finally don’t forgot to use the -u command to unmount the disk when you are finished. I would always recommend taking a backup before edit any images.

How to suppress the Citrix Receiver 3.x URL Prompt

When you first install Citrix Receiver 3.x Enterprise each user will receive a prompt like this one.

To suppress this prompt simply create the following registry key.

[HKEY_CURRENT_USER\Software\Citrix\PNAgent]
“SuppressURLPromptAtLogin”=dword:00000001

Hope this helps.

Automating COM+ Applications Management Using VBScript

I wanted a script to add the Network Service account to all available roles for a specific COM+ application, however, it seems to be really hard to find out how to script these actions. Anyway after some research here is a sample script to assign the Network Service account in this case to all roles within the Sample COM+ application.

'' Setup variables
Const ApplicationName = "Sample"
Const AccountName = "NT AUTHORITY\NETWORK SERVICE"

'' Setup COM+ Application Catalog Object
Set Catalog = CreateObject("COMAdmin.COMAdminCatalog")
Set apps = Catalog.GetCollection("Applications")
''Populate the object with Applications from the COM Admin Catalog object
apps.populate

'' Loop for each application in the array
For each app in apps
'' Check for my application
    If app.Name = ApplicationName then
    '' If the application is found perform actions then create the roles object
        '' Clear the application Authentication Access Checks value
        app.Value("ApplicationAccessChecksEnabled") = false
        '' Set the application identity to be the Network Service
        app.Value("Identity") = "NT AUTHORITY\NetworkService"
        '' Save the changes to the application object
        apps.SaveChanges
        Set roles = apps.GetCollection("Roles", app.key)
        '' Populate the roles array with the roles from the current application in the initial loop
        roles.populate
        '' Loop each role in the roles array
        For each role in roles
            '' Setup the users array by getting the UsersInRole attribute
            Set users = roles.GetCollection("UsersInRole", role.Key)
            '' Add a new element in the array for the new user
            Set user = users.Add
            '' Set the user to add as the AccountName variable
            user.Value("User") = AccountName
            '' Save the changes to the array back to the COM+ Application
            users.SaveChanges
        '' Progress the roles loop
        Next
    '' Escape the If statment
    End If
'' Progress the application loop
Next

There is a useful MDSN article outlining all the avaliable object properties here

Hopefully this helps you automate your own COM+ Application administration.

Citrix XenApp 6.5 Initialize data store fails when creating a new farm

When working with a recent customer I came across a rather odd issue. I was creating a second XenApp farm for testing, however, I kept getting a failure when “Initializing the Citrix data store”.

The installer log showed little more than the following.

Exception: Initializing the Citrix data store failed.

The Windows system event log showed some further detail but still wasn’t giving much away. I had gone through many different troubleshooting steps including different database servers, rebuilding the server from a clean Windows DVD and manually setting up an ODBC connect to test the username, password and database. Everything worked as expected but the farm could still not be created.

Log Name: System
Source: IMAService
Date: 30/01/2012 17:04:42
Event ID: 3989
Task Category: None
Level: Error
Keywords: Classic
User: N/A
Computer: Server1
Description:
Citrix XenApp failed to connect to the Data Store. ODBC error while connecting to the database: IM002 -> [Microsoft][ODBC Driver Manager] Data source name not found and no default driver specified

Finally I tried some further troubleshooting including changing the farm name, database name, username and password. I was using SQL authentication in this instance, ultimately I found the issue was caused by the use of a semi-colon ; in the password. It appears ; is either an illegal or escape character for the XenApp farm creation. It is worth noting the semi-colon was accepted in an OBDC connection and at the SQL server.

Hope this helps!

Automating diskpart commands using PowerShell

A small script to generate a ASCII text file to automate diskpart. Using this with PSExec can make a quick yet powerful tool.

This script in particular automates the process of rescanning a disk and extending the select volume in Windows Server 2008 or Windows 7.

$script = $Null
$script = @"
rescan 
select disk 0
select volume 2
extend
exit
"@
$script | Out-File -Encoding ASCII -FilePath "c:\Diskpart-extend.txt"

diskpart.exe /s c:\Diskpart-extend.txt

Checking for VM Snapshots in vCenter using Powershell

A small script to output snapshots per VM.

Connect-VIServer myserver.fqdn.com
Write "#####START#####"
$vms = $null
$vms = Get-VM
foreach ($vm in $vms) {
$snapshots =  Get-Snapshot -VM $vm
$i = 1
foreach ($snapshot in $snapshots) {
$i = $i + 1
if ($i -ge 2) {
$vm.name
$i
#$snapshot.Name
#$snapshotTable =  @($vm.Name) # | Sort-Object {$_.name}
#$snapshotTable
}
}
}
Write "#####DONE######"

You can also list snapshots based on a name containing any value using the following code:

Get-VM | Get-Snapshot | Where-Object {$_. -contains "searchString"}