Why automate XenDesktop 7 Site Creation?

XenDesktop 7 is out for a while now and after doing some PoC implementations I recently got into the situation of having to install and setup a XenDesktop 7 site with separate databases which is our best practice for production environments.

As you might know with XenDesktop 7, in addition to the site configuration database two more data stores are created which are initially contained within the site database when doing a manual configuration via Citrix Studio:

Configuration logging database – captures site configuration changes and administrative activities
Monitoring database – captures historical performance data for analysis via Citrix Director

Of course it is easily possible to change the databases after the site has been created via Citrix Studio but that still involves some manual intervention afterwards and we do not want this, do we ? Moreover it would be nice to cover more configuration steps automatically.

There are already quite some good information and code snippets out there in the internet covering different parts of an unattended XenDesktop 7 site creation including the database creation. So I thought It would be worthwhile combining the PowerShell stuff out there and building a script for a complete automated installation of a XenDesktop 7 site including license server and role configuration.

As when it comes to automating workflows Citrix provides an excellent Powershell SDK for XenDesktop. Beginning with XenDesktop 7 it is now also possible for the first time to create the databases via PowerShell which we will need for a complete script-based setup. The commands for that are contained in a separate PowerShell module called Citrix.XenDesktop.Admin. The “standard” commands for configuration and administration are accessible via the standard XenDesktop PowerShell snap-ins. Details concerning the snap-ins can be found here:  http://support.citrix.com/proddocs/topic/xendesktop-7/cds-sdk-cmdlet-help.html

PowerShell Scripting for Site Creation and Configuration

So here we go. Though the script has been tested you should verify the code in a test environment first before using it for a productive environment. It is intended to be run on the first delivery controller after base installation.

First we have to import the Citrix.XenDesktop.Admin module and add the standard Citrix PowerShell snap-ins:

<span class="code-keyword">Import-Module</span> Citrix.XenDesktop.Admin
<span class="code-keyword">Add-PSSnapin</span> Citrix.*

Next we define the parameters that will have to be adapted for each environment, including the database server, database names, site name, security group for full administration and license server details. Possible values for the LicenseServer_LicensingModel variable are UserDevice and Concurrent. LicenseServer_ProductEdition can be any of STD, ENT or PLT. For using XenApp Licenses for XenDesktop 7 App Edition set the LicenseServer_ProductCode to MPS.

$DatabaseServer = <span class="code-quote">"dbserver.domain.com"</span> 
$DatabaseName_Site = <span class="code-quote">"XD7-DB_Site"</span>
$DatabaseName_Logging = <span class="code-quote">"XD7-DB_Logging"</span> 
$DatabaseName_Monitor = <span class="code-quote">"XD7-DB_Monitor"</span>
$XD7Site = <span class="code-quote">"XD7Site"</span>
$FullAdminGroup = <span class="code-quote">"Domain\FullAdminGroup"</span>
$LicenseServer = <span class="code-quote">"licenseserver.domain.com"</span> 
$LicenseServer_LicensingModel = <span class="code-quote">"UserDevice"</span> 
$LicenseServer_ProductCode = <span class="code-quote">"XDT"</span> 
$LicenseServer_ProductEdition = <span class="code-quote">"PLT"</span>

For creating the databases we will need a user with at least dbcreator and securityadmin permissions on the database server. In order to enable the script to be executed in a customer environment without exposing passwords (which you should never do in a script) we leverage a PSCredential object that stores the password as a SecureString:

$DatabaseUser = <span class="code-keyword">Read-Host</span> "Please enter user for database connection (Domain\Username)" 
$DatabasePassword = <span class="code-keyword">Read-Host</span> "Please enter password for user $DatabaseUser" -AsSecureString 
$Database_CredObject = <span class="code-keyword">New-Object System.Management.Automation.PSCredential</span>($DatabaseUser,$DatabasePassword)

Now that all parameters are set we can create distinct Site, Configuration Logging and Monitoring databases via the New-XDDatabase command which creates the databases and the schema for XenDesktop on the database server. Note the parameter -DataStore for the defining the schema to be created:

<span class="code-keyword">New-XDDatabase</span> -AdminAddress $env:COMPUTERNAME -SiteName $XD7Site -DataStore Site -DatabaseServer $DatabaseServer -DatabaseName $DatabaseName_Site -DatabaseCredentials $Database_CredObject
<span class="code-keyword">New-XDDatabase</span> -AdminAddress $env:COMPUTERNAME -SiteName $XD7Site -DataStore Logging -DatabaseServer $DatabaseServer -DatabaseName $DatabaseName_Logging -DatabaseCredentials $Database_CredObject
<span class="code-keyword">New-XDDatabase</span> -AdminAddress $env:COMPUTERNAME -SiteName $XD7Site -DataStore Monitor -DatabaseServer $DatabaseServer -DatabaseName $DatabaseName_Monitor -DatabaseCredentials $Database_CredObject

Now we are ready to create and setup the site with our newly created databases:

<span class="code-keyword">New-XDSite</span> -DatabaseServer $DatabaseServer -LoggingDatabaseName $DatabaseName_Logging -MonitorDatabaseName $DatabaseName_Monitor -SiteDatabaseName $DatabaseName_Site -SiteName $XD7Site -AdminAddress $env:COMPUTERNAME

So we have the databases and the site created, but we still need to configure licensing. One important step here is to store the License server SSL certificate hash inside the XenDesktop database to enable trusted communication with the license service.

