Many of you may have seen my last blog on how to automate the creation of pooled catalogs that leverage Machine Creation Services. In XenDesktop 5 terminology, we automated the “Pooled-Random” catalog type. That type of catalog is very commonly used in POCs/Pilots where you own the hypervisor that you are leveraging and you want to automate the creation of the virtual desktops themselves in addition to the creation of the catalog. In this blog we are going to switch gears and talk about a different type of catalog – the physical catalog.

A physical catalog is a catalog that points to pre-existing desktops. These desktops could be physical devices (such as Blade PCs) or pre-existing VMs that have the Virtual Desktop Agent installed. If you create a “physical” catalog using the Desktop Studio Console (see screen shot below), it’s going to automatically put the catalog into a assigned on first use state. Catalogs that are assigned on first use are different than pooled catalogs. With assigned on first use, new users will get assigned to the next available desktop, and the desktop assignment will stick on subsequent launches of the desktop. With pooled desktops, users get assigned to the next available desktop and that assignment is cleared upon logoff. On the next logon, they will get assigned to the next available desktop again which could be a different device. In XenDesktop 5, to create a physical catalog that is pooled you need to create the catalog using the PowerShell SDK; the Desktop Studio Console doesn’t provide it as an option. In this blog, I’ll show you how to do this with the SDK!

This is the fourth blog in a series on how to use the XenDesktop 5 PowerShell SDK. In the first blog, I provided info on how to get started with the SDK, some approaches you can take for learning the cmdlets, some reference web pages that you can bookmark, and the tools you can use for creating your own scripts. If you haven’t read that article yet, please visit that blog first. For a complete list of topics that I will be covering in this series, see the bottom of this article.

Sample use case for using physical catalogs
Before I go into the PowerShell script, I want to provide some context for why I needed to look into physical catalogs to begin with. It’s actually an interesting scenario that you might be faced with as well. To sum up in word one – we encountered this scenario in the cloud!

The Citrix Virtual Computing Demo Center system that I manage provisions XenDesktop 5 demo environments on-demand in SoftLayer’s CloudLayer. With the CloudLayer, we order VMs from pre-built templates, specify what type of hardware they should be hosted on, and SoftLayer does the rest – they have internal processes for finding which XenServers will host the VMs based on availability. The CloudLayer is a multi-tenant infrastructure where each individual XenServer could be hosting VMs provisioned from the Demo Center and VMs provisioned from other customers. We do not have any visibility into the underlying XenServer itself such as it’s address or root password. Because we do not have native hypervisor access with VMs running in the CloudLayer, our XenDesktop 5 demo environments that run in the CloudLayer cannot define any hypervisor connections and hosts in the Desktop Studio console. To get around this issue, each XenDesktop demo environment that we provision contains a few virtual desktop VMs that are treated as physical devices by XenDesktop. When the DDC VM is ordered from template and brought online, it runs a PowerShell script (very similar to the one below) that dynamically creates a physical catalog containing the virtual desktop VMs that are part of that environment. Those virtual desktops are treated as unmanaged devices since it doesn’t have the hypervisor details to manage them. A diagram of the XenDesktop 5 demo environment that we provision in SoftLayer’s CloudLayer with the Demo Center is shown below. The XenDesktop 5 PowerShell SDK really is the glue that puts it all together, as we use the SDK to dynamically create the physical catalogs and desktop groups within XenDesktop so that everything is pre-configured and ready to be used before the first user hits it. (I’ll be covering the automation of the desktop groups in the next article.)

PowerShell Script Goals
The PowerShell script sample below creates a pooled physical catalog called “Windows 7 Catalog” that contains a few physical devices. To help you understand the script better, the details of this catalog are specified below. You will see these same values specified in the Global Variables section of the script.

Configuration Value
Catalog Name Windows 7 Catalog
Catalog Description Windows 7 Physical Catalog
Physical Devices to add to Catalog XENDESKTOP\Win7-1
XENDESKTOP\Win7-2
DDC Address ddc.xendesktop.cloud:80

PowerShell Script for Creating Pooled Physical Catalogs
The sample script below demonstrates how to create a pooled physical catalog.

#*****************************************************************************
#Write debug message to signify start of script
#*****************************************************************************
$objDateTime = Get-Date
Write-Host ""
Write-Host <span class="code-quote">"*****Script started at"</span> $objDateTime <span class="code-quote">"*****"</span>

