Category Archives: Application

Downloading Citrix App Layering (Unidesk)

unidesk_ww
Intro

About a week ago (April 3, 2017), Citrix released App Layering 4.1.0. This is the slightly rebranded Unidesk and Citrix is emphasizing (over-emphasizing based on some comments) that¬†it…

Achieves app compatibility greater than 99.5%

I find it interesting that out of the gate, Citrix is positioning App Layering as a direct competitor/replacement for Microsoft App-V, which I believe has¬†more success supporting many different types of applications (this is based on my years of experience with App-V and minutes spent with Unidesk ūüôā ). I always viewed Unidesk as a more comprehensive approach to delivering a fully realized, layered solution. But let’s face it, most Citrix administrators/engineers have to become application analysts/re-packagers/engineers in order to make applications work in a Citrix deployment. This blog will not dive into using App Layering, but instead will try and shine some light on actually downloading this “new” product from Citrix

Requirements

Note: The following is based on discussions with our Citrix sales engineer and the Unidesk website
  • You must be active on Select Service to use it.
  • You must have platinum licensing if you wish to run App Layering on-premises.
  • You must have a one of the following hypervisors
    • Citrix XenServer (6.5, 7.0, 7.1)
    • Microsoft Azure
    • Microsoft Hyper-V (at least 2012 R2)
    • Nutanix Acropolis
    • VMware VSphere (5.5.x, 6.0.x, 6.5.x)
  • SMB Network File Share Protocol
  • A network connection of 10GB between the Layering appliance and the file share
  • One of the following publishing platforms
    • Citrix MCS for Nutanix AHV
    • Citrix MCS for vSphere
    • Citrix MCS for XenServer
    • Citrix PVS 7.1, 7.6 – 7.9, 7.11 – 7.12 with recommended network speeds to the PVS Store of 10 GB.
    • Citrix XenApp and XenDesktop 6.5, 7.0 – 7.12
    • Microsoft Azure, with recommended network speeds to the Azure publishing location of 10 GB.
    • VMware Horizon View 6.x, 7.0.x (Note: View Persona Management is not supported with Elastic Layering)
  • A Citrix Cloud Account

How to Download

Login into your Citrix Cloud Account
unidesk1

Go down to Available Services and click Request Trial on App Layering
unidesk2

Once you receive an email from Citrix Cloud, log back into your account. Find App Layering and click Manage
unidesk3

On the App Layering screen, click Get Started
unidesk4
Install the Cloud Connector (This will be required if you do not have local resources to run the appliance).

Note: Installing the Cloud Connector will affect your existing Citrix Studio install. You will have to uninstall the Cloud Connector and Studio and then reinstall Studio if you installed the Connector accidentally or just to try it out.

unidesk5

Download the appliance
unidesk6

Install and Configure the Appliance
unidesk7
unidesk8

That’s all for now

I won’t cover the install and configuration of the appliance at this time. Hopefully, this helps shed some¬†light on actually downloading the appliance. If you do not have Platinum Citrix licensing or Select, you can still download a trial from the¬†Unidesk web site.

Thanks for reading,
Alain

Advertisements

Application woes: Solarwinds Advanced Subnet Calculator

bg_adv_subnet_calc_top

Solarwinds Advanced Subnet Calculator (ASC) is a great, freely-available tool to generates lists of IP4 networks. I recently ran into an issue installing it in a Windows 7 virtual desktop. It would run fine for administrators, but regular users received errors like this and this.

I broke out Process Monitor and Regshot to investigate what was going on here. I found that regular users could not register the SWLogo.ocx file listed in the above link. This makes sense as I had applied reasonable security on non-admins.
I reinstalled the ASC as the local admin (i.e. non-domain administrator) and that fixed one error for users, but a new one popped up. Running Process Monitor again, I found that ASC was expecting read/write permissions on

c:\programdata\Solarwinds\VB\Banners.

asc_error

This folder contains a series of bitmap banner ads for Solarwinds products. Not at all unreasonable for a free tool. Once I modified permissions in the disk image to allow users to modify (ha!) this folder I was back in business.

Thanks,
Alain

Powershell: XenDesktop 7.x Published Applications

xendesktop7iscoming

Intro

Citrix XenDesktop 7 represents a major change from previous versions of Citrix. Those of us who have managed large XenApp-based farms with many published applications will find us rushing to scour the Internet for how-to’s and Citrix documentation because everything “seems” very different.

You are not wrong…things are different, and if you are considering a move to XenDesktop 7.x, you owe it to yourself to document (in detail) what you have done in your current XenApp 6.5, 5.0, etc environment and examine how to do the same thing XenDesktop 7.x. In this blog post, we will look at a PowerShell script that will automate the creation of published applications in XenDesktop 7.6.

