Free Consultation

XenApp 6.x to XenApp 7.x App Migration Script

In light of the fact the XenApp migration scripts from Citrix are not publicly available yet I have written this script

This script will migrate application from XenApp 6.x to XenDesktop 7.x – App Edition (from here on in referred to also as XenApp 7.x) and XenApp 7.x including all command lines and command line arguments, security, icon data, client folder info, and desktop short-cut placement info.

You have the option of adding new accounts / groups, replacing the old groups with the test accounts / groups, and disabling the apps during import.

XenApp 6.x and XenApp 7.x treat command line arguments differently (in XenApp 6.x they are tagged onto the end of the command line and in XenApp 7.x there is a different field) to accommodate this I had to search and split the XenApp 6.x command line field based on certain characters (/ ” etc). For this reason you might find that it doesn’t always work. Please let me know your results.

You need to install the XenDesktop Broker PowerShell cmdlets on a server in your XenApp 6.x farm and run the script from there. This was the most simple way to do this as it is much easier to remote commands with the XenApp 7.x PowerShell cmdlets (you just specify the controller address).

The PowerShell cmdlet you need to install is x64Citrix Desktop Delivery ControllerBroker_PowerShellSnapIn_x64.msi in the XenApp 7.x install media.

Some of the names of the applications in XenApp 7.x Studio may appear with new display names, this is due to the fact that Studio does not allow duplicate Application Display Names in the console so I had to use the Application Browser Name, which is unique.

I could not find an easy way to bring across File Type Associations so you will need to select these in the apps once they are migrated.

Disclaimer: Use this script at your own risk. All scripts should be tested on non-Production environments first.

Update
Script has been updated to version 1.2

Please see the version notes file for information.

[download id=”1508″]

[download id=”1517″]

[download id=”1521″]

[download id=”1519″]

[download id=”1535″]

Full list of syntax and help is available by typing Get-Help XenApp_App_Migration_V1.1.ps1

<#
.SYNOPSIS
Migrates published applications from XenApp 6.x to XenDesktop 7.x – App Edition and XenApp 7.x
.DESCRIPTION
Imports applications into XenDesktop 7.x that were exported from XenApp 6 or XenApp 6.5 using the AppImport.ps1 script
.PARAMETER Folders
The folders within the XenApp farm to be migrated. Should be specified as “Applications If no folders are specified all applications in the farm
will be migrated.
.PARAMETER AdminAddress
The FQDN address of a XenDesktop 7.x delivery controller in the destination farm. Defaults to localhost if not specified
.PARAMETER DesktopGroup
The Delivery Group that the applications will be published to.
Default is 20%
.PARAMETER NewAccounts
The names of new accounts or groups that will be added to the applications when they are imported.
These should be in the format of DomainUserName or DomainGroup and seperated by commas
.PARAMETER ReplaceAccounts
No groups will be migrated from XenApp 6.x. Only test accounts will be added to the new Published Applications.
.PARAMETER DisableApps
Disable all the applications during import.
.PARAMETER Path
The path where the report will be saved to.
.EXAMPLE
PS C:PSScript > XenApp_App_Migration_V1.2.ps1 -AdminAddress myxendesktopcontroller.mydomain.com -DeliveryGroup Finance

Will migrate all applications from the XenApp 6 farm to the Finance Delivery Group in the XenApp 7 farm.
.EXAMPLE
PS C:PSScript > XenApp_App_Migration_V1.2.ps1 -Folders “ApplicationsProduction”,”ApplicationsHuman ResourcesLive” -AdminAddress myxendesktopcontroller.mydomain.com
-DeliveryGroup Windows2008R2

Will migrate all the applications in the folders Production and Human ResourcesLive from the XenApp 6 farm to the
Finance Delivery Group in the XenApp 7 farm.
.EXAMPLE
PS C:PSScript > XenApp_App_Migration_V1.2.ps1 -AdminAddress myxendesktopcontroller.mydomain.com -DeliveryGroup Finance -NewAccounts “MyDomainTest Group”

Will migrate all applications from the XenApp 6 farm to the Finance Delivery Group in the XenApp 7 farm.
The group Test Group will be added to all applications during import.
.EXAMPLE
PS C:PSScript > XenApp_App_Migration_V1.2.ps1 -AdminAddress myxendesktopcontroller.mydomain.com -DeliveryGroup Finance -NewAccounts “MyDomainTest Group” -ReplaceAccounts $true

Will migrate all applications from the XenApp 6 farm to the Finance Delivery Group in the XenApp 7 farm.
The group Test Group will replace all existing accounts and groups on the published applications during import
.EXAMPLE
PS C:PSScript > XenApp_App_Migration_V1.2.ps1 -AdminAddress myxendesktopcontroller.mydomain.com -DeliveryGroup Finance -DisableApps $true -Path C:Temp

