Академический Документы
Профессиональный Документы
Культура Документы
Licensing Server
Infrastructure
Using NetScaler Global Server Load
Balancing (GSLB) and CtxLicChk.ps1
PowerShell Scripts
Written By
Dane Young (@youngtech)
Citrix Technology Professional
Revision 1.0
Acknowledgements
Brendan Lin, Citrix Consulting Services
Nicholas Rintalan, Citrix Consulting Services
Victor DiMascio, Entisys Solutions
Written
by
Dane
Young
Overview
In medium to large organizations, there are many business reasons why the Citrix Licensing server
(license server) component of a Citrix XenApp/XenDesktop infrastructure should be centralized. For
example, when seasonal bursts exist within departments or geographic regions, a central license
server offers manageability benefits as the segregated peaks become normalized across the various
groups consuming licenses. When license servers are segregated (departmentalized, regionalized, or
decentralized), peak usage can create additional Citrix Administrator operational overhead in
allocating, revoking, reallocating, and managing the license files installed in various license servers
and usage groups. License usage trending also becomes difficult in segregated environments as usage
data must be aggregated and reported across groups or disparate license servers. For these reasons
and others, organizations centralize the Citrix license server to avoid operational overhead, simplify
compliance and usage reporting.
When the license server is centralized, a fairly obvious single point of failure risk exists. Citrix Licensing
involves a grace period whereby clients/servers that lose communication with the license server are
protected, allowing the clients/servers to continue operations as if they were still in communication
with the license server. In practice, the grace period is a good feature, however there are instances
when Citrix Licensing may cause service interruptions to occur. An example is a scenario known as the
Citrix Licensing black hole, whereby the Citrix Licensing services and ports are up and responding to
licensing requests, however no licenses are available to be issued or obtained. This can occur if the
administrator fails to load license files properly, or in more rare instances that are difficult to reproduce
(Windows OS patches, antivirus definition updates or scans, etc.). For this reason, many organizations
define process and policy for semi-automatic/manual license server recovery including: Clustering the
licensing service, creating a cold standby with licenses preloaded, backing up license files, and
performing virtual machine snapshots of the license server. These and other options are valid (and less
complex), but offer a less resilient and robust option.
To help overcome this limitation and identify service interruptions before they occur, Citrix offers a
Citrix Licensing server monitoring tool called the Citrix License Check Utility (CtxLicChk.exe) that can
be obtained from the following support article: http://support.citrix.com/article/CTX123935. This utility
is intended to be used in conjunction with the Independent Management Architecture (IMA) based
Health Monitoring and Recovery feature available with Citrix Presentation Server 4.x, XenApp 5.x, and
XenApp 6.x. At the time of writing this guide, the Health Monitoring and Recovery feature is not yet
available in the FlexCast Management Architecture (FMA) based Citrix XenApp/XenDesktop 7.x
platform. However, using Microsoft Windows PowerShell, running this utility can be automated to
provide additional resiliency to a Citrix Licensing server infrastructure. Accompanying this guide is
CtxLicChk.ps1, a PowerShell script that can perform regular Citrix Licensing health checks using
CtxLicChk.exe, report license allocation failures using SMTP e-mail alerts, and stop the Citrix Licensing
service if license allocation fails.
When combined with Citrix NetScaler Load Balancing and Global Server Load Balancing (GSLB), a
bulletproof Citrix Licensing server infrastructure can be achieved. When the Citrix Licensing service is
stopped on the primary license server, NetScaler Load Balancing and GSLB can be used to fail over
licensing communication to a warm standby backup license server. In the examples herein, two Data
Centers (DC1 and DC2) are configured with local Citrix license servers, NetScaler Load Balancing, and
NetScaler Global Server Load Balancing provided from each Data Center. Under normal conditions only
the license server in Data Center 1 is active and primary. In the event of failures such as the primary
license server, NetScaler Load Balancing Virtual Server IP (VIP), or Data Center connectivity, Citrix
licensing traffic will be directed to the backup license server in Data Center 2.
Global Server Load Balancing is not a requirement if local resiliency within a single Data Center is
sufficient. The examples below show NetScaler configurations for both local Load Balancing as well as
GSLB. If GSLB is not a licensed feature or required for cross Data Center resiliency, local Load
Balancing can be configured using the samples below. In this case, the second set of NetScaler pair
configurations and GSLB specific sections can be dismissed.
Most importantly, if configured according to the examples provided in this guide, this bulletproof Citrix
Licensing server infrastructure complies with Citrixs product End User License Agreements (EULAs).
According to the EULAs, multiple Citrix Licensing servers may exist and have allocated licenses
installed, provided only one Citrix Licensing server is active and others are warm standby backup
2|Page
blog.itvce.com
Written
by
Dane
Young
license servers. Compliance to this requirement is fairly simple to validate in the event of a licensing
audit using the configuration provided in this guide.
3|Page
blog.itvce.com
Topology
The following is an example topology covered in more details throughout this guide.
4|Page
blog.itvce.com
Written
by
Dane
Young
Prerequisites
As shown in the above topology, the example environment consists of two Data Centers (DC1 and DC)
with Global Server Load Balancing between the two subnets (172.16.4.0/24 and 172.16.5.0/24). These
two Data Centers can represent West and East coast, North America and Europe, or any other
departmental or geographic separation where discrete failure domains would be desired.
Two sets of NetScaler High Availability (HA) pairs (one HA pair in each subnet) have been deployed.
The following have been configured on each NetScaler HA pair: NetScaler IPs, Subnet IPs, appropriate
NetScaler licenses to enable Global Server Load Balancing functionality.
Two Windows Server 2012 R2 virtual machines (one in each subnet) were deployed using CTXLIC as
the NetBIOS/DNS name (case sensitive). Since these machines require the same NetBIOS/DNS name
for Citrix Licensing to load the license file, these license servers should not be domain joined as they
cannot share the same Active Directory computer object. Citrix Licensing server components have
been installed and a license file has been loaded to the MyFiles folder using the process described in
the Importing License Files section of product documentation.
Note: If the license severs must be domain joined to adhere to organization policy, the servers can be
joined to different subdomains under the top level forest. The example environment uses domain.com
for the top level forest and domain. To domain join multiple Citrix license servers, the following could
exist under the same top level forest: CTXLIC.dc1.domain.com and CTXLIC.dc2.domain.com. It is not a
recommended configuration to create subdomains strictly for this purpose unless other reasons or
benefits exist for organizational subdomains.
Two XenApp/XenDesktop 7.x Delivery Controllers have been installed (one in each subnet) to represent
resources in each Data Center. Multiple XenApp/XenDesktop resources (Windows Client and Server OS)
were deployed in each site, with the Virtual Desktop Agent installed and configured.
Summary of Prerequisites:
The following represents a summary of the prerequisites:
Two Data Centers (DC1 and DC2) with disparate subnets and routing between (172.16.4.0/24 &
172.16.5.0/24).
Two sets of NetScaler HA Pairs (one HA pair in each subnet).
NetScaler IP addresses (NSIP), Subnet IPs (SNIP), and licenses configured for each pair.
Two License servers deployed (one in each subnet) using identical NetBIOS/DNS name (CTXLIC).
o License servers are not to be domain joined.
o Citrix licensing server components have been installed on each with the license file loaded.
Citrix XenApp/XenDesktop Delivery Controller components installed on at least two servers (one in
each subnet).
o Citrix Licensing is required when the site is configured. Ideally this should be done after
GSLB licensing has been configured according to the procedures in this guide. Otherwise,
reconfiguring a Citrix XenApp/XenDesktop Site to the GSLB DNS address is acceptable and
documented in this guide if the XenApp/XenDesktop site and licensing was already
configured.
Citrix XenApp/XenDesktop resources installed and configured (Windows Client or Server OS) with
the VDA installed and configured.
5|Page
blog.itvce.com
Written
by
Dane
Young
6|Page
blog.itvce.com
Written
by
Dane
Young
7|Page
blog.itvce.com
Written
by
Dane
Young
5)
6)
Optionally, the following can be run from an elevated command prompt (restart the server once
completed):
reg add HKLM\System\CurrentControlSet\Services\LanmanServer\Parameters /v
DisableStrictNameChecking /t REG_DWORD /d 1
8|Page
blog.itvce.com
Written
by
Dane
Young
9|Page
blog.itvce.com
Written
by
Dane
Young
10 | P a g e
blog.itvce.com
11 | P a g e
blog.itvce.com
$ctxlicchk = "$PSScriptRoot$ctxlicchkpath"
# Create a string variable with all IP addresses for reporting
$ipaddresses = Get-NetIPAddress | format-table | out-string
# If SMTP is enabled, setup the SMTP Client using the Global parameters
if ($EnableSMTP -eq $true){$Global:SMTPClient = New-Object Net.Mail.SmtpClient($SmtpServer, 587);$Global:SMTPClient.EnableSsl = $true;$Global:SMTPClient.Credentials = New-Object
System.Net.NetworkCredential($SMTPUsername, $SMTPPassword)}
# If SMTP is enabled, fire off the first e-mail notification at script startup
if ($EnableSMTP -eq $true){$SMTPClient.Send($EmailFrom, $EmailTo, "Starting CtxLicChk Script with the following global vairables:","ctxlicchkpath:" + $ctxlicchkpath + "`nctxlicsrv:" +
$ctxlicsrv + "`nctxlictype:" + $ctxlictype + "`nctxlicchkfreq:" + $ctxlicchkfreq + "`n" + $ipaddresses)}
# Create a CtxLicChk.log file in the same directory for logging. Flush the log and add an entry at script startup
write-output ("Starting CtxLicChk Script with the following global vairables: ctxlicchkpath:" + $ctxlicchkpath + "; ctxlicsrv:" + $ctxlicsrv + "; ctxlictype:" + $ctxlictype + ";
ctxlicchkfreq:" + $ctxlicchkfreq + "`n" + $ipaddresses) | Out-File "$PSScriptRoot\CtxLicChk.log"
# Create an infinite loop
$infiniteloop = $true
do {
# Run the CtxLicChk.exe using the ctxlicsrv and ctxlictype parameters and log the output to a new variable ctxlicchkoutput
$ctxlicchkoutput = & $ctxlicchk $ctxlicsrv $ctxlictype
# Perform logic to see if the ctxlicchk passed or failed
if ($ctxlicchkoutput -like "*License checkout test failed!*"){
# Write an entry to the CtxLicChk.log and e-mail using SMTPClient if the test failed
write-output (get-date)$ctxlicchkoutput | Out-File "$PSScriptRoot\CtxLicChk.log" -append
if ($EnableSMTP -eq $true){$SMTPClient.Send($EmailFrom, $EmailTo, "License Check Failed! Stopping Citrix Licensing Service:" + $ctxlicchkoutput + ".", $ipaddresses)}
# If the test failed, log to CtxLicChk.log that the service is being stopped and stop the Citrix Licensing service (TCP 27000 port down state)
write-output (get-date)"License Check Failed! Stopping Citrix Licensing Service" | Out-File "$PSScriptRoot\CtxLicChk.log" -append
Stop-Service -displayname "Citrix Licensing" | Out-File "$PSScriptRoot\CtxLicChk.log" -append
} else {
# If the ctxlicchk test didn't fail, log the output to the CtxLicChk.log file
write-output (get-date)$ctxlicchkoutput | Out-File "$PSScriptRoot\CtxLicChk.log" -append
}
# As part of the infinite loop, log to the CtxLogChk.log that the script is sleeping for xx minutes and go to sleep for duration specified in ctxlicchkfreq global variable
write-output (get-date)"Sleeping for $ctxlicchkfreq Minutes" | Out-File "$PSScriptRoot\CtxLicChk.log" -append
start-sleep -s ($ctxlicchkfreq * 60) # Sleep for CtxLicChk Frequency converted to seconds
} while ($infiniteLoop -eq $true)
#---------------------------------------------------------------------------------------------------------------------------------------------------------------------#---------------------------------------------------------------------------------------------------------------------------------------------------------------------# Created by Dane Young (@youngtech), CTP, itvce.com Copyright 2015
# Check http://blog.itvce.com/?p=5748 for updates and for NetScaler Load Balancing / Global Server Load Balancing configuration examples
# Build 2015.02.08 Revision 1
#---------------------------------------------------------------------------------------------------------------------------------------------------------------------#---------------------------------------------------------------------------------------------------------------------------------------------------------------------# THIS POWERSHELL SCRIPT AND ANY RELATED INFORMATION ARE PROVIDED "AS IS" WITHOUT
# WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE. We
# grant You a nonexclusive, royalty-free right to use and modify the PowerShell Script
# and to reproduce and distribute the object code form of the PowerShell Script,
# provided that You agree: (i) to not use this script in part or in whole for
# profitable gain; (ii) to not change parts of this script including owner information
# and copyright statements without crediting the author; (iii) to not market Your
12 | P a g e
blog.itvce.com
13 | P a g e
blog.itvce.com
Written
by
Dane
Young
CtxLicChk
or local
Be sure to select
Run whether user is logged on or not
2.
3.
14 | P a g e
blog.itvce.com
5.
Written
by
Dane
Young
15 | P a g e
blog.itvce.com
Written
by
Dane
Young
Text to Replace
mon_ctxlicdc1
gslb_site_dc2
172.16.4.15
Replace With
(Optional to replace)
mon_ctxlicdc2
(Optional to replace)
svc_ctxlicdc1
(Optional to replace)
svc_ctxlicdc2
(Optional to replace)
lb_ctxlicdc1
(Optional to replace)
lb_ctxlicdc2
(Optional to replace)
mon_gslb_ctxlicdc1
(Optional to replace)
mon_gslb_ctxlicdc2
(Optional to replace)
svc_gslb_ctxlicdc1
(Optional to replace)
svc_gslb_ctxlicdc2
(Optional to replace)
lb_ctxlicdc1_vip
(Optional to replace)
lb_ctxlicdc2_vip
(Optional to replace)
gslb_site_dc1
(Optional to replace)
172.16.5.15
172.16.4.14
(Optional to replace)
0.0.0.0
(Replace with real IP)
0.0.0.0
(Replace with real IP)
0.0.0.0
(Replace with real IP)
172.16.5.14
0.0.0.0
(Replace with real IP)
172.16.4.13
0.0.0.0
(Replace with real IP)
16 | P a g e
blog.itvce.com
Written
by
Dane
Young
172.16.5.13
0.0.0.0
(Replace with real IP)
ctxlic.gslb.domain.com
0.0.0.0
(Replace with real IP)
mon_ctxlicdc1_27000
mon_ctxlicdc1_7279
mon_ctxlicdc1_8082
mon_ctxlicdc1_8083
17 | P a g e
blog.itvce.com
Written
by
Dane
Young
mon_ctxlicdc2_27000
mon_ctxlicdc2_7279
mon_ctxlicdc2_8082
mon_ctxlicdc2_8083
mon_ctxlicdc1_27000
mon_ctxlicdc1_7279
mon_ctxlicdc1_8082
mon_ctxlicdc1_8083
blog.itvce.com
Written
by
Dane
Young
mon_ctxlicdc2_27000
mon_ctxlicdc2_7279
mon_ctxlicdc2_8082
mon_ctxlicdc2_8083
19 | P a g e
blog.itvce.com
Written
by
Dane
Young
ROUNDROBIN
-tolerance
-EDR
ENABLED
svc_gslb_ctxlicdc1_27000
svc_gslb_ctxlicdc1_7279
svc_gslb_ctxlicdc1_8082
svc_gslb_ctxlicdc1_8083
20 | P a g e
blog.itvce.com
vserver
lb_ctxlicdc2_vip
TCP
-backupLBMethod
Written
ROUNDROBIN
by
-tolerance
Dane
0
Young
-appflowLog
svc_gslb_ctxlicdc2_27000
svc_gslb_ctxlicdc2_7279
svc_gslb_ctxlicdc2_8082
svc_gslb_ctxlicdc2_8083
21 | P a g e
blog.itvce.com
Written
by
Dane
Young
172.16.4.13
172.16.5.13
Configure using the information in the configuration details table for NetScaler Subnet IP (to be used
for ADNS Binding and GSLB Site IP).
1.
2.
3.
4.
5.
6.
To create a delegation, right-click the domain and select New Delegation from the shortcut menu.
Click Next in the Delegated Domain Name wizard.
Type the sub-domain to delegate, such as gslb.
Click Next.
Click Add.
Type the NetScaler ADNS Service IP in the FQDN and IP Address fields.
22 | P a g e
blog.itvce.com
7.
8.
Written
by
Dane
Young
Click OK.
Repeat Step 5 to Step 7 of this procedure to add each additional NetScaler ADNS Service IP:
9. Click Next.
10. Click Finish.
11. After completing the preceding procedure, the queries sent to the sub-domain to the DNS server
either cause a recursive lookup to the NetScaler appliances or are responded to with the NetScaler
records that have been configured. To verify this, query the DNS server directly for the NetScaler
appliance record of the sub-domain, as shown in the following screen shot:
23 | P a g e
blog.itvce.com
Written
by
Dane
Young
4.
5.
Click OK
24 | P a g e
blog.itvce.com
Written
by
Dane
Young
25 | P a g e
blog.itvce.com
Written By
Dane Young (@youngtech)
Citrix Technology Professional
Revision 1.0
Acknowledgements
Brendan Lin, Citrix Consulting Services
Nicholas Rintalan, Citrix Consulting Services
Victor DiMascio, Entisys Solutions
THIS CONFIGURATION GUIDE AND ANY RELATED INFORMATION ARE PROVIDED "AS IS" WITHOUT
WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE. We grant
You a nonexclusive, royalty-free right to use and modify the configuration guide and to reproduce and
distribute the object code form of the included script, provided that You agree: (i) to not use this
configuration guide or included script in part or in whole for profitable gain; (ii) to not change parts of
this configuration guide or included script including owner information and copyright statements
without crediting the author; (iii) to not market Your software product in which this configuration guide
or included script is embedded; (iv) to include a valid copyright and disclaimer notice wherever this
configuration guide or included script is embedded; and (v) to indemnify, hold harmless, and defend Us
and Our suppliers from and against any claims or lawsuits, including attorneys fees, that arise or
result from the use or distribution of this configuration guide or included script. This posting is provided
"AS IS" with no warranties, and confers no rights. Use of included script samples are subject to the
terms specified at http://blog.itvce.com/?page_id=4934.