Scenario

I’m migrating a XenApp 6.5 / XenDesktop 5.6 environment to XenDesktop 7.6. In the old XenApp farm, users run a split Access database as a published application with many front-ends pointing to a single back-end. The idea of recreating 60+ published applications (each assigned to a single user) with the Citrix Studio GUI is like a dream come true…no I mean a nightmare.

I wanted to approach this with a script to automate the front-end creation and to minimize any user error. This could allow a lower-level admin or helpdesk member to create the front-end without opening up the Citrix Studio.

The Script

NOTE: The new-brokerapplication cmdlet resides in the Citrix.Broker.Admin.V2 module. It should available on any system/workstation with the Citrix Studio installed.

.SYNOPSIS
    Takes a username or list of usernames and creates the same published application for each user.
.DESCRIPTION
    Takes a username or list of usernames and creates the same published application for each user.

    It is recommended that this script be run as an AD and Citrix admin. In addition, the Citrix and MS Active Directory Powershell module should be available for user lookup and published application creation..
.PARAMETER username
    Required parameter.
    User account(s) that will be assigned published application. 
.PARAMETER pubappname
    Required parameter.
    Common name for published application. Script will append the username to this parameter so it will be unqiue for each user. 
.PARAMETER applocation
    Required parameter.
    Location of executable. Used for location in published application.
.PARAMETER cmmdline
    Optional parameter.
    Location of file or optional parameter that could go into command line field for a published application.
.PARAMETER DeliveryGroup
    Required parameter.
    Which Delivery Group to publish application to.
.PARAMETER DeliveryController
    Required parameter.
    Which Citrix Delivery Controller (farm) to publish applicaiton with
.EXAMPLE
    PS C:\PSScript > .\create-pubapp.ps1 -username TESTUSER -applocation "C:\app.exe" -DeliveryGroup "Production" -DeliveryController "CitrixStudio"
    
    Will create a new published application (c:\app.exe) assigned to TESTUSER and published to the Production Delivery Group.
.EXAMPLE
    PS C:\PSScript > .\create-pubapp.ps1 -username TESTUSER -applocation "C:\app.exe" -DeliveryGroup "Production" -DeliveryController "CitrixStudio" -verbose
    
    Will create a new published application (c:\app.exe) assigned to TESTUSER and published to the Production Delivery Group.
    Feedback and progress messages will be displayed.
.INPUTS
    None.  You cannot pipe objects to this script.
.OUTPUTS
    No objects are output from this script.  
    This script creates a Xendesktop 7.x published application.
.NOTES
    NAME: create-pubapp.ps1
    VERSION: 2.00
    CHANGE LOG - Version - When - What - Who
                 1.00 - 07/1/2015 - Initial script - Alain Assaf
                 1.01 - 07/6/2015 - Modified module import fuctions to use -like instead of -eq
                                    Created new parameter to capture delivery controller
                 2.00 - 07/6/2015 - Major edit to make this script more generic
    AUTHOR: Alain Assaf
    LASTEDIT: July 6, 2015
.LINK
    http://www.linkedin.com/in/alainassaf/
    http://wagthereal.com
    http://www.icenlemon.co.uk/blog/?p=307
    http://stackoverflow.com/questions/8388650/powershell-how-can-i-stop-errors-from-being-displayed-in-a-script

Param(
    [parameter(Position = 0, Mandatory=$True )]     
    [ValidateNotNullOrEmpty()]
    $username,
    
    [parameter(Position = 1, Mandatory=$True )]     
    [ValidateNotNullOrEmpty()]
    $pubappname,
    
    [parameter(Position = 2, Mandatory=$True )]     
    [ValidateNotNullOrEmpty()]
    $applocation,

    [parameter(Position = 3, Mandatory=$False )]     
    [ValidateNotNullOrEmpty()]
    $cmmdline,
    
    [parameter(Position = 4, Mandatory=$True )]     
    [ValidateNotNullOrEmpty()]
    $DeliveryGroup,
    
    [parameter(Position = 5, Mandatory=$True )]     
    [ValidateNotNullOrEmpty()]
    $DeliveryController
    )

#Constants
$datetime = get-date -format "MM-dd-yyyy_HH-mm"
$ScriptRunner = (get-aduser $env:username | select name).name
$PSModules = ("activedirectory")
$PSSnapins = ("*citrix*")
$compname =  (gci env:COMPUTERNAME).value
#$ErrorActionPreference= 'silentlycontinue' # Comment out to see all error messages
$addomain = (Get-ADDomain).name

