CITRIX and PowerShell are both prominent names when it comes to managing complex IT infrastructures. Not surprisingly, they complement each other perfectly to expand the scope of action of IT professionals.
For example, when managing Citrix Virtual Apps and Desktops, PowerShell allows certain features from Citrix Studio to be applied more accurately and to multiple targets simultaneously.
See the article for more examples of how PowerShell can save you time and effort in CVDA management.
There several reasons that you might want to consider using PowerShell for helping to manage your Citrix environment.
For me, I will have a PowerShell prompt open where I have the required Citrix cmdlets available (see later) where I can quickly see the state of the environment from a single command and when I’ve run it before, I can quickly find it in my persistent PowerShell history (via ctrl + r) so I don’t even have to remember what parameters to use or type anything further.
This can include looking for overloaded servers, disconnected sessions which haven’t reset (and reset them), servers unexpectedly in maintenance mode or unregistered, etc.
Another reason is automation. For instance, I had a customer problem whereby a specific event in the local event log on a CVAD server meant that the print spooler was in a state that couldn’t be recovered until a reboot and any application trying to print would hang.
As a short term mitigation, I wrote a script that ran regularly as a scheduled task to check for this event and if it had happened it would put the server into maintenance mode, to prevent new logons, and message the users that they might want to log off and back on, so they go to an unaffected server.
In subsequent runs of the script, it will check for users on servers suffering the problem and if there aren’t any, it will take it out of maintenance mode and reboot it.
The first decision is whether you need to manage on-premises or cloud infrastructure as they require different PowerShell modules which cannot co-exist on the same machine although thankfully most of the commands are the same between the two so once you know one, it is very easy to switch to use the other.
The required PowerShell cmdlets for on-prem are installed when Citrix Studio is installed but it is not recommended to run any management consoles or tools on Delivery Controllers since this consumes resources which are then unavailable for its primary role.
Therefore, the easiest way to install the required PowerShell cmdlets for on-prem is to install Citrix Studio from CVAD ISO on another machine such as a management server where all consoles are installed.
Alternatively, if you don’t want to install Studio, mount the CVAD ISO and run the following in an elevated PowerShell prompt from the X64Citrix Desktop Delivery Controller folder of the mounted ISO:
The web page also includes information on the additional authentication which is required. They must not be installed on a machine which has the on-prem PowerShell components installed.
It’s a good idea to match the version of the PowerShell cmdlets to the (minimum) version of CVAD that you have installed, just as you would for Studio.
The version of Windows PowerShell you use is up to you as anything between 2.0 and 5.1 will work although I’d recommend rolling out 5.1 as it gives the most cmdlets and thus capabilities.
In order to use the CVAD cmdlets, we need to load the PowerShell modules that they reside in except until recent releases, Citrix put these cmdlets into PowerShell snapins rather than modules which means we load them in a slightly different way.
To load all Citrix cmdlets from snapin we can run this:
However, this can take a considerable amount of time to complete because it loads every available cmdlet whereas you may only need a single snapin. For instance, if you are using Get-BrokerMachine and associated cmdlets to retrieve CVAD machines, you can run this instead, which is much quicker:
To find out what snapin a particular cmdlet is in, load all Citrix snapins as shown first in this section and then specify the cmdlet as an argument to Get-Command whereupon it will tell you the name of the snapin containing it that you can load instead.
With CVAD releases from 1912 LTSR onwards we can load cmdlets from modules instead via Import-Module (alias ipmo) instead of Add-PSSnapin (alias asnp) but the same applies as above in that we can load all Citrix modules by specifying “Citrix*” to Import-Module or just the specific modules required, again by loading all Citrix modules and then using Get-Command on the cmdlets we need to see what module(s) they exist in.
To make my scripts compatible on both newer and older CVAD releases, I generally use something like the code shown below which tries first to load the necessary Citrix module and if that fails it will try loading the equivalent snapin:
One we’ve installed and loaded the cmdlets we require, we are ready to go. The commands I mostly use to retrieve information start with Get-Broker, such as Get-BrokerMachine, GetBrokerDesktopGroup (for delivery groups), Get-BrokerCatalog and Get-BrokerSession. To see all Citrix cmdlets for retrieving information, you can run the following:
Which will work whether you are using snapins or modules. To see help for a specific command, run something like this:
You could also replace –ShowWindow with –Online to open a browser window with the help, assuming you have external internet access.
However, I rarely have to RTFM as the arguments passed to the cmdlets are generally the same and you can tab through them or hit ctrl + space after typing a minus/dash after the cmdlet name to list all possible arguments which you can move through with the cursor keys.
So let’s see what machines we have in CVAD by running Get-BrokerMachine (figure 1):
Fig. 1: PowerShell output from running Get-BrokerMachine
Well that didn’t go so well now, did it? If you ran this on a Delivery Controller, which is not recommended, it would actually work and list the machines.
However, I ran this on a VM satisfying the prerequisites but isn’t a Delivery Controller, so it doesn’t know which machine (Delivery Controller) to send the request to so it defaults to querying the localhost which fails as it is not a Delivery Controller (or Cloud Connector if you are using Citrix Cloud).
To tell the cmdlets which Delivery Controller to connect to, which means we can connect to different farms/instances from the same machine which is tricky with Studio, we use the -AdminAddress argument (see figure 2) thus:
Fig. 2: PowerShell output from running Get-BrokerMachine with the -AdminAddress argument
But that can give a very long listing which is difficult to comprehend, so we can either just grab the properties we are interested in, by looking through this long listing (see figure 3; you can also tab complete the properties passed to Select-Object (alias select)), or my preference is to pipe to Out-GridView which gives an onscreen grid view where you can further sort and filter the data (figure 4).
Fig. 3: You can display specific properties by passing the output from Get-BrokerMachine to Select-Object
Fig. 4: Piping the output from Get-BrokerMachine to Out-Gridview gives you a clear overview of the data
Ok, we know how to query most of what we can see in Studio with just a few Get-Broker* cmdlets but what if we want to change something? For instance, if we want to place some machines into maintenance mode, we can do it via their names, including a pattern, by piping in (filtered) results from Get-BrokerMachine or passing one or more machines previously returned from Get-BrokerMachine, stored in an array, to the -InputObject argument of Set-BrokerMachine.
Fig. 5: Configuration of machines in CVAD via PowerShell
Please make sure you know what you intend to achieve and what the script is actually going to do – you can see that it would be very easy for instance to put every machine into maintenance mode which may not be great news for your users at 0900 on a Monday morning.
When writing scripts that could perform undesirable actions, I typically use PowerShell’s built-in confirmation mechanism where I wrap the commands that change things in a $PSCmdlet.ShouldProcess block as per this article.
These scripts can still be run without user intervention by specifying -Confirm:$false.
Notice that once we’ve used -AdminAddress once in a session that we no longer need to specify it.
PowerShell in Citrix Studio
Hopefully there’s enough in this article to get you started with PowerShell in CVAD – there are plenty of script examples out there for all manner of tasks although always check these before running them in a production environment lest they accidentally, or deliberately, damage it. This is where an isolated test environment can be invaluable.
Occasionally it may not be obvious how to perform a particular task that you can do in Studio. If this happens, execute the action in Studio and then go to the PowerShell tab to see the PowerShell cmdlet used and the arguments used.
Fig. 6: The PowerShell tab in Citrix Studio shows the PowerShell cmdlet used for executing an action
In the above, we can ignore the -BearerToken and -LoggingId as they are not required. To get the UID for the catalog to add the machine to, we call Get-BrokerCatalog for the catalog we want:
Fig. 7: Simplified PowerShell command for retrieving the UID of a catalog
I hope this article has introduced you to some approaches and ideas that can help you to simplify your daily work with CVAD.
If you want to learn more about the interplay of CITRIX and PowerShell, you can look forward to the next article, which will focus on the use of PowerShell with CITRIX Machine Creation Services (MCS).
https://www.scriptrunner.com/wp-content/uploads/2020/11/windows-prozesse-powershell.png10001000Thomas Jooshttps://www.scriptrunner.com/wp-content/uploads/2018/05/ScriptRunner_Logo_RGB-300x45.pngThomas Joos2020-11-11 10:30:112021-01-07 16:43:43Display, retrieve, and terminate Windows processes with PowerShellScriptRunner Software GmbH
https://www.scriptrunner.com/wp-content/uploads/2020/11/19_Zeichenfläche-1.png10001000Vignesh Mudliarhttps://www.scriptrunner.com/wp-content/uploads/2018/05/ScriptRunner_Logo_RGB-300x45.pngVignesh Mudliar2020-11-04 10:00:092021-01-07 16:50:21Introduction to Pester – Part 1