Let’s explore how to automate the XenDesktop 7 Hosting configuration. More specifically, I’m talking about how to write a PowerShell script that configures the items inside the Hosting node of Citrix Studio (Citrix Studio → Configuration → Hosting):

Citrix Studio Hosting Node - XenDesktop 7

Scripting the configuration of XenDesktop Hosting is comprised of setting up Host Connections and Hosting Infrastructures. Hosting is supported on Citrix XenServer, Microsoft System Center Virtual Machine Manager (SCVMM), or VMware vSphere. In this example, we will be covering XenServer and vSphere. For this we need to start off by adding the necessary PowerShell Snap-ins into the PowerShell session as follows:

Add-PSSnapin -Name "Citrix.Broker.Admin.V2","Citrix.Host.Admin.V2"

Host Connections

Because Citrix recommends using SSL for communication, the first thing to ensure is that the certificate used on the hosts is trusted by the delivery controllers. After ensuring this, we would need to build the correct URL string for the connection to the host, create the connection in the XDHyp PSDrive, and create the connection in the XenDesktop site. Here is an example PowerShell function that creates a Host Connection:

function New-HostConnection
{
    [CmdletBinding()]
    Param 
    (
        [Parameter(Mandatory=$true,ParameterSetName='vSphere')]
        [switch]$vSphere,
        [Parameter(Mandatory=$true,ParameterSetName='XenServer')]
        [switch]$XenServer,
        [Parameter(Mandatory=$true)]
        [string]$HostConnectionName,
        [Parameter(Mandatory=$true)]
        [string]$HostAddress,
        [Parameter(Mandatory=$true)]
        [string]$HostUserName,
        [Parameter(Mandatory=$true)]
        [string]$HostPassword,
        [Parameter(Mandatory=$false)]
        [switch]$NoSSL
    )

    # Determine type of hypervisor and build URL string
    if ($PSCmdlet.ParameterSetName -eq 'vSphere')
    {
        $hType = "VCenter"
        $HostAddress = "https://" + $HostAddress + "/sdk"
    }
    elseif ($PSCmdlet.ParameterSetName -eq 'XenServer')
    {
        $hType = "XenServer"
        $HostAddress = "https://" + $HostAddress
    }
    # Revert to http if SSL is not used
    if ($NoSSL)
    {
        $HostAddress = $HostAddress.Replace("https://","http://")
    }

    # Create connection in XDHyp PSDrive
    $hConn = $null
    $hConn = New-Item -Path XDHyp:\Connections `
                      -Name $HostConnectionName `
                      -HypervisorAddress $HostAddress `
                      -UserName $HostUserName `
                      -Password $HostPassword `
                      -ConnectionType $hType `
                      -Persist
    if ($hConn -ne $null)
    {
        # Create connection in XenDesktop site
        $bhc = $null
        $bhc = New-BrokerHypervisorConnection -HypHypervisorConnectionUid $hConn.HypervisorConnectionUid
        if ($bhc -ne $null)
        {
            # Return connection name for future use
            return $HostConnectionName
        }
        else
        {
            throw "New-HostConnection: Unable to create new host connection. `$bhc is null"
        }
    }
    else
    {
        throw "New-HostConnection: Unable to create new host connection. `$hConn is null"
    }
}

Hosting Infrastructures

After a host connection has been created, we can add hosting infrastructures that are accessed through that connection. For this we would build the necessary strings for the hosting unit resources and create the hosting unit in the XDHyp PSDrive. Here is an example PowerShell function that creates a Hosting Infrastructure:

function New-HostingInfrastructure
{
    [CmdletBinding()]
    Param
    (
        [Parameter(Mandatory=$true,ParameterSetName='vSphereCluster')]
        [Parameter(Mandatory=$true,ParameterSetName='vSphereComputeResource')]
        [switch]$vSphere,
        [Parameter(Mandatory=$true,ParameterSetName='XenServer')]
        [switch]$XenServer,
        [Parameter(Mandatory=$true)]
        [string]$HostingInfrastructureName,
        [Parameter(Mandatory=$true)]
        [string]$HostConnectionName,
        [Parameter(Mandatory=$true)]
        [string]$NetworkName,
        [Parameter(Mandatory=$true)]
        [string]$StorageName,
        [Parameter(Mandatory=$true,ParameterSetName='vSphereCluster')]
        [Parameter(Mandatory=$true,ParameterSetName='vSphereComputeResource')]
        [string]$DataCenterName,
        [Parameter(Mandatory=$true,ParameterSetName='vSphereCluster')]
        [string]$ClusterName,
        [Parameter(Mandatory=$true,ParameterSetName='vSphereComputeResource')]
        [string]$ComputeResourceName,       
        [Parameter(Mandatory=$false)]
        [string]$PvDStorageName=""
    )

    # Determine type of hypervisor and build the host specific suffix string
    if ($PSCmdlet.ParameterSetName -eq 'vSphereCluster')
    {
        $hostSpecificSuffix = "\$DataCenterName.datacenter\$ClusterName.cluster\"
    }
    elseif ($PSCmdlet.ParameterSetName -eq 'vSphereComputeResource')
    {
        $hostSpecificSuffix = "\$DataCenterName.datacenter\$ComputeResourceName.computeresource\"
    }
    elseif ($PSCmdlet.ParameterSetName -eq 'XenServer')
    {
        $hostSpecificSuffix = "\"
    }

    # Build string for hosting unit resources
    $hRootPath = "XDHyp:\Connections\"+$HostConnectionName+$hostSpecificSuffix   
    $networkPath = $hRootPath + $NetworkName + ".network"
    $storagePath = $hRootPath + $StorageName + ".storage"
    if ($PvDStorageName -ne "")
    {
        $pvdStoragePath = $hRootPath + $PvDStorageName + ".storage"
    }
    else
    {
        $pvdStoragePath = $hRootPath + $StorageName + ".storage"
    }

    # Create the hosting unit
    $hInf = $null
    $hInf = New-Item -Path XDHyp:\HostingUnits `
                     -Name $HostingInfrastructureName `
                     -HypervisorConnectionName $HostConnectionName `
                     -RootPath $hRootPath `
                     -NetworkPath $networkPath `
                     -StoragePath $storagePath `
                     -PersonalvDiskStoragePath $pvdStoragePath 

    if ($hInf -ne $null)
    {
        # Return hosting infrastructure name for future use
        return $HostingInfrastructureName
    }
    else
    {
        throw "New-HostingInfrastructure: Unable to create new hosting infrastructure. `$hInf is null"
    }
}

Note: Parameters like the datacenter name, cluster name, and compute resource name are case sensitive.

I hope you found this information useful and keep in mind that these methods can be reused to configure the XenDesktop 7 hosting as necessary for your environment.

Happy Scripting!

Santiago Cardenas

Citrix Solutions Lab