Citrix Virtual Apps and Desktops (CVAD) includes two mechanisms which allow new machines to be quickly created in order to add additional capacity for end users. These are Machine Creation Services (MCS) and Provisioning Services (PVS).
This article does not go into details of how these work or how to set them up and assumes that a machine catalogue using MCS has already been created – we shall show how to use PowerShell to create brand-new machines in this catalogue and assign them to a delivery group.
It is of course possible to create the MCS based machine catalogues themselves with PowerShell – in fact, a whole CVAD implementation can be built from scratch with PowerShell if required.
Prior to performing the steps to create the machines, the CVAD PowerShell cmdlets must be loaded. Prior to release 1912 (LTSR), these were provided as (legacy) snap ins whereas from that release onwards they are available as modules (read the first part of this series for more information: An Introduction to PowerShell in Citrix Virtual Apps and Desktops).
The following code will work on all releases to load the cmdlets used in this post:
The code can be run on a Citrix Delivery Controller or on any machine where Citrix Studio or the CVAD PowerShell cmdlets are installed where the latter is preferred for resource consumption reasons. If the latter is used, the parameter -AdminAddress must be specified to the Citrix cmdlets in order to direct the calls to a specified delivery controller.
Creating Active Directory Machine Accounts
Since we are assuming that we are adding machines to an existing catalogue, various internal structures which the PowerShell code needs will already have been created, although these are not visible as discrete entities in Citrix Studio.
One of these will be an identity pool which, if created by Citrix Studio, will have the same name as the catalogue to which it applies and contains the naming convention chosen when the catalogue was created (see figure 1).
Fig. 1: When setting up a machine catalogue you must also define a naming convention for its machines
We can check that the identity pool we require exists with the following command:
Figure 2 shows the output.
Fig. 2: Using Get-AcctIdentityPool to check whether a certain identity pool exists
Which we can see correspond to the MCS machine catalogues in existence (figure 3):
Fig. 3: The list of catalogues shows the existing MCS catalogues
To create the Active Directory accounts for the new machines, we run the following which creates two machine accounts using the naming convention and OU defined in the specified identity pool – note that we do not have to specify the name, or name base, ourselves:
We have assigned the result to a variable as we will be using it in the next step, but we can check the result by looking at the contents of this variable (figure 4):
Fig. 4: Content of the variable $newAccounts
If you check AD, you should see these machine accounts have been created in the correct OU.
Creating Virtual Machines
We now need to create the virtual machines corresponding to these AD accounts and for this we need the provisioning scheme name which will have been created when the MCS machine catalogue was created and, as with the identity pools, will have the same name as the catalogue to which it pertains.
Fig. 5: Retrieving the provisioning scheme name via PowerShell
When creating the VMs, we create a task which can either be run synchronously, so the cmdlet will not return until the task has fully completed, or run asynchronously such that the cmdlet returns immediately. In the latter case you have to check that the task has completed before continuing although this can be useful if the task could take a long time to run such that other actions need to be performed or a progress indicator needs to be displayed.
Here we run it async in order to show how we check that the task has completed.
The task GUID is stored in the variable which we can query, as seen in figure 6:
Fig. 6: Properties of $taskDetails
Notice the Active, Status, TaskState and TaskStateInformation properties which we can use to test whether the task has completed or not. Note that when checking the properties in a loop, have some kind of delay, such as via Start-Sleep, to reduce the CPU consumption of this polling loop.
Adding the Machines to a Catalogue
Now that we have created the VMs, which can be verified in your hypervisor console, we can add them as machines to a machine catalogue. The sample below has a placeholder for error handling if an error should occur – do not neglect error checking/reporting!
Figure 7 shows that the execution was successful:
Fig. 7: The search result shows all VMs that are part of the “MCS Server 2019” machine catalogue
Adding the Machines to a Delivery Group
In order for these newly created machines to be available for end users, they need to belong to a delivery group which is achieved by running the following:
As expected, figure 8 shows that the machines have been successfully added to the Delivery Group.
Fig. 8: The search result shows all VMs that are part of the “MCS Server 2019” Delivery Group
Powering on the Machines
Assuming this succeeds, all that remains to be done is to power on these new machines so that they boot, register with a delivery controller and thence become available to provide published applications and/or desktops.
Notice in the PowerShell below that it changes the computer account name contained in the $taskDetails variable by removing the “$” character at the end of the name to turn it into an AD computer name.
This is achieved with a regular expression (regex) where $ is a special character meaning the end of the string, so we have to escape it using the backslash character.
If everything has worked correctly, Citrix Studio should now show the newly created machines (figure 9) and after a short delay, to allow them to boot, they should be registered and thus capable of being used to supply apps and/or desktops that use the delivery group.
Fig. 9: Overview of the newly created VM in Citrix Studio
Configuring new VM with MCS via PowerShell offers the typical advantages of scripted solutions: Accuracy, standardizability and reproducibility. The resulting time savings are also not to be ignored.
However, in combination with ScriptRunner, even more opportunities open up: For example, the creation of new VMs can be fully automated and even delegated to helpdesk and end users. All processes remain secure, error-free and traceable.