Will migrate all applications from the XenApp 6 farm to the Finance Delivery Group in the XenApp 7 farm.
All Published Apps will be disable during import
Report will be saved to C:temp
.INPUTS
None. You cannot pipe objects to this script.
.OUTPUTS
No objects are output from this script. This script creates a its own logs files
.LINK
http://www.shaunritchie.co.uk
.NOTES
NAME: XenApp_App_Migration_V1.2.ps1
VERSION: 1.2
AUTHOR: Shaun Ritchie
#>

#Thanks to @jeffwouters and @carlwebster for the below parameter structure.

[CmdletBinding(SupportsShouldProcess = $False, ConfirmImpact = “None”, DefaultParameterSetName = “”) ]
Param (
[parameter(Mandatory=$False)]
[Alias(“F”)]
[ValidateNotNullOrEmpty()]
[Array]$Folders=””,

[parameter(Mandatory=$True)]
[Alias(“AA”)]
[ValidateNotNullOrEmpty()]
[String]$AdminAddress=””,

[parameter(Mandatory=$True)]
[Alias(“DG”)]
[ValidateNotNullOrEmpty()]
[String]$DesktopGroup=””,

[parameter(Mandatory=$False)]
[Alias(“NA”)]
[ValidateNotNullOrEmpty()]
[Array]$NewAccounts=””,

[parameter(Mandatory=$False)]
[Alias(“RA”)]
[ValidateNotNullOrEmpty()]
[Boolean]$ReplaceAccounts=$False,

[parameter(Mandatory=$False)]
[Alias(“DA”)]
[ValidateNotNullOrEmpty()]
[Boolean]$DisableApps=$False,

[parameter(Mandatory=$True)]
[Alias(“P”)]
[ValidateNotNullOrEmpty()]
[String]$Path=””)

Add-PSSnapin Citrix.* -ErrorAction silentlycontinue

# Get Desktop Group UID

$DesktopGroupUID = Get-BrokerDesktopGroup -AdminAddress $AdminAddress -Name $DesktopGroup

[Array]$AppReport = @()
[Array]$XAApplist = @()
If ($Folders -ne $null)
{
ForEach ($Folder in $Folders)
{
$SubFolders += Get-XAFolder -FolderPath $Folder -Recurse
$XAAppList += Get-XAApplication -FolderPath $Folder
}
If ($SubFolders -ne $null)
{
ForEach ($SubFolder in $SubFolders)
{
$XAAppList += Get-XAApplication -FolderPath $SubFolder
}
}
ForEach ($XAApp in $XAAppList)
{
$AppReport += Get-XAApplicationReport -BrowserName $XAApp.BrowserName
}
}
Else
{
$AppReport = Get-XAApplicationReport *
}

$AppReport= $AppReport | Where-Object {$_.ApplicationType -eq “ServerInstalled”}

#Get FTA and IconData information for each application.

[Array]$AppIcons = @()

ForEach ($App in $AppReport)
{
$AppIcons += Get-XAApplicationIcon -BrowserName $App.BrowserName
}

Start-Transcript -Path ($Path + “XenApp_App_Migration.txt”)

# Break up command line executable and command line arguments ready for input

