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 { param( [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 )
For the variables $StorageResource and $HostResource, you will use the names from Citrix Studio – Configuration – Hosting. I use “XenServer” for $HostResource and “XS_SharedStorage” for $StorageResource
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 }
Hello Could you help me i cant see to get this to work i keep getting error with the string can you show me where to put them. : [string] $xdControllers, #FQDN of a delivery controller
LikeLike
I’m just calling this function like this:
update-MCSCatalog -XDControllers “ddc-test.snpp.local” -MachineCatalogName “TestCatalog” -MasterImage “Win10-1809” -StorageResource “XS_SharedStorage” -HostResource “XenServer” -XSMaster “XS1.snpp.local”
What error do you get?
LikeLike
Hello Daniel,
Thank you for sharing the script. I hope to use it our environment to update the VMs in Machine Catalog. Question on
on the script parameters. I am new Citrix SDK. Not sure how to get value of the $storageResource, $HostResource?
Is $XSMaster variable would be a vCenter server? Thank you in advance.
LikeLike
I added a screen shot on where to get the $STorageResource and $hostResource items. It comes from Studio.
For a vSphere environment, I believe you will use the vCenter server FQDN. Don’t have vSphere handy to test it out. You will also want to remove the last section “# Change description for the VMs in the MachineCatalog to be the name of the master image VM” as this is using XenServer powershell. I believe the rest of the function uses Virtual Apps/Desktops Powershell functions.
LikeLike
getting a issue issue with : $brokerHypConnection = Get-BrokerHypervisorConnection -AdminAddress $xdControllers -HypHypervisorConnectionUid $hostConnection.HypervisorConnectionUid
Get-BrokerHypervisorConnection : Cannot bind parameter ‘HypHypervisorConnectionUid’ to the target. Exception setting “HypHypervisorConnectionUid”: “Object reference not set to an instance
of an object.”
At line:1 char:112
+ … rConnectionUid $hostConnection.HypervisorConnectionUid
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : WriteError: (:) [Get-BrokerHypervisorConnection], ParameterBindingException
+ FullyQualifiedErrorId : ParameterBindingFailed,Citrix.Broker.Admin.SDK.GetBrokerHypervisorConnectionCommand
LikeLike
Will need to track down which item before that fails. When it fails, do you have info for the variable $HostConnection?
I added a screenshot to the blog identifying where to get the $StorageResource and $HostResource variable names.
LikeLike
where do I get this from ? “variable $HostConnection”
LikeLike
Look in Citrix Studio under Configuration – Hosting. In the image in the blog, you can see mine is called “XenServer”. I use that for the $HostConnection. Within that host connection is XS_SharedStorage. I use that for my $StorageResource
LikeLike
$VM = Get-ChildItem “XDHyp:\HostingUnits\$storageResource” | Where-Object { $_.ObjectType -eq “VM” -and $_.Name -like $masterImage }. $VM is blank, unfortunately my W10 master images are in a vSphere resource pool under Citrix/Master, not at the root level. So the required VM object is not retrieved
Small point, I guess
PS I always enjoy your Citrix presentations
LikeLike
How do I kick off the script because when i run it it just shows all the code nothing else.
LikeLike
It’s a function that you have to call…
update-MCSCatalog -XDControllers “ddc-test.snpp.local” -MachineCatalogName “TestCatalog” -MasterImage “Win10-1809” -StorageResource “XS_SharedStorage” -HostResource “XenServer” -XSMaster “XS1.snpp.local”
LikeLike
thank you so much i was able to kick it off and everything went fine but today keep getting the following error:
New-HypVMSnapshot : Cannot validate argument on parameter ‘LiteralPath’. The argument is null. Provide a valid value for
the argument, and then try running the command again.
LikeLike
This is *almost* what I’ve been hunting around for since Citrix has mysteriously not given us scheduling options in the GUI. Before i get started making this work with vmware, has anyone already done that yet? If not, I’ll reply back here with an updated version that’ll work with vmware.
LikeLike
Greg,
Were you able to get the script updated for MVWare? I’ve run into this same problem on my side.
LikeLike