Featured post

Automation | Powershell scripts

Automation | Powershell scripts Xenapp 6.5 Health check script XenAppServerHealthCheck Report through Script  ## XenAppServerHealthCheck ## ...

Friday, 18 February 2022

Automation | Powershell scripts

Automation | Powershell scripts

Xenapp 6.5 Health check script

XenAppServerHealthCheck Report through Script 




## XenAppServerHealthCheck

## The script checks the health of a XenApp 6.x farm and e-mails two reports. The full farm

## health report is attached to the e-mail and any errors encountered are in an html report

## embedded in the email body.

## This script checks the following:

##   - Ping response

##   - Logon enabled

##   - Assigned Load Evaluator

##   - Active sessions

##   - ICA port response 

##   - CGP port response (session reliability)

##   - WMI response (to check for WMI corruption)

##   - Citrix IMA, Citrix XML, Citrix Print Manager and Spooler services

##   - Server uptime (to ensure scheduled reboots are occurring)

##   - Server folder path and worker group memberships are report for informational purposes

##   - PVS vDisk and write cache file size

## 

## Change history:

##   2.7 - Fixed bug with Check Services 

##   2.6 - Added support for unique load evaluators and PVS vDisks per server silo (based on 

##         server folder path). This functionality is in the $allSiloInfo hash table data 

##         structure.

##   2.5 - Added support for Cache in device RAM overflow to disk PVS option, now queries running 

##         services once for each server speeding up the script.

##   2.4 - Changed default Load Evaluator to handle multiple values; updated Ping routine to be 

##         more robust.

## 

## TO DO

##   - Rewrite for XA/XD 7.x!!

##   - Add unique user count

##   - Move per environment variable data to an XML file

##   - PVS server health check

##   - Incorporate Medvac??

## 

## You are free to use this script in your environment but please e-mail me any improvements.

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

if ((Get-PSSnapin "Citrix.XenApp.Commands" -EA silentlycontinue) -eq $null) {

try { Add-PSSnapin Citrix.XenApp.Commands -ErrorAction Stop }

catch { write-error "Error loading XenApp Powershell snapin"; Return }

}

 

# Change the below variables to suit your environment

#==============================================================================================

# Default load evaluator assigned to servers. Can have multiple values in format "LE1", "LE2",

# if a match is made to ANY of the listed LEs SUCCESS is returned for the LE check.

$defaultLE       = "Servers"


# Default PVS vDisk assigned to servers

$defaultVDisk    = "XA6_Desktop_1"


# Relative path to the PVS vDisk write cache file

$PvsWriteCache   = "d$\.vdiskcache"

$PvsWriteCache2  = "d$\vdiskdif.vhdx"


# Maximum size of the local PVS write cache file

$PvsWriteMaxSize = 8gb # size in GB


# Servers in the excluded folders will not be included in the health check

$excludedFolders = @("Servers/Test","Servers/Turned Off")

 

# We always schedule reboots on XenApp farms, usually on a weekly basis. Set the maxUpTimeDays

# variable to the maximum number of days a XenApp server should be up for.

$maxUpTimeDays = 7


# E-mail report details

$emailFrom     = "XenAppFarmReport@acme.co.nz"

$emailTo       = "citrix.admins@acme.co.nz"

$smtpServer    = "mail.acme.co.nz"

$emailSubject  = ("XenApp Farm Report - " + (Get-Date -format R))


# Silo info

$allSiloInfo = @{}

$siloInfo    = @{}

# Uncomment the below to enable silo support

# Copy the below four line as many time as required - once for each silo to be supported.

#$siloInfo.name  = "Servers/Production"

#$siloInfo.LE    = "Productions Servers"

#$siloInfo.vDisk = "XA6_Desktop_1"

#$allSiloInfo.($siloInfo.name) = $siloInfo


# Only change this if you have changed the Session Reliability port from the default of 2598

$sessionReliabilityPort = "2598"


#==============================================================================================

 

$currentDir = Split-Path $MyInvocation.MyCommand.Path

$logfile    = Join-Path $currentDir ("XenAppServerHealthCheck.log")

$resultsHTM = Join-Path $currentDir ("XenAppServerHealthCheckResults.htm")

$errorsHTM  = Join-Path $currentDir ("XenAppServerHealthCheckErrors.htm")

 

$headerNames  = "FolderPath", "WorkerGroups", "ActiveSessions", "ServerLoad", "Ping", "Logons", "LoadEvaluator", "ICAPort", "CGPPort", "IMA", "CitrixPrint", "WMI", "XML", "Spooler", "Uptime", "WriteCacheSize", "vDisk"

$headerWidths = "6",          "6",            "4",              "4",          "4",    "6",      "6",             "4",       "6",                  "4",   "4",           "4",   "4",   "4",       "5",      "4",              "4"


#==============================================================================================

function LogMe() {

Param(

[parameter(Mandatory = $true, ValueFromPipeline = $true)] $logEntry,

[switch]$display,

[switch]$error,

[switch]$warning,

[switch]$progress

)



if ($error) {

$logEntry = "[ERROR] $logEntry" ; Write-Host "$logEntry" -Foregroundcolor Red}

elseif ($warning) {

Write-Warning "$logEntry" ; $logEntry = "[WARNING] $logEntry"}

elseif ($progress) {

Write-Host "$logEntry" -Foregroundcolor Green}

elseif ($display) {

Write-Host "$logEntry" }

 

#$logEntry = ((Get-Date -uformat "%D %T") + " - " + $logEntry)

$logEntry | Out-File $logFile -Append

}



#==============================================================================================

function Ping([string]$hostname, [int]$timeout = 1000, [int]$retries = 3) {

$result = $true

$ping = new-object System.Net.NetworkInformation.Ping #creates a ping object

$i = 0

do {

$i++

#write-host "Count: $i - Retries:$retries"

try {

#write-host "ping"

$result = $ping.send($hostname, $timeout).Status.ToString()

} catch {

#Write-Host "error"

continue

}

if ($result -eq "success") { return $true }

} until ($i -eq $retries)

return $false

}



#==============================================================================================

Function writeHtmlHeader

{

param($title, $fileName)

$date = ( Get-Date -format R)

$head = @"

<html>

<head>

<meta http-equiv='Content-Type' content='text/html; charset=iso-8859-1'>

<title>$title</title>

<STYLE TYPE="text/css">

<!--

td {

font-family: Tahoma;

font-size: 11px;

border-top: 1px solid #999999;

border-right: 1px solid #999999;

border-bottom: 1px solid #999999;

border-left: 1px solid #999999;

padding-top: 0px;

padding-right: 0px;

padding-bottom: 0px;

padding-left: 0px;

overflow: hidden;

}

body {

margin-left: 5px;

margin-top: 5px;

margin-right: 0px;

margin-bottom: 10px;

table {

table-layout:fixed; 

border: thin solid #000000;

}

-->

</style>

</head>

<body>

<table width='1200'>

<tr bgcolor='#CCCCCC'>

<td colspan='7' height='48' align='center' valign="middle">

<font face='tahoma' color='#003399' size='4'>

<!--<img src="http://servername/administration/icons/xenapp.png" height='42'/>-->

<strong>$title - $date</strong></font>

</td>

</tr>

</table>

<table width='1200'>

<tr bgcolor='#CCCCCC'>

<td width=50% height='48' align='center' valign="middle">

<font face='tahoma' color='#003399' size='4'>

<!--<img src="http://servername/administration/icons/active.png" height='32'/>-->

Active Sessions:  $TotalActiveSessions</font>

<td width=50% height='48' align='center' valign="middle">

<font face='tahoma' color='#003399' size='4'>

<!--<img src="http://servername/administration/icons/disconnected.png" height='32'/>-->

Disconnected Sessions:  $TotalDisconnectedSessions</font>

</td>

</tr>

</table>

"@

$head | Out-File $fileName

}


# ==============================================================================================

Function writeTableHeader

{

param($fileName)

$tableHeader = @"

<table width='1200'><tbody>

<tr bgcolor=#CCCCCC>

<td width='6%' align='center'><strong>ServerName</strong></td>

"@


$i = 0

while ($i -lt $headerNames.count) {

$headerName = $headerNames[$i]

$headerWidth = $headerWidths[$i]

$tableHeader += "<td width='" + $headerWidth + "%' align='center'><strong>$headerName</strong></td>"

$i++

}


$tableHeader += "</tr>"


$tableHeader | Out-File $fileName -append

}


# ==============================================================================================

Function writeData

{

param($data, $fileName)

$data.Keys | sort | foreach {

$tableEntry += "<tr>"

$computerName = $_

$tableEntry += ("<td bgcolor='#CCCCCC' align=center><font color='#003399'>$computerName</font></td>")

#$data.$_.Keys | foreach {

$headerNames | foreach {

#"$computerName : $_" | LogMe -display

try {

if ($data.$computerName.$_[0] -eq "SUCCESS") { $bgcolor = "#387C44"; $fontColor = "#FFFFFF" }

elseif ($data.$computerName.$_[0] -eq "WARNING") { $bgcolor = "#FF7700"; $fontColor = "#FFFFFF" }

elseif ($data.$computerName.$_[0] -eq "ERROR") { $bgcolor = "#FF0000"; $fontColor = "#FFFFFF" }

else { $bgcolor = "#CCCCCC"; $fontColor = "#003399" }

$testResult = $data.$computerName.$_[1]

}

catch {

$bgcolor = "#CCCCCC"; $fontColor = "#003399"

$testResult = ""

}

$tableEntry += ("<td bgcolor='" + $bgcolor + "' align=center><font color='" + $fontColor + "'>$testResult</font></td>")

}

$tableEntry += "</tr>"

}

$tableEntry | Out-File $fileName -append

}


 

# ==============================================================================================

Function writeHtmlFooter

{

param($fileName)

@"

</table>

<table width='1200'>

<tr bgcolor='#CCCCCC'>

<td colspan='7' height='25' align='left'>

<font face='courier' color='#003399' size='2'><strong>Default Load Evaluator  = $DefaultLE</strong></font>

<tr bgcolor='#CCCCCC'>

<td colspan='7' height='25' align='left'>

<font face='courier' color='#003399' size='2'><strong>Default VDISK Image         = $DefaultVDISK</strong></font>

</td>

</tr>

</table>

</body>

</html>

"@ | Out-File $FileName -append

}


Function Check-Port  

{

param ([string]$hostname, [string]$port)

try {

#$socket = new-object System.Net.Sockets.TcpClient($ip, $_.IcaPortNumber) #creates a socket connection to see if the port is open

$socket = new-object System.Net.Sockets.TcpClient($hostname, $Port) #creates a socket connection to see if the port is open

} catch {

$socket = $null

"Socket connection failed" | LogMe -display -error

return $false

}


if($socket -ne $null) {

"Socket Connection Successful" | LogMe

if ($port -eq "1494") {

$stream   = $socket.GetStream() #gets the output of the response

$buffer   = new-object System.Byte[] 1024

$encoding = new-object System.Text.AsciiEncoding


Start-Sleep -Milliseconds 500 #records data for half a second

while($stream.DataAvailable)

{

$read     = $stream.Read($buffer, 0, 1024)  

$response = $encoding.GetString($buffer, 0, $read)

#Write-Host "Response: " + $response

if($response -like '*ICA*'){

"ICA protocol responded" | LogMe

return $true

}

"ICA did not response correctly" | LogMe -display -error

return $false

} else {

return $true

}

   

} else { "Socket connection failed" | LogMe -display -error; return $false }

}


# ==============================================================================================

# ==                                       MAIN SCRIPT                                        ==

# ==============================================================================================

"Checking server health..." | LogMe -display


rm $logfile -force -EA SilentlyContinue


# Data structure overview:

# Individual tests added to the tests hash table with the test name as the key and a two item array as the value.

# The array is called a testResult array where the first array item is the Status and the second array

# item is the Result. Valid values for the Status are: SUCCESS, WARNING, ERROR and $NULL.

# Each server that is tested is added to the allResults hash table with the computer name as the key and

# the tests hash table as the value.

# The following example retrieves the Logons status for server NZCTX01:

# $allResults.NZCTX01.Logons[0]


$allResults = @{}


# Get session list once to use throughout the script

$sessions = Get-XASession

 

Get-XAServer | % {


$tests = @{}

$server = $_.ServerName

# Check to see if the server is in an excluded folder path

$folderPath = $_.FolderPath 

#$excludedFolders | ? { $_ -like $folderPath } | { $server + " in excluded folder - skipping" | LogMe; return }

if ($excludedFolders -contains $_.FolderPath) { $server + " in excluded folder - skipping" | LogMe; return }

$server | LogMe -display -progress

    

    if ($allSiloInfo.$folderPath) {

        # Silo specific info is available

        if (($allSiloInfo.$folderPath).LE)    { $serverLE    = ($allSiloInfo.$folderPath).LE }

        if (($allSiloInfo.$folderPath).vDisk) { $serverVDisk = ($allSiloInfo.$folderPath).vDisk }

    } else {

        $serverLE    = $defaultLE

        $serverVDisk = $defaultVDisk

    }

$tests.FolderPath   = $null, $_.FolderPath

$tests.WorkerGroups = $null, (Get-XAWorkerGroup -ServerName $server | % {$_.WorkerGroupName})

if ($_.CitrixVersion -ge 6.5) { $minXA65 = $true }

else { $minXA65 = $false }


# Check server logons

if($_.LogOnsEnabled -eq $false){

"Logons are disabled on this server" | LogMe -display -warning

$tests.Logons = "WARNING", "Disabled"

} else {

$tests.Logons = "SUCCESS","Enabled"

}

# Report on active server sessions

$activeServerSessions = [array]($sessions | ? {$_.State -eq "Active" -and $_.Protocol -eq "Ica" -and $_.ServerName -match $server})

if ($activeServerSessions) { $totalActiveServerSessions = $activeServerSessions.count }

# the  following line will return unique users rather than active sessions

#if ($activeServerSessions) { $totalActiveServerSessions = ($activeServerSessions | Group-Object -property AccountName).count }

else { $totalActiveServerSessions = 0 }

$tests.ActiveSessions = $null, $totalActiveServerSessions

# Check Load Evaluator

$assignedLE = (Get-XALoadEvaluator -ServerName $_.ServerName).LoadEvaluatorName

if ($serverLE -notcontains $assignedLE) {

"Non-default Load Evaluator assigned" | LogMe -display -warning

$tests.LoadEvaluator = "WARNING", $assignedLE

} else {

$tests.LoadEvaluator = "SUCCESS", $assignedLE

}


# Ping server 

$result = Ping $server 100

if ($result -ne "SUCCESS") { $tests.Ping = "ERROR", $result }

else { $tests.Ping = "SUCCESS", $result 

# Test ICA connectivity

if (Check-Port $server $_.IcaPortNumber) { $tests.ICAPort = "SUCCESS", "Success" }

else { $tests.ICAPort = "ERROR","No response" }

# Test Session Reliability port

if (Check-Port $server $sessionReliabilityPort) { $tests.CGPPort = "SUCCESS", "Success" }

else { $tests.CGPPort = "ERROR", "No response" }

# Check services

$services = Get-Service -Computer $Server

if (($services | ? {$_.Name -eq "IMAService"}).Status -Match "Running") {

"IMA service running..." | LogMe

$tests.IMA = "SUCCESS", "Success"

} else {

"IMA service stopped"  | LogMe -display -error

$tests.IMA = "ERROR", "Error"

}

if (($services | ? {$_.Name -eq "Spooler"}).Status -Match "Running") {

"SPOOLER service running..." | LogMe

$tests.Spooler = "SUCCESS","Success"

} else {

"SPOOLER service stopped"  | LogMe -display -error

$tests.Spooler = "ERROR","Error"

}

if (($services | ? {$_.Name -eq "cpsvc"}).Status -Match "Running") {

"Citrix Print Manager service running..." | LogMe

$tests.CitrixPrint = "SUCCESS","Success"

} else {

"Citrix Print Manager service stopped"  | LogMe -display -error

$tests.CitrixPrint = "ERROR","Error"

}

if (($minXA65 -and $_.ElectionPreference -ne "WorkerMode") -or (!($minXA65))) {

if (($services | ? {$_.Name -eq "ctxhttp"}).Status -Match "Running") {

"XML service running..." | LogMe

$tests.XML = "SUCCESS","Success"

} else {

"XML service stopped"  | LogMe -display -error

$tests.XML = "ERROR","Error"

}   

} else { $tests.XML = "SUCCESS","N/A" }

# If the IMA service is running, check the server load

if ($tests.IMA[0] -eq "Success") {

try {

$CurrentServerLoad = Get-XAServerLoad -ServerName $server

#$CurrentServerLoad.GetType().Name|LogMe -display -warning

if( [int] $CurrentServerLoad.load -lt 7500) {

  "Serverload is low" | LogMe

  $tests.Serverload = "SUCCESS", ($CurrentServerload.load)

}

elseif([int] $CurrentServerLoad.load -lt 9000) {

"Serverload is Medium" | LogMe -display -warning

$tests.Serverload = "WARNING", ($CurrentServerload.load)

}   

else {

"Serverload is High" | LogMe -display -error

$tests.Serverload = "ERROR", ($CurrentServerload.load)

}   

}

catch {

"Error determining Serverload" | LogMe -display -error

$tests.Serverload = "ERROR", ($CurrentServerload.load)

}

$CurrentServerLoad = 0

}



# Test WMI

$tests.WMI = "ERROR","Error"

try { $wmi=Get-WmiObject -class Win32_OperatingSystem -computer $_.ServerName } 

catch { $wmi = $null }


# Perform WMI related checks

if ($wmi -ne $null) {

$tests.WMI = "SUCCESS", "Success"

$LBTime=$wmi.ConvertToDateTime($wmi.Lastbootuptime)

[TimeSpan]$uptime=New-TimeSpan $LBTime $(get-date)


if ($uptime.days -gt $maxUpTimeDays){

"Server reboot warning, last reboot: {0:D}" -f $LBTime | LogMe -display -warning

$tests.Uptime = "WARNING", $uptime.days

} else {

$tests.Uptime = "SUCCESS", $uptime.days

}

} else { "WMI connection failed - check WMI for corruption" | LogMe -display -error }


################ PVS SECTION ###############

if (test-path \\$Server\c$\Personality.ini) {

$PvsWriteCacheUNC = Join-Path "\\$Server" $PvsWriteCache 

$CacheDiskexists  = Test-Path $PvsWriteCacheUNC


if ($CacheDiskexists -eq $False) {

$PvsWriteCacheUNC = Join-Path "\\$Server" $PvsWriteCache2

$CacheDiskexists  = Test-Path $PvsWriteCacheUNC

}



if ($CacheDiskexists -eq $True)

{

$CacheDisk = [long] ((get-childitem $PvsWriteCacheUNC -force).length)

$CacheDiskGB = "{0:n2}GB" -f($CacheDisk / 1GB)

"PVS Cache file size: {0:n2}GB" -f($CacheDisk / 1GB) | LogMe

#"PVS Cache max size: {0:n2}GB" -f($PvsWriteMaxSize / 1GB) | LogMe -display

if($CacheDisk -lt ($PvsWriteMaxSize * 0.5))

{

   "WriteCache file size is low" | LogMe

   $tests.WriteCacheSize = "SUCCESS", $CacheDiskGB

}

elseif($CacheDisk -lt ($PvsWriteMaxSize * 0.8))

{

   "WriteCache file size moderate" | LogMe -display -warning

   $tests.WriteCacheSize = "WARNING", $CacheDiskGB

}   

else

{

   "WriteCache file size is high" | LogMe -display -error

   $tests.WriteCacheSize = "ERORR", $CacheDiskGB

}

}              

   

$Cachedisk = 0

   

$VDISKImage = get-content \\$Server\c$\Personality.ini | Select-String "Diskname" | Out-String | % { $_.substring(12)}

if($VDISKImage -Match $serverVDisk){

"Default vDisk detected" | LogMe

$tests.vDisk = "SUCCESS", $VDISKImage

} else {

"vDisk unknown"  | LogMe -display -error

$tests.vDisk = "WARNING", $VDISKImage

}   

}

else { $tests.WriteCacheSize = "SUCCESS", "N/A";  $tests.vDisk = "SUCCESS", "N/A" }

############## END PVS SECTION #############

}


$allResults.$server = $tests

}


# Get farm session info

$ActiveSessions       = [array]($sessions | ? {$_.State -eq "Active" -and $_.Protocol -eq "Ica"})

$DisconnectedSessions = [array]($sessions | ? {$_.State -eq "Disconnected" -and $_.Protocol -eq "Ica"})


if ($ActiveSessions) { $TotalActiveSessions = $ActiveSessions.count }

# the  following line will return unique users rather than active sessions

# if ($activeSessions) { $totalActiveSessions = ($activeSessions | Group-Object -property AccountName).count }

else { $TotalActiveSessions = 0 }


if ($DisconnectedSessions) { $TotalDisconnectedSessions = $DisconnectedSessions.count }

else { $TotalDisconnectedSessions = 0 }


"Total Active Sessions: $TotalActiveSessions" | LogMe -display

"Total Disconnected Sessions: $TotalDisconnectedSessions" | LogMe -display


# Write all results to an html file

Write-Host ("Saving results to html report: " + $resultsHTM)

writeHtmlHeader "XenApp Farm Report" $resultsHTM

writeTableHeader $resultsHTM

$allResults | sort-object -property FolderPath | % { writeData $allResults $resultsHTM }

writeHtmlFooter $resultsHTM


# Write only the errors to an html file

#$allErrors = $allResults | where-object { $_.Ping -ne "success" -or $_.Logons -ne "enabled" -or $_.LoadEvaluator -ne "default" -or $_.ICAPort -ne "success" -or $_.IMA -ne "success" -or $_.XML -ne "success" -or $_.WMI -ne "success" -or $_.Uptime -Like "NOT OK*" }

#$allResults | % { $_.Ping -ne "success" -or $_.Logons -ne "enabled" -or $_.LoadEvaluator -ne "default" -or $_.ICAPort -ne "success" -or $_.IMA -ne "success" -or $_.XML -ne "success" -or $_.WMI -ne "success" -or $_.Uptime -Like "NOT OK*" }

#Write-Host ("Saving errors to html report: " + $errorsHTM)

#writeHtmlHeader "XenApp Farm Report Errors" $errorsHTM

#writeTableHeader $errorsHTM

#$allErrors | sort-object -property FolderPath | % { writeData $allErrors $errorsHTM }

#writeHtmlFooter $errorsHTM


($mailMessageParameters = @{

From       = $emailFrom

To         = $emailTo

Subject    = $emailSubject

SmtpServer = $smtpServer

Body       = (gc $resultsHTM) | Out-String

Attachment = $resultsHTM

}


Send-MailMessage @mailMessageParameters -BodyAsHtml)


$mailMessageParameters = @{


from = “abc@co.com”

to = “xyz@coi.com”
Subject = “XenApp6 Health Check Report”
body = get-content “C:\Temp\XenApp 6.x\XenAppServerHealthCheckResults.htm” | Out-String
attachments = “C:\Temp\XenApp 6.x\XenAppServerHealthCheckResults.htm”
smtpserver = “10.0.0.1”
}
Send-MailMessage @mailMessageParameters -BodyAsHtml



Thursday, 1 July 2021

Vmware -ESxi -How to remove ESXi v5.5 License via ESXi command line

 

How to remove ESXi v5.5 License via ESXi command line –

1.      Disconnect the ESXi Host from the VCenter management console.

 

2.      Remove the ESXi Host from the inventory.

 

3.      Check for the existing license by logging to the ESXi Host via vSphere client.



    Login to the ESXi Host via putty.

    Locate the License files in /etc/vmware directory – vmware.lic & license.cfg.

   Delete the license files using command – rm -rf file_name



1.    Reboot the ESXi Host.

Post reboot, ESXi Host will enter Evaluation mode as shown below -






Tuesday, 16 March 2021

How to Configure SSL on XenDesktop and Xenapp Controller to Secure XML Traffic

 

Objective

This article describes how to enable SSL on XenDesktop 5 controllers to secure XML traffic from Web Interface or Access Gateway, and how to configure Web Interface site to secure the XML traffic.
Note: For Access Gateway communication, this secures the Secure Ticket Authority (STA) ticket that uses the XML service as well.

For XenDesktop 7.x, refer to CTX218986 - Secure XML traffic between StoreFront and Delivery Controller 7.x

Requirements

  • XenDesktop 5
  • Web Interface 5.x

Note: For this article, XenDesktop 5 Service Pack 1 was used along with Web Interface 5.4.


Instructions

From XenDesktop Controller

IIS Installed on XenDesktop Controller

In this scenario, the XenDesktop controller has IIS installed and functioning to serve Web Interface or other web services. To complete this setup, you must request a Server Certificate and install it on IIS.

There are two ways to generate Server Certificates on IIS 7.x:

  • Create Certificate Request: This generates a CSR file to be submitted to a third party Certification Authority (CA) or to your internal Microsoft CA. For more information, refer to Microsoft TechNet article – Request an Internet Server Certificate (IIS 7)

  • Create Domain Certificate: This generates a CSR file and submits it to your domain registered Microsoft CA server. For more information, refer to the Microsoft TechNet article – Create a Domain Server Certificate on IIS 7.

    User-added image

After the Server Certificate is installed on IIS, ensure to set the Bindings to enable HTTPS on IIS by completing the following procedure:

  1. Select the IIS site that you want to enable HTTPS and select Bindings under Edit Site.

    User-added image

  1. Click Add, select Type as https, port number as 443, select the SSL Certificate that you installed and click OK.

    User-added image

  1. Open Registry Editor on XenDesktop Controller and look for the following key name.
    HKEY_LOCAL_MACHINE\SOFTWARE\Citrix\DesktopServer.

    Caution! Refer to the Disclaimer at the end of this article before using Registry Editor.

  1. Verify that XmlServicesSslPort registry key exists with the correct value for SSL port. By default, it is set to 443.

    User-added image

  1. Change the XML service port.
    You can do this using PowerShell by running the following command:
    BrokerService –WiSslPort <port number>
    Note
    : If you decide to change the XML service port number on XenDesktop Controller, ensure to update the IIS port number as well under Bindings to match the new value.

IIS is not Installed on XenDesktop Controller

In this scenario, the XenDesktop Controller does not have IIS installed. As a result, there are a few ways to obtain a Server Certificate for the Controller:

  • Export an existing Server Certificate from another server in PFX format. When exporting the Server Certificate, ensure to select the private key as well.

  • You can use the Certreq utility from Microsoft to generate a Certificate Signing Request and submit it to a third party CA or your internal Microsoft CA server. For more information, refer to the Microsoft TechNet article – Certreq.exe Syntax.
    Note: Ensure to always import the PFX server certificates under the XenDesktop controller Local Computer certificate store and not My user account.

    User-added image

After the Server Certificate is installed on XenDesktop Controller, register the SSL certificate for HTTPS on the server. To accomplish this, Windows 2008 has a built-in utility called netsh that allows you to bind SSL certificates to a port configuration. For more information, refer to the Microsoft MSDN article – How to: Configure a Port with an SSL Certificate

The following is the command that you must use:
netsh http add sslcert ipport=0.0.0.0:<port Number> certhash=<hash number> appid={XenDesktop Broker Service GUID}
To obtain the certificate hash of a Server Certificate, open the Registry Editor, and open the following key name location and search for the Server Certificate that you want to use:
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\SystemCertificates\MY\Certificates

User-added image

An alternative to obtain this certificate hash
  1. Open the Server Certificate and under the Details tab, select Thumprint:

    User-added image

  1. Obtain the GUID of the XenDesktop controller Citrix Broker Service.

  2. Open Registry Editor and select Find.

  3. Search for Broker Service words. By default, the location is in HKEY_CLASSES_ROOT\Installer\Products\ (see the following example):

    User-added image

  1. Now that you have the certificate hash and Citrix Broker Service GUID, you can run the netsh command to bind the SSL certificate to port 443 and Citrix Broker Service. The following example is based on the GUID and certificate hash values taken from the preceding screenshots:

    Here is command to get the GUID 

    Run the below command in Elevated command prompt on the DDC

    wmic product where "Name like 'Citrix Broker Service'" get Name,identifyingnumber
    IdentifyingNumber

    ​C:\ >netsh http add sslcert ipport=10.12.37.231:443 certhash=298B8AB50322A5A601A57D4976875191D85A2949 appid={13C9D851-5D94-7C44-4A2B-218F89A28DC7}
    Note
    : For GUID, ensure to include dashes (-). Otherwise, the command cannot run successfully.

Note:

certhash : Thumbprint of Certificate

Command to find appid : wmic product where "Name like 'Citrix Broker Service'" get Name,identifyingnumber



A successful bind looks as displayed in the following screen shot:

User-added image

From the Web Interface server

Configure the XenApp Web Site or XenApp Services Site to use HTTPS and 443 as Transport Type and XML Service port respectively under Server Farms.

User-added image

Note: To have a successful SSL connection to the XenDesktop 5 Controller, ensure that Web Interface has installed the Trusted Root certificate (under Local Computer certificate store).

Monday, 15 March 2021

There are no apps or desktops available to you at this time

         There are no apps or desktops available to you at this time


Successfully logging onto Citrix StoreFront displays the message: "There are no apps or desktops available to you at this time."

Problem

Users have complained that they no longer see published apps and desktops after successfully logging onto Citrix as they only see the message:

There are no apps or desktops available to you at this time.

image

Reviewing the Citrix Delivery Services event logs on the Citrix StoreFront server displays the following errors:

None of the Citrix XML Services configured for farm Controller are in the list of active services, so none were contacted.

Log Name: Citrix Delivery Services
Source: Citrix Store Service
Event ID: 4012
Level: Error

image

Failed to launch the resource 'Controller.GP' as it was not found.

Log Name: Citrix Delivery Services
Source: Citrix Store Service
Event ID: 28
Level: Warning

image

None of the Citrix XML Services configured for farm Controller are in the list of active services, so none were contacted.

Log Name: Citrix Delivery Services
Source: Citrix Store Service
Event ID: 4012
Level: Error

image

Solution

The most important entry in the event logs written for this issue could easily be missed because the entry that provides the cause of the issue is actually labeled as Information. Continuing to move to earlier logs will reveal the following entry indicating that the SSL certificate on the Delivery Controller has expired:

The Citrix XML Service at address svr-ctxdc-02.ccs.int:443 has failed the background health check and has been temporarily removed from the list of active services. Failure details: An SSL connection could not be established: The server sent an expired security certificate. The certificate *.ccs.int, *.ccs.int is valid from 10/29/2018 9:37:20 AM until 10/28/2020 9:37:20 AM.. This message was reported from the Citrix XML Service at address https://svr-ctxdc-02.ccs.int/scripts/wpnbr.dll[UnknownRequest].

image

You would not be able to see this entry if you are reviewing the logs in the Administrative Events, which does not display Information entries.

image

To correct the issue, simply issue a new SSL certificate to replace the expired certificate on the Delivery Controller (or controllers if there are more than one), then update the bindings in IIS Manager:

imageimage

Successfully updating the SSL certificate will re-establish communication between the StoreFront server and the Delivery Controller(s).


Friday, 25 September 2020

How I Upgraded Citrix virtual apps 7.15 to 1912

 This is a guide on how I upgraded my site from 7.15 flat, all the way up to 1912. I also included moving off 2012R2 to 2016 DDCs with some troubleshooting situations you might run into. I covered the basics of upgrading licensing, DDC upgrades, Storefront upgrades with NS VIP configuration, PVS upgrades, WEM upgrades, VDA upgrades, and some re-configuration of Snap-ins with Citrix Director for ADM and session recording.


References for detailed instructions:

https://docs.citrix.com/en-us/citrix-virtual-apps-desktops/upgrade-migrate/upgrade.html
https://www.carlstalhood.com/delivery-controller-1912-ltsr-and-licensing/#licensingupgrade












Upgrade the licensing Server
:
Go download the version you need. In this case, it’s 11.16.3.0, Build 29000.



Run the CTX_licensing installer.


Check the box to agree.













After upgrading Citrix Licensing Server, in Citrix Studio, go to Configuration and Licensing.

On the right, click Authenticate Certificate.






Open Citrix licensing Manager.




I was prompted to register my licensing server with Citrix Cloud.

Licensing Manager might prompt you to register with Citrix Cloud.




On the Settings > Usage and Statistics page, in the "Share usage statistics with Citrix" section, click Register.




You’ll see a screen with a registration code. Click the Copy button and then click Register to be taken to Citrix Cloud.





After logging in to Citrix Cloud, on the top left, click the menu (hamburger) icon and then click License & Usage. If you don’t see this link, you might have to log out and log back in.




In the License & Usage service, switch to the Registrations tab.




Click the blue Register button in the middle of the page to register.





Paste in the copied code and then click Continue. Click Register.





In the On-premises Licensing Manager, it will eventually show as Registered.

On the same Usage & Statistics page, scroll down, and then click Upload now. This should cause data to upload to Citrix Cloud and show up in Citrix Cloud License & Usage.

Citrix.cloud.com reporting:










*Note* I always check and make sure it shows as activated within Studio and is set to the right product edition.

Upgrade VDA to 1912.

I also upgrade my VDAs ahead of time. It’s easy, and something I just do. Depending on your provision side, PVS, MCS, or old fashion servers (which is still used).

Mount ISO and upgrade.















Upgrade Delivery Controllers 7.15.5000.

Snapshot your Delivery controller.

Backup your SQL databases.

Attach the 7.15 CU5 media.

Run the Studio and Server Components for the upgrade.




Read and Accept.




Read and make sure you take the correct actions you need in your environment.




Start your Preliminary Test and make sure you are good!






Firewall Ports:



Summary:





Upgraded process started.















Connect to Call home if you need to.



Launch Studio.













**NOTE** If you already have two controllers, in Load Balancing, reactivate the servers with the new Delivery Controller version and set the second half of the servers to Down. Follow the top steps on the second half of the Delivery Controller Server. Activate each server with the new Delivery Controller Server version in Load Balancing again.

I am adding a 2016 server to move off 2012R2. I will add the Second 2016 server in, then make sure 2016 is handling the connections. Then Decom 2012R2 and add a new second (replacement of 2012R2 as 2016 server.

Attach the 7.15.5000 ISO, click on XenDesktop or XenApp (depending on your deployment).

XenDesktop allows for both XenApp and XenDesktop. XenApp is only XenApp.



Select Delivery Controller.



Read and Understand, accept.



We only want: Delivery Controller, Studio, and Director.




I don’t want SQL express in the step – uncheck it.




Review and make sure the firewall is configured based on your environment.




Installs:



This will take about 5-7 minutes.



Select Call Home options:



Finish, reboot, and then launch Studio.




After Studio is opened, select “Connect this Delivery Controller to an existing site.”




Add the primary DDC.



It will ask to update the DB automatically. I select "yes" and will put in my SQL creds.







Studio will open and show the Site.



Run a Site check to make sure it’s good.




This will take 10 minutes.



Looks good.



At this point, I have the following:

2012R2 715.5000 Deliver Controller

2016 7.15.5000 Delivery Controller.

Both are upgraded from 7.15 to 7.15.500.



Now we will begin the 7.15.500 upgrade to 1912 LTSR.

Snapshot your Delivery controller.

Backup your SQL databases.

Attach the 1912 media.

Run the Studio and Server Components for the upgrade.




Read and accept.





Make sure the following has been completed to ensure an upgrade will go smooth:




Licensing Error I received when I clicked "next." Even though I upgraded my licensing version to 11.16.3.0 build 29000, I had to update my licensing files past November 2019. I logged into my Citrix Licensing manager, https://yourCTXlicServer.FQDN:8083, then selected "check for available renewals." Follow the prompts to get an updated timestamp.




Before:



After:



Being as this is not production; my specs are lower than what it wants. However, I will meet the minimum to ensure the upgrade is solid.




Server specifications: https://docs.citrix.com/en-us/citrix-virtual-apps-desktops/system-requirements.html





Let's pick back up where I left off. Preliminary Site Test (Run this to ensure no errors exist).






Test in progress.






Two tests will not run, as they don’t apply.






Results: go through and test all the orchestrations of the environment.





Firewall ports.





Summary, then click upgrade.







Upgrade progress:





Upgraded, but Reboot needed.






After Reboot it will resume. Now on Post Install….




Connect to Citrix Cloud for Diagnostics data if needed in your environment.




Finish and now open Studio.




Now upgrade the Database through Studio (my service account has permissions).




It will ask you again about backing up the DB.




Add the credentials, unless you are logged into the server as the account (account needs proper permissions, in Citrix, and on the servers).




It’s now started.




 Going, 9 successful… GOOOD so far.




Still going well.




Finished.




You now need to do the second Delivery controller we added early in the process. It’s the 2016 server.




Remote to the Server, attach the Media, and I double-click on the mounted ISO from my hypervisor.




Click "Upgrade" on Studio and Server components.




Read and Agree.



Ensure the following is completed, although it’s a second DDC.




Firewall for DDC and Director:




Summary:




Warning pop up about not being able to stop it once it starts.




Upgrading has started (the time says 13 minutes). Sometimes it’s accurate, or not accurate.




The machine needs to be rebooted to apply some .Net settings/updates.








Rebooted, and now it’s still applying them.



Log back in, and it will resume back to the place it was at. Be patient!






Connect to Citrix Cloud for Diagnostics data if needed in your environment.






Now launch Studio.




Start the automatic site upgrade.




Being this has already ran, it shouldn’t take long.




Studio is now launched.




Lets do a site Test on the Delivery controller.




Things passed, and look good.



Let’s do a Machine Catalog and Delivery group test. (Failed)?!! Looks like my Delivery controllers don’t have the updated vCenter cert. Let me fix this. I simulated a failure to show the value of running the tests.

I fixed my cert by following this: https://support.citrix.com/article/CTX138640




Once both have updated 1912 software, go into the first Delivery Controller and finish the “upgrade remaining delivery Controllers.”




Once all the Delivery Controllers and VDAs are upgraded, within Citrix Studio, view your Catalog for the current functional level. (Set to VDA version you have in the catalogs.) Citrix Virtual Apps and Desktops (CVAD) 1912 lets you upgrade your Catalogs and Delivery Groups to functional level 1811 if needed.

**WARNING****

Don’t upgrade the Catalog or Delivery Group until all VDAs with the Catalog and Delivery Group are VDA version 1811 or newer.






Then upgrade the Delivery Groups by right-clicking on a Delivery Group and clicking Upgrade Delivery Group.






This concludes the upgrade for the Delivery controller.

Now let’s Decom one Delivery controller, which is 2012R2.

*Note*

https://discussions.citrix.com/topic/388816-decommission-delivery-controller/

https://docs.citrix.com/en-us/citrix-virtual-apps-desktops/manage-deployment/delivery-controllers.html

Active connections should not be dropped if you remove a delivery controller from the site. Remove the controllers from Storefront first, then from Citrix studio. Any VDAs registered to the controller should re-register with the remaining controllers, however, this may take a few minutes, so a resource that hasn’t registered yet might be unavailable for a relatively short time.

You could also stop the Broker service on the redundant controllers, which would also cause any registered VDAs to de-register.

Whilst doing this during business hours should be OK, there’s always a risk that for some reason a VDA doesn’t register with the remaining controllers, so unless you can’t avoid it, doing it out of hours, or during low use phases is always preferable.

Remove the controllers from Storefront first.




Then from studio.

Make sure the Controller is powered on so that Studio loads in less than one hour. Once Studio loads the Controller you want to remove, power off the Controller when prompted to do so.

Select Configuration > Controllers in the Studio navigation pane and then select the Controller you want to remove.




Select Remove Controller in the Actions pane. If you do not have the correct database roles and permissions, you are offered the option of generating a script that allows your database administrator to remove the Controller for you.










This errored out. So, I did it and selected "No" here.




Then it asked to generate a DB script, for the Database guys.






This still didn’t remove it. So, at this time I found the CTX link: 

https://support.citrix.com/article/CTX139505

https://www.jgspiers.com/remove-orphaned-delivery-controller-xenapp-xendesktop-site/

Run “Get-BrokerController”:




Then run this POSH Script.




It will put an Evict.txt file in either your profile %userprofile% or C:\windows\system32. Give this file to your DBA, then run it on the database.




Check Studio and it's gone.




Any VDAs registered to the controller should re-register with the remaining controllers.

Adding a second 2016 Delivery controller now to slit the broker balancing out.

Install Virtual Apps and Desktops.




Select Delivery Controller.




Read and accept.




Select the components you need.




Install the Feature you need (NO Local SQL for me).




Firewall ports:




Summary:




Extracting Files.




The machine needs to reboot.




Collect diagnostic information.




Finished, now launch Studio.




Connect the delivery controller to an existing site.




Add the delivery controller address that is already a part of the site.




For this part, in my environment, I selected "Yes."




Enter my creds to add to the database, then let the process begin.




I now have two controllers that are 2016.




Both servers are:




Remember to update the List of DDCs for the new DDC to register the machines.

https://docs.citrix.com/en-us/citrix-virtual-apps-desktops/manage-deployment/vda-registration.html

Finalize Citrix Director.

Finalize Director upgrade run this:

C:\inetpub\wwwroot\Director\tools\Directorconfig.exe /upgrade

If you use Citrix ADM, and Citrix Session Recorder you will need to register the Snapin back after all the upgrades. This is so you can control the feature in Director.

Register Director ADM MAS back.

If using HTTPS to connect to Insight Center, the Insight Center certificate must be valid and trusted by both the Director Server and the Director user’s browser. To link Citrix Director with NetScaler HDX Insight, on the Director server run:

C:\inetpub\wwwroot\Director\tools\DirectorConfig.exe /confignetscaler

Enter Machine name or IP: Netscaler Insights machine or IP vs1ctxadm01.jaxnavy.org
Enter 1 for Citrix ADM (aka MAS).
Rest is self-explanatory.




Register Director Snapin back for Session recording.

Run C:\inetpub\wwwroot\Director\tools\DirectorConfig.exe /configsessionrecording

Enter the Session Recording FQDN (server.FQDN) 19. Enter 1 for HTTPS.

Enter 443 as the port.




Upgrading or replacing the SQL Local DB for Local Host Cache for 1912 or 1912 CU1:

There have been some recent changes to the LTSR article around Local Host Cache upgrades:

  • When upgrading Delivery Controllers to Citrix Virtual Apps and Desktops version 1912 or 2003: Upgrading SQL Server Express LocalDB is optional. Local Host Cache works properly, with no loss of functionality, regardless of whether you upgrade SQL Server Express LocalDB. We added the option to move to a newer version of SQL Server Express LocalDB in case there are concerns about the end of support from Microsoft for SQL Server Express LocalDB 2014.
  • When upgrading Delivery Controllers to Citrix Virtual Apps and Desktops versions newer than 2003: The minimum supported version is SQL Server Express 2017 LocalDB Cumulative Update (CU) 16. If you originally installed a Delivery Controller earlier than version 1912, and have not replaced SQL Server Express LocalDB with a newer version since then, you must replace that database software now. Otherwise, Local Host Cache will not work.

As you can see here, at one time it stated you needed to upgrade, or it would not work. However, it doesn’t seem that is 100% anymore. I think that’s why Citrix updated the doc. 

As you can see here, some had the same concerns or questions around it. I most certainly did. 




So, let’s get started. I always do a snapshot first, which is completed. 

Complete the upgrade of your Citrix Virtual Apps and Desktops components, databases, and site. (Those database upgrades affect the site, monitoring, and configuration logging databases. They do not affect the Local Host Cache database that uses SQL Server Express LocalDB.)

As you can see, I am on 1912 CU1 and have MSQL Express 2014.




On the Delivery Controller, download PsExec from Microsoft. See the Microsoft document PsExec v2.2.





Stop the Citrix High Availability Service.




Open CMD as Admin and open PsExec.exe

psexec -i -u “NT AUTHORITY\NETWORK SERVICE” cm






Move to the folder containing SqlLocalDB.

cd “C:\Program Files\Microsoft SQL Server\120\Tools\Binn”




Stop and delete CitrixHA (LocalDB).
If you don’t stop it, you will get this error (me not paying attention):



SqlLocalDB stop CitrixHA.

SqlLocalDB delete CitrixHA.




Remove the related files in C:\Windows\ServiceProfiles\NetworkService




Uninstall SQL Server Express LocalDB 2014 from the server, using the Windows feature for removing programs.




Install SQL Server Express LocalDB 2017. In the Support > SQLLocalDB folder on the Citrix Virtual Apps and Desktops installation media, double-click sqllocaldb.msi.














Reboot the server and make sure this is started: “Citrix High Availability Service.”




Logged on and it took about 15 seconds to show up.




Then 60 seconds or so on this.




Check if the CitrixHA Db is created.

CitrixHA is re-created the next time configuration sync occurs. After a minute or two, use the SqlLocalDB utility to confirm that CitrixHA has been re-created.

SqlLocalDB i

CitrixHA

MSSQLLocalDB

Example:

While still in the PsExec session run this:

C:\Program Files\Microsoft SQL Server\120\Tools\Binn>SqlLocalDB i

CitrixHA

MSSQLLocalDB








You will see this until you do the second broker.




After I did my second broker this was in the logs:






But then I see this almost every two minutes. I remember reading about this. But I thought it was fixed many versions ago. 




Did some Googling on the errors and came up with the two links below.

https://blog.citrix24.com/xendesktop-7-15-local-host-cache-troubleshooting/

LHC DB upgrade reference:

https://docs.citrix.com/en-us/citrix-virtual-apps-desktops/upgrade-migrate/upgrade.html#replace-sql-server-express-localdb

Turns out some AD account was deleted over time, and it had some bad SIDs.

So, I ran the quick script to get the output.

Get-BrokerApplication |foreach {if ($_.AssociatedUserNames -match “S-1-5-21”) {$_.Name; $_.AssociatedUserNames -match “S-1-5-21”; “”}}





Went into Studio and deleted them from the location it displayed above, which was in Published Application Visibility.

Then, based on CTX230775, had needed to redo the LHC DB. So, quickly ran through the process and it fixed the error. 


In summary, this is how I upgraded the LHC DB and some minor troubleshooting. Hope it helps someone.

Citrix StoreFront 7.15 to 1912 (example I did on one SF server on the upgrade, but you would want 2 servers).

If you have a load balancer, disable it in your load balancer. This way traffic doesn’t route to it. (Assuming you have two or more storefront servers.)

In my case, I have an LB Vserver and IP is X.X.X.X  and back end servers are A.A.A.A  and B.B.B.B

Server A.A.A.A is disabled.

Browse the ISO.






Accept the terms.




Ready to install.




Installing.




Upgrade has finished.




I am adding a new StoreFront Server, so this will be a new install and add to the Storefront store. I just browse to the StoreFront application and run it.






License agreement.




Review prerequisites.




Ready to install.




Installing Software.




Successfully installed Storefront.




Join existing server group.




On the Primary StoreFront Server click “Add Server” here to get an Authorization Code.



Take this information and input it on the secondary StoreFront Server.




Input information on the Second server.




Joining.








Sever joined.

Now add IIS Cert and bind it to 443 in IIS.




Add this second server into NetScaler LB (I already have the one added in NS).

https://docs.citrix.com/en-us/storefront/current-release/integrate-with-citrix-gateway-and-citrix-adc/load-balancing-with-citrix-gateway.html

https://docs.citrix.com/en-us/storefront/current-release/integrate-with-citrix-gateway-and-citrix-adc/load-balancing-with-citrix-gateway.html#citrix-service-monitor

Add Server in netscaler>Traffic Management>Load Balancing>Servers

Add Server.




Add service.




Add monitor.

 



Now go bind it. Once you bind it to the Service, you will notice it’s down – which is normal, from what I have gathered.




The StoreFront monitors by default are only via HTTP. What I created earlier is trying to probe the backend services of our server through HTTPS.

To fix this do this:

Run PowerShell as an administrator.

PS C:\Program Files\Citrix\Receiver StoreFront\Scripts> .\ImportModules.ps1






PS C:\Program Files\Citrix\Receiver StoreFront\Scripts> Get-DSServiceMonitorFeature http://localhost:8000/StorefrontMonitor




Now run the command Set-DSServiceMonitorFeature -ServiceURL https://localhost:443/StoreFrontMonitor.




All steps outlined in Red.




Now you will see the monitor come alive on the Service.




Now bind it to the main Vserver.

Provisioning Server 1808 to 1912.

Please check to see if the previous version needs to be uninstalled first. In some versions, Citrix wants you to uninstall the older version first. But most of the time you don’t need to. 

Example here: https://discussions.citrix.com/topic/400292-pvs-server-upgrade-1808-to-1811-please-uninstall-pvs-server/

We are updating 1808 to 1912 so an in-place upgrade is good.

Before I start, I make sure I use a service account that is tied to the database so it can upgrade the database.

I put the account in the local admin of the PVS servers and use it to do the upgrades


Machine generated alternative text:
•I Panel 
All Control Panel Items Programs and Features 
Uninstall or change a program 
Search Programs and Fei 
To uninstall a program, select it from the list and then click Uninstall, Change, or Repair. 
Orga nize 
Uninstall Repair 
Citrix Diagnostics Facility 
Citrix Host Service PowerSheII snap-in 
Citrix Provisioning Consolexæ 1811.1.0 
Citrix Provisioning Server x64 1808.1.0 
Publisher 
Citrix Systems, Inc. 
Citrix Systems, Inc. 
Citrix Systems, Inc. 
Citrix Systems, Inc. 
Installed On 
8/30/2017 
12/28/2018 
12/28/2018 
10/16/2018

After the uninstall has completed, restart the server. When it comes back up, log back in with the service account.

Attach the ISO. Run Server installation.


Machine generated alternative text:
Citrix Provisioning 
Console Installation 
Server Installation 
Larget Device Installation 
Help and Support 
DVD 
Install the Server and its dependencies. 
O Exit

Click “Install,” the process will begin and then the window will disappear for a couple of minutes while it installs some of the pre-requisites. 


Machine generated alternative text:
Citrix Provisioning Server x64 1906.1.0 InstallShieId Wizard 
Citrix Provisioning Server x64 1906.1.0 requires the following items to be installed on 
your computer Click Install to begin installing these requirements. 
Status 
succeeded 
Succeeded 
Installing 
Pending 
Pending 
Pending 
P ending 
Requir ement 
CDF x64 
Telemetry Service x64 
Broker Snapin v2 x64 
Host PovverSheII Snapln v2 x64 
DelegatedAdmin PonerSheII Snapln x64 
ConfigLogging_PonerSheIISnapInx64 
Con figur a ton _P o n er ShellSnapInx64 
Installing Broker Snapin v2 x64

When the window pops back up Click “Next.” 



Accept the License Agreement and click “Next.”





Enter “Something” in the User Name and Organization fields, then click “Next.”



Click “Next.”



Click “Install.” 




Installing.




Click Finish.




The configuration wizard will start.











 









 

For this screenshot, I have 2 PVS servers. Depending on your farm, you could have one or more. The PVS server IP address will show here. If you have one server then one Ip will show. If you have two, then two will show. 



 









Backup your database before starting.








PVS console upgrade

Log in to the server with the service account.

In C:\SRC\1906 open the “Console” Folder. 

Right-click on “PVS_Console_x64.exe” and run as administrator. 

Once the .exe has launched Click next through the installation.



(Additional Screenshots of steps)

If you run into any issues during the installation of the pre-requisites refer to: 

https://www.carlstalhood.com/provisioning-services-server-install/


Accept the licensing term.




Fill in the names.




Install in the default directory.




Install.





Installing:




Finish.




Open the console and check the version.




You need to re-register those PowerShell snap-ins. Reregistering Citrix.PVS.Snapin.dll is well-known. Here are five other snap-ins that are necessary as well.

https://support.citrix.com/article/CTX235079

Citrix.PVS.Snapin

Citrix.Broker.Admin.V2

Citrix.Configuration.Admin.V2

Citric.ConfigurationLogging.Admin.V1

Ctrix.DelegatedAdmin.Admin.V1

Citrix.Host.Admin.V2


On the PVS server, run CMD as Administrator. Then in each of these folders:

CD \Windows\Microsoft.NET\Framework64\v4.0.30319

CD \Windows\Microsoft.NET\Framework\v4.0.30319


Run all of these commands:

.\InstallUtil.exe “C:\Program Files\Citrix\Provisioning Services Console\Citrix.PVS.Snapin.dll”

.\InstallUtil.exe “C:\Program Files\Citrix\Broker\Snapin\v2\BrokerSnapin.dll”

.\InstallUtil.exe “C:\Program Files\Citrix\Configuration\SnapIn\Citrix.Configuration.Admin.V2\Citrix.Configuration.PowerShellSnapIn.dll”

.\InstallUtil.exe “C:\Program Files\Citrix\ConfigurationLogging\SnapIn\Citrix.ConfigurationLogging.Admin.V1\Citrix.ConfigurationLogging.PowerShellSnapIn.dll”

.\InstallUtil.exe “C:\Program Files\Citrix\DelegatedAdmin\SnapIn\Citrix.DelegatedAdmin.Admin.V1\\Citrix.DelegatedAdmin.PowerShellSnapIn.dll”

.\InstallUtil.exe “C:\Program Files\Citrix\Host\SnapIn\Citrix.Host.Admin.V2\\Citrix.Host.PowerShellSnapIn.dll”


PVS Targets upgrades

You will need to go to the PVS server that you are working on the upgrades and open the PVS console.

Then go to vDisk Pools and create new versions. If you have five versions, then the sixth version will need to be merged with the last base and updates or updates only and needs to be Maintenance mode. It will take some time to create the merge-base.

Now go into your Hypervisor and power on the Master VM up that has the new version.

Open the console so you can see the VM.

It will ask you to press 1 for the new Maintenance version. Press 1, and it will boot into windows.

Now bring over the PVS software, and put it on the C or D drive of the Target.






Click Next at "Welcome to the Installation Wizard for Citrix Provisioning Service Target Device x64."




Select "I accept the terms in the license agreement," Click Next.




Leave as default, Click Next.




Leave as default, Click Next.




At "Ready to install the program," click Install.




Installation will begin and take a few minutes to complete.




Click Finish at "Installation Wizard Completed."




At this stage, the vDisk should be re-sealed (based on your sealing techniques) and re-distributed/copied to each Provisioning Server.

Update the BDM ISO. 

We use the BDM ISO.






Information:

Remember don’t check this unless your troubleshooting:

https://support.citrix.com/article/CTX230333

Reason why is here:

https://discussions.citrix.com/topic/363293-pvs-76-xa65-tds-taking-10mins-to-boot/








Upload to your hypervisor storage. Datastor/Container

Now attach that ISO to the PVS Targets you upgraded on 4c. It will need to new ARDBIN file. (If you forget this step, it will still boot. But will be slower and could get stuck in a loop.)

Citrix WEM 1811 upgrade to 1912 LTSR

Upgrade Deployments.

The data below is from Citrix Workspace Environment Manager 1912 Citrix Systems.

https://docs.citrix.com/en-us/workspace-environment-management/current-release/upgrade.html



The Workspace Environment Management components must be upgraded in the following order:

Infrastructure services

https://docs.citrix.com/en-us/workspace-environment-management/current-release/upgrade.html#step-1-upgrade-the-infrastructure-services

Database

https://docs.citrix.com/en-us/workspace-environment-management/current-release/upgrade.html#step-2-upgrade-the-database

Administration console

 https://docs.citrix.com/en-us/workspace-environment-management/current-release/upgrade.html#step-3-upgrade-the-administration-console

Agent

 https://docs.citrix.com/en-us/workspace-environment-management/current-release/upgrade.html#step-4-upgrade-the-agent


The following changes are going to occur so be ready:

  • A new clean installation of the WEM Agent will result in a complete change of Service Names and Folder Structures as below
  • The new Service name is: Citrix WEM Agent Host Service
  • The new process name is: Wem.Agent.Service.exe
  • The new path structure is: %ProgramFiles%\Citrix\Workspace Environment Management Agent

An upgraded installation of the WEM agent will result in partial changes to your environment:

  • The new Service name is: Citrix WEM Agent Host Service
  • The new process name is: Wem.Agent.Service.exe

The path on the file system will not be altered and will remain as it was: %ProgramFiles%\Norskale\Norskale Agent Host

Be aware also that in both clean and upgraded deployments, the Windows Event logs will change from Norskale Agent Service to WEM Agent Service 

Source:

https://jkindon.com/2019/09/11/citrix-wem-updated-start-up-scripts/

Infrastructure services.




I need .Net 4.7.1






I selected Yes.




Reboot and log in.




















Database

Open the database management Utility.














I at this point just restarted the server.

Check Database parameters (open the WEM Infrastructure Service Configurations).




You will notice the Port and old name (1811).




You will notice the Port and new name -1912.




*One thing to note on Port* 

Cache synchronization port. (Applicable to Workspace Environment Management 1909 and earlier; replaced by Cached data synchronization port in Workspace Environment Management 1912 and later.) The port on which the agent cache synchronization process connects to the infrastructure service to synchronize the agent cache with the infrastructure server. The cache synchronization port must be the same as the port you configured for the cache synchronization port (WEM Infrastructure Service Configuration > Network Settings) during the infrastructure services configuration. The port defaults to 8285 and corresponds to the AgentCacheSyncPort command-line argument.

Cached data synchronization port. (Applicable to Workspace Environment Management 1912 and later; replaces Cache synchronization port of Workspace Environment Management 1909 and earlier.) The port on which the agent cache synchronization process connects to the infrastructure service to synchronize the agent cache with the infrastructure server. The cached data synchronization port must be the same as the port you configured for the cached data synchronization port (WEM Infrastructure Service Configuration > Network Settings) during the infrastructure services configuration. The port defaults to 8288 and corresponds to the CachedDataSyncPort command-line argument. Alternatively, you can specify the port using a command-line option in the silent installation of the WEM agent 

Wayne Lui states it's backward compatible and still listens, but I would add this into your Firewall Ruleset. 




Admin Console.






















Agents

Upgrade the Agent on the machines. I did this with the GUI, but I do this in production.

##Install CMDLine with an SCCM task


Task 1:

“Citrix Workspace Environment Management Agent Setup.exe” Cloud=0 VUEMAppCmdDelay=5 WaitForNetwork=30 SyncForegroundPolicy=1 GpNetworkStartTimeoutPolicyValue=5 /log WEM2003.txt /quiet


Task 2:

##Copys Startup script 

xcopy “\\server\Citrix\Upgrade Files\WEM\2003\Workspace-Environment-Management-v-2003-01-00-01\WemRefreshCache\RefreshWEMAgentonReboot.bat” c:\scripts\refreshWemAgent /h /i /c /k /e /r /y


Task 3:

Then it runs a:

C:\Windows\Microsoft.NET\Framework64\v4.0.30319\ngen.exe update

C:\Windows\Microsoft.NET\Framework64\v4.0.30319\ngen.exe eqi 3


I took James Kindon's script: https://jkindon.com/2019/09/11/citrix-wem-updated-start-up-scripts/

Then it’s called it the same name as my older script was (RefreshWEMAgentonReboot.bat), does an xcopy, and placed it in the same location. This way the scheduled task will still have the same name when it runs. The CLI parameters are different but will do the same deal.










We use BISF to handle this during our sealing process.












Agents are completed.