### FUNCTION: get-mymodule #####################################################
Function Get-MyModule {
    Param([string]$name)
    if(-not(Get-Module -name $name)) {
        if(Get-Module -ListAvailable | Where-Object { $_.name -like $name }) {
            Import-Module -Name $name
            $true
        } #end if module available then import
        else { $false } #module not available
        } # end if not module
    else { $true } #module already loaded
}  
### FUNCTION: get-mymodule #####################################################

### FUNCTION: get-mysnapin #####################################################
Function Get-MySnapin {
    Param([string]$name)
    if(-not(Get-PSSnapin -name $name)) {
        if(Get-PSSnapin -Registered | Where-Object { $_.name -like $name }) {
            add-PSSnapin -Name $name
            $true
        } #end if module available then import
        else { $false } #snapin not available
        } # end if not snapin
    else { $true } #snapin already loaded
}  
### FUNCTION: get-mysnapin #####################################################

### FUNCTION: Check-ADUser #####################################################
#Function to check if user account exists in AD
Function Check-ADUser
{
    Param ($usrname)
 
    $isuser = $(try {Get-ADUser $usrname} catch {$null})
    if ($isuser -ne $null) {
        return $true
    } else {
        return $false
    }  
}
### FUNCTION: Check-ADUser #####################################################

#Import Module(s) and Snapin(s)
foreach ($module in $PSModules) {
    if (!(get-mymodule $module)) {
        write-verbose "$module PowerShell Cmdlet not available."
        write-verbose "Please run this script from a system with the $module PowerShell Cmdlets installed."
        exit
    }
}
foreach ($snapin in $PSSnapins) {
    if (!(get-MySnapin $snapin)) {
        write-verbose "$snapin PowerShell Cmdlet not available."
        write-verbose "Please run this script from a system with the $snapin PowerShell Cmdlets installed."
        exit
    }
}

#Confirm Delivery Group Exists
$testDG = Get-BrokerDesktopGroup $DeliveryGroup -AdminAddress $DeliveryController
if ($testDG -eq $null) {
    write-verbose "Delivery group - $DeliveryGroup - DOES NOT EXIST. Exiting"
    exit
}

#Confirm applicaiton exists on machine you are running the script from. If False warn admin.
if (test-path $applocation) {
} else {
    write-verbose "Published Application Location - $applocation - is not valid on $compname"
}

foreach ($user in $username) {
    if (Check-ADUser $user) { #User Exists - proceed
        write-verbose "User -$user - exists"
        $pubname = $pubappname + "-" + $user
        $newapp = new-BrokerApplication -name $pubname -commandlineexecutable $applocation -DesktopGroup $DeliveryGroup -ApplicationType HostedOnDesktop -CommandLineArguments $cmmdline -UserFilterEnabled $true -AdminAddress $DeliveryController 
        Add-BrokerUser "$addomain\$user" -Application $newapp.Name
    } else {
        write-verbose "User - $user - DOES NOT EXIST"
    }
}

Wait…what about the published application icon?

One of the parameters in the new-brokerapplication cmdlet is IconUid. If you want to assign something other than the default you can add this parameter to line 168 in the above script. I did not find an automated way to assign this icon. So, in this case I created an application using the GUI (and chose a non-default icon) and then ran this powershell command to see what the iconuid is:

get-brokerapplication -name "Notepad"
AdminFolderName                  :
AdminFolderUid                   : 3
ApplicationName                  : Notepad
ApplicationType                  : HostedOnDesktop
AssociatedDesktopGroupPriorities : {0}
AssociatedDesktopGroupUUIDs      : {1a9c3138-d236-4d70-a20b-78ff85d55897}
AssociatedDesktopGroupUids       : {4}
AssociatedUserFullNames          : {Domain Users}
AssociatedUserNames              : {Domain\Domain Users}
AssociatedUserUPNs               : {}
BrowserName                      : Notepad
ClientFolder                     : 
CommandLineArguments             : 
CommandLineExecutable            : C:\windows\system32\notepad.exe
CpuPriorityLevel                 : Normal
Description                      : 
Enabled                          : True
IconFromClient                   : False
IconUid                          : 2
MetadataKeys                     : {}
MetadataMap                      : {}
Name                             : Notepad
PublishedName                    : Notepad
SecureCmdLineArgumentsEnabled    : True
ShortcutAddedToDesktop           : False
ShortcutAddedToStartMenu         : False
StartMenuFolder                  : 
UUID                             : c7eb9ced-c7b4-4ea7-b58a-9157e06c144f
Uid                              : 14
UserFilterEnabled                : True
Visible                          : True
WaitForPrinterCreation           : False
WorkingDirectory                 :

Now you have the iconuid and it will apply the same icon to each published application instance.

Take care and have fun with XenDesktop 7.x

Thanks,
Alain