#*****************************************************************************
#Add Citrix snapins to PowerShell session <span class="code-keyword">if</span> not already added
#*****************************************************************************
$snapins = Get-PSSnapin | where { $_.Name -like <span class="code-quote">"Citrix*"</span> }
<span class="code-keyword">if</span> (($snapins -eq $<span class="code-keyword">null</span>) -or ($snapins.Count -ne 8))
{
    Write-Host <span class="code-quote">"Loading the XenDesktop cmdlets into <span class="code-keyword">this</span> session..."</span>
    Get-PSSnapin -Registered <span class="code-quote">"Citrix*"</span> | Add-PSSnapin
    Add-PSSnapin <span class="code-quote">"PvsPsSnapin"</span>
}
<span class="code-keyword">else</span>
{
    Write-Host <span class="code-quote">"XenDesktop cmdlets are already loaded into <span class="code-keyword">this</span> session..."</span>
}

#*****************************************************************************
#Global variables <span class="code-keyword">for</span> entire script
#*****************************************************************************
$strCatalogName = <span class="code-quote">"Windows 7 Catalog"</span>                           #Name of the catalog that will be created
$strCatalogDescription = <span class="code-quote">"Windows 7 Physical Catalog"</span>           #Description given to the catalog
$arrDevices = <span class="code-quote">"XENDESKTOP\Win7-1"</span>, <span class="code-quote">"XENDESKTOP\Win7-2"</span>          #Array of physical devices to be added to the catalog
$strDDCAddress = <span class="code-quote">"DDC.xendesktop.cloud:80"</span>                      #DDC the cmdlets will connect to <span class="code-keyword">for</span> performing operations on the XenDesktop site

#*****************************************************************************
#Create pooled <span class="code-quote">"physical"</span> catalog
#*****************************************************************************

#Create the catalog
$objCatalog = New-BrokerCatalog -AllocationType 'Random' -CatalogKind 'Unmanaged' -Name $strCatalogName -Description $strCatalogDescription -AdminAddress $strDDCAddress
<span class="code-keyword">if</span> ($objCatalog -ne $<span class="code-keyword">null</span>)
{
    #Write debug message
    Write-Host <span class="code-quote">"Successfully created a catalog container called"</span> $objCatalog.Name <span class="code-quote">"..."</span>
}
<span class="code-keyword">else</span>
{
    #Write debug message
    Write-Host <span class="code-quote">"ERROR: Could not create a catalog container called"</span> $strCatalogName <span class="code-quote">"..."</span>
}

#Add physical devices to the catalog
foreach ($strDevice in $arrDevices)
{
    $objBrokerMachine = New-BrokerMachine -CatalogUid $objCatalog.Uid -MachineName $strDevice -AdminAddress $strDDCAddress
    <span class="code-keyword">if</span> ($objBrokerMachine -ne $<span class="code-keyword">null</span>)
    {
        #Write debug message
        Write-Host <span class="code-quote">"Successfully added"</span> $strDevice <span class="code-quote">"to the"</span> $objCatalog.Name <span class="code-quote">"catalog..."</span>
    }
    <span class="code-keyword">else</span>
    {
        #Write debug message
        Write-Host <span class="code-quote">"ERROR: Could not add"</span> $strDevice <span class="code-quote">"to the"</span> $objCatalog.Name <span class="code-quote">"catalog..."</span>
    }
}

#*****************************************************************************
#Write debug message to signify end of script
#*****************************************************************************
$objDateTime = Get-Date
Write-Host <span class="code-quote">"*****Script completed at"</span> $objDateTime <span class="code-quote">"*****"</span>
Write-Host ""

Note: The sample script above performs some basic error handling to help you keep track of the automation status. It outputs the success or failure of key sections of the script to the PowerShell window. The expected output is shown below. If you run into any issues, you can use a PowerShell editor such as PowerGui.exe to step through each line of the script.

After the script is executed, you can open the Desktop Studio console to verify the physical catalog is present within the Machines node.

Analyzing the PowerShell Script
For those of you that saw my last blog on creating pooled MCS-based catalogs, you can see that creating physical catalogs is much simpler!

The Global Variables section defines the configuration information for the catalog that I wanted to create. This is the information that you would have normally configured if you were to run through the wizard in Desktop Studio. You’ll want to change the values here to reference your own environment.

The remainder of the script leverages two cmdlets from the XenDesktop 5 SDK. The table below provides a summary of them:

Cmdlet Name Description
New-BrokerCatalog Creates a new catalog container within XenDesktop. I call this just a “container” since you still need to perform more actions on it for it to be valid, such as adding the desktops that it contains. Notice that the CatalogKind is “Unmanaged” to denote the physical catalog type and the AllocationType is “Random” to denote that devices should be pooled.
New-BrokerMachine Adds a desktop to the specified catalog.

Blogs in this series
I have several blogs planned for this series based on the recent projects that I’ve had. In the next blog I’ll discuss how to create desktop groups in XenDesktop 5 using PowerShell.

Ed York – Senior Architect – Worldwide Technical Readiness
Ask-the-Architect Site: http://community.citrix.com/p/product-automation#home
Follow Me on twitter: http://twitter.com/citrixedy