<span class="code-keyword">Set-XDLicensing</span> -AdminAddress $env:COMPUTERNAME -LicenseServerAddress $LicenseServer -LicenseServerPort 27000
<span class="code-keyword">Set-ConfigSite</span>  -AdminAddress $env:COMPUTERNAME -LicensingModel $LicenseServer_LicensingModel -ProductCode $LicenseServer_ProductCode -ProductEdition $LicenseServer_ProductEdition
<span class="code-keyword">Set-ConfigSiteMetadata</span> -AdminAddress $env:COMPUTERNAME -Name 'CertificateHash' -Value $(Get-LicCertificate -AdminAddress "https://$LicenseServer").CertHash

Nearly done for the base setup, we only have to define an Active Directory group that will be configured with the Full Administrator role for the site:

<span class="code-keyword">New-AdminAdministrator</span> -AdminAddress $env:COMPUTERNAME -Name $FullAdminGroup
<span class="code-keyword">Add-AdminRight</span> -AdminAddress $env:COMPUTERNAME -Administrator $FullAdminGroup -Role 'Full Administrator' -All

So by leveraging a scripted approach for site and initial database creation you can save some time, avoid manual database reconfiguration for logging and monitoring and fully automate installations. Have fun !

Here you can view the whole script:

###########################################
#
# Create XenDesktop Site with 3 separate databases
#
###########################################

Import-Module Citrix.XenDesktop.Admin
Add-PSSnapin Citrix.*

# Parameters ###############################

$DatabaseServer = "dbserver.domain.com"
$DatabaseName_Site = "XD7-DB_Site"
$DatabaseName_Logging = "XD7-DB_Logging"
$DatabaseName_Monitor = "XD7-DB_Monitor"
  
$XD7Site = "XD7Site"

$FullAdminGroup = "Domain\FullAdminGroup"

$LicenseServer = "licenseserver.domain.com"

$LicenseServer_LicensingModel = "UserDevice"
$LicenseServer_ProductCode = "XDT"
$LicenseServer_ProductEdition = "PLT"

############################################

$DatabaseUser = Read-Host "Please enter user for database connection (Domain\Username)"
$DatabasePassword = Read-Host "Please enter password for user $DatabaseUser" -AsSecureString

$Database_CredObject = New-Object System.Management.Automation.PSCredential($DatabaseUser,$DatabasePassword)

# Create Databases

New-XDDatabase -AdminAddress $env:COMPUTERNAME -SiteName $XD7Site -DataStore Site -DatabaseServer $DatabaseServer -DatabaseName $DatabaseName_Site -DatabaseCredentials $Database_CredObject 
New-XDDatabase -AdminAddress $env:COMPUTERNAME -SiteName $XD7Site -DataStore Logging -DatabaseServer $DatabaseServer -DatabaseName $DatabaseName_Logging -DatabaseCredentials $Database_CredObject 
New-XDDatabase -AdminAddress $env:COMPUTERNAME -SiteName $XD7Site -DataStore Monitor -DatabaseServer $DatabaseServer -DatabaseName $DatabaseName_Monitor -DatabaseCredentials $Database_CredObject 
  
# Create Site

New-XDSite -DatabaseServer $DatabaseServer -LoggingDatabaseName $DatabaseName_Logging -MonitorDatabaseName $DatabaseName_Monitor -SiteDatabaseName $DatabaseName_Site -SiteName $XD7Site -AdminAddress $env:COMPUTERNAME 

# ConfigureLicensing and confirm the certificate hash

Set-XDLicensing -AdminAddress $env:COMPUTERNAME -LicenseServerAddress $LicenseServer -LicenseServerPort 27000
Set-ConfigSite  -AdminAddress $env:COMPUTERNAME -LicensingModel $LicenseServer_LicensingModel -ProductCode $LicenseServer_ProductCode -ProductEdition $LicenseServer_ProductEdition 
Set-ConfigSiteMetadata -AdminAddress $env:COMPUTERNAME -Name 'CertificateHash' -Value $(Get-LicCertificate -AdminAddress "https://$LicenseServer").CertHash

# Add admin group to full admins

New-AdminAdministrator -AdminAddress $env:COMPUTERNAME -Name $FullAdminGroup
Add-AdminRight -AdminAddress $env:COMPUTERNAME -Administrator $FullAdminGroup -Role 'Full Administrator' -All

Thomas Fuhrmann
Principal Consultant
Citrix Consulting Central Europe

And to satisfy the legal guys:

Disclaimer Notice

This software / sample code is provided to you “AS IS” with no representations, warranties or conditions of any kind. You may use, modify and distribute it at your own risk. CITRIX DISCLAIMS ALL WARRANTIES WHATSOEVER, EXPRESS, IMPLIED, WRITTEN, ORAL OR STATUTORY, INCLUDING WITHOUT LIMITATION WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NONINFRINGEMENT. Without limiting the generality of the foregoing, you acknowledge and agree that (a) the software / sample code may exhibit errors, design flaws or other problems, possibly resulting in loss of data or damage to property; (b) it may not be possible to make the software / sample code fully functional; and (c) Citrix may, without notice or liability to you, cease to make available the current version and/or any future versions of the software / sample code. In no event should the software / code be used to support of ultra-hazardous activities, including but not limited to life support or blasting activities. NEITHER CITRIX NOR ITS AFFILIATES OR AGENTS WILL BE LIABLE, UNDER BREACH OF CONTRACT OR ANY OTHER THEORY OF LIABILITY, FOR ANY DAMAGES WHATSOEVER ARISING FROM USE OF THE software / SAMPLE CODE, INCLUDING WITHOUT LIMITATION DIRECT, SPECIAL, INCIDENTAL, PUNITIVE, CONSEQUENTIAL OR OTHER DAMAGES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. Although the copyright in the software / code belongs to Citrix, any distribution of the code should include only your own standard copyright attribution, and not that of Citrix. You agree to indemnify and defend Citrix against any and all claims arising from your use, modification or distribution of the code.