ForEach ($App in $AppReport)
{
[Array]$CommandLines = @()
If (($App.CommandLineExecutable.Contains(” /”)) -eq $True)
{
$CommandLines = $App.CommandLineExecutable -split ” /”
$CommandLines[1] = “/” + $CommandLines[1]
}

ElseIf (($App.CommandLineExecutable.Contains(‘” ‘)) -eq $True)
{
$CommandLines = $App.CommandLineExecutable -split ‘” ‘
}

ElseIf (($App.CommandLineExecutable.Contains(‘”‘)) -eq $True)
{
$CommandLines += ($App.CommandLineExecutable -replace ‘”‘, “”)
}
Else
{
$CommandLines += ($App.CommandLineExecutable)
}

# Create the application icon

$XA6IconData = $AppIcons | Where-Object {$_.BrowserName -eq $App.BrowserName}
$BrokerIcon = New-BrokerIcon -AdminAddress $AdminAddress -EncodedIconData $($XA6IconData.EncodedIconData -as [string])

#Create the application

If ($CommandLines[1] -eq $null -and $DisableApps -eq $True)
{
New-BrokerApplication -Name $App.BrowserName -AdminAddress $AdminAddress -ApplicationType ‘HostedOnDesktop’ -BrowserName $App.BrowserName -ClientFolder $App.ClientFolder -CommandLineExecutable ($CommandLines[0] -Replace ‘”‘, “”) -CpuPriorityLevel $($App.CpuPriorityLevel -as [string]) -Description $App.Description -DesktopGroup $DesktopGroupUID.Uid -Enabled $False -IconUid $BrokerIcon.Uid -Priority 0 -PublishedName $App.BrowserName -SecureCmdLineArgumentsEnabled $True -ShortcutAddedToDesktop $($App.AddToClientDesktop -as [bool]) -ShortcutAddedToStartMenu $($App.AddToClientStartMenu -as [bool]) -UserFilterEnabled $True -Visible $False -WaitForPrinterCreation $($App.WaitOnPrinterCretion -as [bool]) -WorkingDirectory $App.WorkingDirectory
}
ElseIf ($CommandLines[1] -eq $null -and $DisableApps -eq $False)
{
New-BrokerApplication -Name $App.BrowserName -AdminAddress $AdminAddress -ApplicationType ‘HostedOnDesktop’ -BrowserName $App.BrowserName -ClientFolder $App.ClientFolder -CommandLineExecutable ($CommandLines[0] -Replace ‘”‘, “”) -CpuPriorityLevel $($App.CpuPriorityLevel -as [string]) -Description $App.Description -DesktopGroup $DesktopGroupUID.Uid -Enabled $($App.Enabled -as [bool]) -IconUid $BrokerIcon.Uid -Priority 0 -PublishedName $App.BrowserName -SecureCmdLineArgumentsEnabled $True -ShortcutAddedToDesktop $($App.AddToClientDesktop -as [bool]) -ShortcutAddedToStartMenu $($App.AddToClientStartMenu -as [bool]) -UserFilterEnabled $True -Visible $True -WaitForPrinterCreation $($App.WaitOnPrinterCretion -as [bool]) -WorkingDirectory $App.WorkingDirectory
}
ElseIf ($CommandLines[1] -ne $null -and $DisableApps -eq $True)
{
New-BrokerApplication -Name $App.BrowserName -AdminAddress $AdminAddress -ApplicationType ‘HostedOnDesktop’ -BrowserName $App.BrowserName -ClientFolder $App.ClientFolder -CommandLineExecutable ($CommandLines[0] -Replace ‘”‘, “”) -CommandLineArguments (($CommandLines[1] -Replace ‘”‘, “”) + ($CommandLines[2] -Replace ‘”‘, “”) + ($CommandLines[3] -Replace ‘”‘, “”) + ($CommandLines[4] -Replace ‘”‘, “”)) -CpuPriorityLevel $($App.CpuPriorityLevel -as [string]) -Description $App.Description -DesktopGroup $DesktopGroupUID.Uid -Enabled $False -IconUid $BrokerIcon.Uid -Priority 0 -PublishedName $App.BrowserName -SecureCmdLineArgumentsEnabled $True -ShortcutAddedToDesktop $($App.AddToClientDesktop -as [bool]) -ShortcutAddedToStartMenu $($App.AddToClientStartMenu -as [bool]) -UserFilterEnabled $True -Visible $False -WaitForPrinterCreation $($App.WaitOnPrinterCretion -as [bool]) -WorkingDirectory $App.WorkingDirectory
}
ElseIf ($CommandLines[1] -ne $null -and $DisableApps -eq $False)
{
New-BrokerApplication -Name $App.BrowserName -AdminAddress $AdminAddress -ApplicationType ‘HostedOnDesktop’ -BrowserName $App.BrowserName -ClientFolder $App.ClientFolder -CommandLineExecutable ($CommandLines[0] -Replace ‘”‘, “”) -CommandLineArguments (($CommandLines[1] -Replace ‘”‘, “”) + ($CommandLines[2] -Replace ‘”‘, “”) + ($CommandLines[3] -Replace ‘”‘, “”) + ($CommandLines[4] -Replace ‘”‘, “”)) -CpuPriorityLevel $($App.CpuPriorityLevel -as [string]) -Description $App.Description -DesktopGroup $DesktopGroupUID.Uid -Enabled $($App.Enabled -as [bool]) -IconUid $BrokerIcon.Uid -Priority 0 -PublishedName $App.BrowserName -SecureCmdLineArgumentsEnabled $True -ShortcutAddedToDesktop $($App.AddToClientDesktop -as [bool]) -ShortcutAddedToStartMenu $($App.AddToClientStartMenu -as [bool]) -UserFilterEnabled $True -Visible $False -WaitForPrinterCreation $($App.WaitOnPrinterCretion -as [bool]) -WorkingDirectory $App.WorkingDirectory
}

# Create the user / groups in the database and map to the application

#[Array]$Accounts = @()
If ($ReplaceAccounts -ne $true)
{
$Accounts = $App.Accounts
ForEach ($Account in $Accounts)
{
New-BrokerUser -Name $Account.AccountDisplayName
Add-BrokerUser -Name $Account.AccountDisplayName -Application $App.BrowserName
}
}
# Create the test users / groups in the database and map to the application

If ($NewAccounts -ne $null)
{
ForEach ($NewAccount in $NewAccounts)
{
New-BrokerUser -Name $NewAccount
Add-BrokerUser -Name $NewAccount -Application $App.BrowserName
}
}
}

Stop-Transcript