XenApp and XenDesktop PowerShell – Update MCS Image

If you need to automate the updating of a Machine Creation Services machine catalog, this script will be useful. It was created for a XenServer host.

The first part is to setup my parameters.

Function Update-MCSCatalog {
    [string] $xdControllers, #FQDN of a delivery controller
    [string] $MachineCatalogName, #Name of the MCS Machine Catalog
    [string] $MasterImage, #VM name for the master image
    [string] $storageResource, #The name of the host connection's resource from Citrix Studio
    [string] $HostResource, #The name of the host connection from Citrix Studio
    [string] $XSMaster, #The FQDN of the master XenServer host
    [string] $XenServerUsername, #XenServer host username
    [string] $XenServerPW #XenServer host password

First, make sure we load the Citrix PowerShell modules.

Write-Host (date -Format hh:mm:ss)   -   Updating machine catalog $machineCatalogName with the master VM $MasterImage -Foregroundcolor Green -Verbose

# Load the Citrix PowerShell modules
Write-Host (date -Format hh:mm:ss)   -   Loading Citrix XenDesktop modules. -Foregroundcolor Yellow -Verbose
Add-PSSnapin Citrix*

Next, we need to gather information about the XenDesktop infrastructure. We need storage and hypervisor information from Citrix Studio

# Get information from the hosting environment via the XD Controller
# Get the storage resource
Write-Host (date -Format hh:mm:ss)   -   Gathering storage and hypervisor connections from the XenDesktop infrastructure. -Foregroundcolor Yellow -Verbose
$hostingUnit = Get-ChildItem -AdminAddress $xdControllers "XDHyp:\HostingUnits" | Where-Object { $_.PSChildName -like $storageResource } | Select-Object PSChildName, PsPath

# Get the hypervisor management resources
$hostConnection = Get-ChildItem -AdminAddress $xdControllers "XDHyp:\Connections" | Where-Object { $_.PSChildName -like $hostResource }

# Get the broker connection to the hypervisor management
$brokerHypConnection = Get-BrokerHypervisorConnection -AdminAddress $xdControllers -HypHypervisorConnectionUid $hostConnection.HypervisorConnectionUid

Updates to an MCS catalog requires a VM snapshot. This section creates a new snapshot with the current date/time as the snapshot name.

# Get the master VM image from the storage resource
Write-Host (date -Format hh:mm:ss)   -   Getting the snapshot details for the catalog: $machineCatalogName  -Foregroundcolor Yellow -Verbose
$VM = Get-ChildItem "XDHyp:\HostingUnits\$storageResource" | Where-Object { $_.ObjectType -eq "VM" -and $_.Name -like $masterImage }
# Create snapshot.
$CurrentTime = Get-Timestamp
$Snapshot = New-HypVMSnapshot  -AdminAddress $XDControllers -LiteralPath $vm.FullPath -SnapshotName $CurrentTime
# Get the snapshot object
$VMSnapshots = Get-ChildItem -AdminAddress $xdControllers $VM.FullPath -Recurse -Include *.snapshot
$TargetSnapshot = $VMSnapshots | Where-Object { $_.FullPath -eq $snapshot }

This is the big part, update a machine catalog with the selected snapshot.

# Publish the image update to the machine catalog
$ProvScheme = Set-ProvSchemeMetadata -AdminAddress $xdControllers -Name 'ImageManagementPrep_DoImagePreparation' -ProvisioningSchemeName $machineCatalogName -Value 'True'
$PubTask = Publish-ProvMasterVmImage -AdminAddress $xdControllers -MasterImageVM $TargetSnapshot.FullPath -ProvisioningSchemeName $machineCatalogName -RunAsynchronously
$provTask = Get-ProvTask -AdminAddress $xdControllers -TaskId $PubTask

Would be nice to have a screen output showing the progress of the update process, as this can take some time.

# Track progress of the image update
Write-Host (date -Format hh:mm:ss)   -   Tracking progress of the machine creation task. -Foregroundcolor Yellow -Verbose
$totalPercent = 0
While ( $provTask.Active -eq $True ) {
    Try { $totalPercent = If ( $provTask.TaskProgress ) { $provTask.TaskProgress } Else {0} } Catch { }

    Write-Progress -Activity "Provisioning image update" -Status "$totalPercent% Complete:" -percentcomplete $totalPercent
    Sleep 15
    $provTask = Get-ProvTask -AdminAddress $xdControllers -TaskId $PubTask
Write-Progress -Activity "Provisioning image update"

Once the updates are master disk image are complete, we need to get these applied to all of the machines in the machine catalog. This section forces a reboot of all machines within the machine catalog.

# Start the desktop reboot cycle to get the update to the actual desktops
Write-Host (date -Format hh:mm:ss)   -   Initiating reboot of Machine Catalog $MachineCatalogName   -Foregroundcolor Yellow -Verbose
Get-brokerCatalog -Name $MachineCatalogName | Start-BrokerRebootCycle -AdminAddress $xdControllers -RebootDuration 1 -WarningDuration 0

This section is optional, but I like my VMs to have a description that says what VM was used as the master VM. Helps me remember.

# Change description for the VMs in the MachineCatalog to be the name of the master image VM
$XSSession = Connect-XenServer -server $XSMaster -UserName $XenServerUsername -Password $XenServerPW -SetDefaultSession -force
$CatalogVMs = Get-BrokerMachine | where { $_.CatalogName -eq $MachineCatalogName }
Foreach ( $catalogVM in $CatalogVMs) {
    set-xenvm -name $catalogvm.hostedmachinename -NameDescription $MasterImage
Disconnect-XenServer -session $XSSession

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.

Blog at WordPress.com.

Up ↑

%d bloggers like this: