How to: Rebootscript XenApp 6.5
- Details
- Published: Thursday, 15 September 2011
Updated 21-12-2011
I found that on several systems a failed ping does not set errorlevel to 1, so hostsavailable won't be updated and the script can fail. I now updated the script with another solution, so a failed ping will end in a failed host in the script.
Introduction
In XenApp 6.5 (which is released at 24 August 2011) the way a Server-based Load Evaluator could be assigned to a server has changed in comparison with previous XenApp version. Till 6.5 it was possible to assign a Load Evaluator directly to a server out of the console or using MFCOM/PowerShell. In 6.5 this option is removed and Load Evaluators can only be assigned using Citrix policies. This has advantage that always the correct Load Evaluator is assigned to a server; however I (and many others) used Load Evaluators to get servers out of the standard load balancing (with keeping the possibility to pick a up a disconnected session or to connect via RDP as an administrator) for troubleshooting, maintenance and reboots. Especially with reboots this works beautifully assigning a Load Evaluator based on scheduling (with the least possible active time as possible at the most quit moment on the farm).
In this article I will describe how the same result can be achieved, while using the new techniques in XenApp 6.5.
Pre-Configuration
As mentioned in the introduction Load Evaluators can only be assigned using Citrix Policies. The setting is located logically in the machine part of the policy settings. Citrix Machine Policies can be assigned to Active Directory OUs or Citrix Worker Groups. Because I don't want to move server between OUs during reboot I have chosen to use Worker Groups. So what I did are the following steps. I created the corresponding Load Evaluators. In this case I created one for the default servers, one Load Evaluator for the Backup Data Collector (which will also host applications) and one load evaluator for the reboot/maintenance windows based on the scheduling rule.
During testing I noticed that a server can be member of none, one or more Worker Groups. To be 100% sure the reboot part will not affect anything else, like Published Applications assigned to a Worker Group. So for every Load Evaluator I created also a worker group with the same names as the load evaluator (this is not a requirement, but to keep it simple).
The next step is to create the corresponding policies. Again I have chosen to create separate policies for the load evaluator part, so I created a policy for each load evaluator with only configures setting configured: Load Evaluator Name configured with the corresponding Load Evaluator. This policy again is assigned to the just created Worker Group, so everything is combined.
So creating a policy with setting a load evaluator to a Worker Group all the needed configuration is available to create the rebootscript. The big change in comparison with the other previous scripts is that we are not assigning load evaluators as a start but moving a server from one worker group to another. Although it's possible to be member of more Worker Groups and so you could set-up a priority in the policy you only have to add a server to a Worker Group I decided to keep it orderly that a server should only be member of one Load Evaluator based Worker Group.
Reboot Script
So the script starts with determine the current Worker Group the server is member of currently. Because we are using more Worker Groups per server, one for the load evaluator and one for assigning Published Applications/Desktops we need to find out which of the Worker Groups is meant for the Load Evaluator. That's one of the reasons I used the same name convention. When a Worker Group starts with LE that's the Worker Group we need. When we got that Worker Group we are removing the server from that Worker Group and assign the Worker Group for the NoNewLogons load evaluator. Below shown PowerShell script, which I will call out of another CMD script basically because I'm not really experienced with PowerShell, is arranging this.
# Script : LEtoNoNewLogons.ps1 add-pssnapin citrix.* $computer=get-content env:computername # Determine current Load Evaluator Worker Group and remove server from that group $WGCurrent=get-xaworkergroup -ServerName $computer remove-xaworkergroupserver $WG $computer # Add Computer to NoNewLogons WorkerGroup so new user will be logged on add-xaworkergroupserver $LE $computer |
It's good to know that Citrix policies are using the same refresh period as Active Directory, so it can take up to 90 minutes (by default) for the policy is applied. So the first thing after running the PowerShell script is running a gpupdate to reflect the change of the Worker Groups (and actually assigning a new Load Evaluator). I also create a log file on date (above in the script) to check if everything runs fine and troubleshooting issues. After the server has moved to the NoNewLogon Worker Group users can reconnect to their session, but new sessions will be forwarded to the other servers available in the farm. Normally I enable the NoNewLogon LE round 18:00/19:00 (or a different time if the company is using time shifts in 24Hour environment) and wait for a specified time interval using the simple ping command. In the example script we wait for six hours before we are going to display messages to the connected users that the server will be rebooted in a time frame.
After the last warning message has been shown to the user the script will read out a file where the available server should be filled in. For every server the script will check if the machine is reachable using ping (think about firewalls disable ICMP request) and if the machine is reachable we will check the IMA services. If the response is not running, we presume that the server is not available. If the number of not available servers is higher than the specified amount, the reboot will be aborted. If enough servers are available the server will be rebooted. In the case the reboot is cancelled we will take the server in production again using another PowerShell script, which I will go into detail a bit later in this article.
@ECHO OFF GOTO START ************************************************************************* :START IF NOT EXIST C:\LOG\RebootCheck MD C:\LOG\RebootCheck FOR /f "tokens=1-3 delims=0123456789 " %%i in ("%date%") do set d=%%i%%j%%k FOR /f "tokens=1-3 delims=%d%" %%i in ("%date%") do set d=%%i%%j%%k SET LOGNAME=%~n0-%d% :: Change the LE of the Server to NoNewLogons by changing the Citrix Worker Group ECHO Using PowerShell script to Disable New Logons using LE and Worker Groups >>%LOGFILE% powershell %LFILES%\LEtoNoNewLogons.ps1 ECHO Start Gpupdate to force the new LE and Worker Group >>%LOGFILE% gpupdate /force :: Wait for 6 Hours to start displaying messages to the end user ECHO Wait for 6 Hours to start displaying messages using PING -n 21600
:DISPLAYMSG
MSG * /SERVER:%COMPUTERNAME% /time:120 "This server will be restarted in 60 minutes." MSG * /SERVER:%COMPUTERNAME% /time:120 "This server will be restarted in 30 minutes." MSG * /SERVER:%COMPUTERNAME% /time:120 "This server will be restarted in 15 minutes." MSG * /SERVER:%COMPUTERNAME% /time:120 "This server will be restarted in 10 minutes." MSG * /SERVER:%COMPUTERNAME% /time:120 "This server will be restarted in 5minutes. Please save your work and logoff. You can logon directly again, where you will be forwarded to another server" GOTO :CHECKSERVERSONLINE
:CHECKSERVERSONLINE SET HOSTSNOTAVAILABLE=0 FOR /F "tokens=*" %%G in ('type "%SERVERFILE%"') do call :CheckStatus %%G IF %HOSTSNOTAVAILABLE% GEQ %MAXLOSTSERVERS% GOTO :CANCEL ECHO Enough Servers Online to Reboot. Reboot for %COMPUTERNAME% will be excuted now >>%LOGFILE% GOTO :END :CheckStatus SET TSNAME=%1 DEL %TEMP%\ping.txt PING %TSNAME% >%temp%\ping.txt FOR /F "tokens=*" %%i in ('FIND /i "Reply" %temp%\ping.txt') DO CALL :LOGCHECK %%i IF %RESULT%==NOT_FOUND set /a HOSTSNOTAVAILABLE+=1 & GOTO :EOF FOR /F "tokens=1,2,3,4" %%A IN ('SC.EXE \\%TSNAME% QUERY IMAService ^| FIND /I "STATE"') DO SET STATE=%%D IF NOT %STATE%==RUNNING set /a HOSTSNOTAVAILABLE+=1 GOTO :EOF :: ------------------------------------------------------------------------- ECHO Script has determnied that the at least %MAXLOSTSERVERS% server(s) are not available. Reboot for %COMPUTERNAME% is cancelled >>%LOGFILE% MSG * /SERVER:%RBSERVER% /time:120 "The reboot of server is cancelld. You can keep on working." powershell %LFILES%\LEtoDefaultLE.ps1 gpupdate /force :END |
Normally I will use a scheduled task to start the reboot process. In a similar article about rebooting servers (with Kemp Load Balancer) I already described how this can be accomplished, so read that article for more information about creating the scheduled task.
After the reboot
After the server is started up again and for example installation and maintenance tasks are performed we need to remove the server from the NoNewLogon Worker Group and add them to his corresponding Load Evaluator group. I again created a small PowerShell script to accomplish start, which I will start as (a part of) a start-up script. In the script you need to define the name of the server hosting the Backup Data Collector (logically this is only necessary if the BDC also acts as application host and the primary data collector is dedicated in this case) and the corresponding Worker Group names. The scripts checks the computername and if it matches the specified BDC name, the server will be added to the BDC Load Evaluator Worker Group otherwise the defined standard Load Evaluator will be used. Don't forget to run the gupdate /force again; otherwise it can take up to 90 minutes before the load evaluator is actually applied.
# Script : LEtoDefaultLE.ps1 add-pssnapin citrix.* $computer=get-content env:computername # Remove Computer from No New Logons Worker Group remove-xaworkergroupserver $NOLOGONWG $computer # Add Computer to his standard LE Worker Group if ($computer -eq $BDCServer) {add-xaworkergroupserver $BDCWG $computer} |
Conclusion
With the release of Citrix XenApp 6.5 the way load evaluators are assigned has changed. It's not possible anymore to directly assign a Load Evaluator to a server, but this should be done using Citrix Policies. However in the previous versions I (and many other) used the Load Evaluator for reboots by assigning a specific Load Evaluator to get the server on a nice way out of the farm. In this article I have explained and shown how the same behavior still can be accomplished using policies and Worker Groups.