Wilco van Bragt - LinkeIn Wilco van Bragt - Twitter rssa 

How to: Reboot Script with Kemp Load Balancers

In this earlier published article I already described the design decisions for creating a reboot script. In this article I will describe a complete reboot script to reboot  Terminal Servers, which are load balanced using a Kemp Load Balancer. I will follow the design decisions in that document to describe the code.

Central v Locally




 

For this customer we decided to place the scripts and the logging locally so a network failure or changed rights won't stop the script from working. With the startup script we will synchronize the scripts with the data on a central share, so that modifications are only need to be made on one location.

@ECHO OFF

GOTO START

*************************************************************************
**
** Script              : Reboot_Server.cmd
** Author           : Wilco van Bragt
** Creation Date: 8-2-2011
** Usage            : Rebooting Server + Check Servers Online
**                           
**
***************************************************************************
**
** Date                               Version                Scripter                               Change
** -----------------------------------------------------------------------------------------
** 11:04 8-2-2011 0.1     WvB                      Intial version
**
**
**
***************************************************************************

:START

                 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%

                SET LOGFILE=C:\LOG\RebootCheck\%LOGNAME%.log

                SET SOURCES=C:\LocalScripts\Sources

                SET TSSERVERFILE=C:\LocalScripts\Sources\TerminalServers.txt

 Script Content

Disable logons on forehand

This one was the most difficult to accomplish. At this customer we decided to let the Kemp Load Balancer do all the load balancing without interacting with the RD Broker. So if we use the MS Disable Logon (which is actually enhanced a lot in Windows 2008 R2, but more about that in a later article) the load balancer does not know about it and would send users to disabled logon servers. Therefore we should find something that makes it possible to disable the server in the Kemp Load Balancing mechanism. I found some information in the manual, but I did not get the message exactly, so I contacted Kemp Support. They helped me perfectly with the command line to make this possible. I needed the curl.exe (took me some time to find the 64bit version working on Windows 2008 R2). In some way the Kemp Load Balancers are working exactly as I hoped. When a user has a disconnected session the state in the load balancer of the real server is bypassed and the user connects to his disconnected session (on the server that has the status disabled within the configuration).

Because the customer just had a few servers I made the script easy by just checking on the actual computer name corresponds with a predefined value. So I multiplied the line below with the actual values like <<COMPNAME>>, <<IPManagementKemp>> and <<IPREALSERVER>>

: Disable Server within Kemp LB so server does not accept new logons

ECHO Disable server in Kemp LB so server does not accepte new logons >>%LOGFILE%

IF %COMPUTERNAME%==<<COMPNAME>> %SOURCES%\curl -k -u bal:<<password>> -d "state=Disable" https://<IPMANAGENTKEMP>>/progs/showrs/enable_disable/<<IPREALSERVER>>

EXAMPLE:

IF %COMPUTERNAME%==VANBRAGTS1 %SOURCES%\curl -k -u bal:secret>> -d "state=Disable" https://172.16.77.111>>/progs/showrs/enable_disable/172.16.77.21

Check if enough servers are available

The servers used were Microsoft Windows 2008 R2, so I re-used my earlier written script to check if a server is online using the a text file, which are specifying which Terminal Servers are being used. Using the for command we will read the Terminal Server out of the text file and query the server using the QUERY TERMSERVER command. If the output has a value with known mentioned we know the server is online (and normally accepting/hosting sessions).

:CHECKSERVERSONLINE

SET HOSTSNOTAVAILABLE=0

FOR /F "tokens=*" %%G in ('type "%TSSERVERFILE%"') do call :CheckStatus %%G

:CheckStatus

                SET TSNAME=%1
                CALL QUERY TERMSERVER %TSNAME% >>C:\LocalScripts\QueryResult.txt
                FOR /f "tokens=*" %%i IN ('FIND /i "Known" C:\LocalScripts\QueryResult.txt') DO CALL :LOGCHECK %%i
                IF /i %RESULT%==NOT_FOUND set /a HOSTSNOTAVAILABLE+=1
                ECHO %HOSTSNOTAVAILABLE%

GOTO :EOF

:: -------------------------------------------------------------------------
::              LOGCHECK
:: -------------------------------------------------------------------------

:LOGCHECK

                SET VALUE=%*
                IF NOT "%VALUE:~,5%"=="-----" SET RESULT=FOUND
                IF /I "%VALUE:~,5%"=="-----" SET RESULT=NOT_FOUND
                del C:\LocalScripts\QueryResult.txt
                GOTO :EOF

Executable to reboot the machine

In Windows 2008 R2 the tsshutdwn.exe has been removed. I'm now using the "normal" shutdown.exe (where the tsshutdwn functionally has been added to) just with the /R switch.

IF %HOSTSNOTAVAILABLE% GEQ 1 GOTO :CANCEL

                ECHO Enough Servers Online to Reboot. Reboot for %COMPUTERNAME% will be excuted now >>%LOGFILE%

                CALL %SYSTEMROOT%\system32\shutdown.exe /R
                GOTO :END

Logging of the reboot process

Logically I will add logging where possible. In this case the logging is done locally and we are logging several phases. For example the check if enough server are available and, disabling the real server in the load balancer. We also notify the connected users that the server will be restarted with a time frame.

:DISPLAYMSG

MSG * /SERVER:%COMPUTERNAME% /time:120 "This server will be restarted in 60 minutes."

ECHO At %time% the message 60 Minutes displayed to end-user on server %COMPUTERNAME% >>%LOGFILE%

ping -n 1800 localhost

MSG * /SERVER:%COMPUTERNAME% /time:120 " This server will be restarted in 30 minutes."

ECHO At %time% the message 30 Minutes displayed to end-user on server %COMPUTERNAME% >>%LOGFILE%

ping -n 900 localhost

MSG * /SERVER:%COMPUTERNAME% /time:120 " This server will be restarted in 15 minutes."

ECHO At %time% the message 15 Minutes displayed to end-user on server %COMPUTERNAME% >>%LOGFILE%

ping -n 600 localhost

MSG * /SERVER:%COMPUTERNAME% /time:120 " This server will be restarted in 10 minutes."

ECHO At %time% the message 10 Minutes displayed to end-user on server %COMPUTERNAME% >>%LOGFILE%

ping -n 300 localhost

MSG * /SERVER:%COMPUTERNAME% /time:120 " This server will be restarted in 5 minutes. Please save your work and log off the session. Within 5 minutes you can log on again. "

ECHO At %time% the message 5 Minutes displayed to end-user on server %COMPUTERNAME% >>%LOGFILE%

ping -n 300 localhost

Reboot Schedule (Creation)

One of the parts of the unattended installation is a small script that adds a scheduled task on the server for initiating the reboot. In this example the server is rebooted twice a week. The days and time are specified in a small .csv based. This file is read and the parameters are filled in the script with this information. If the correct information is found (corresponding with the servername) the values are used to set-up the scheduled task using the default SCHTASKS command.

:: Adding Reboot Schedule

SET SHEDULEDTASKFILE=C:\LocalScripts\Sources ebootschedule.csv

for /F "tokens=1,2,3,4 delims=," %%G in ('type "%SHEDULEDTASKFILE%"') do call :ProcessPair %%G %%H %%I %%J

GOTO :FINALIZE

:ProcessPair

                set HOST=%1
                set DAY=%2
                set DAY2=%3
                set TIME=%4
                if "%HOST%" neq "" (
                               if "%HOST%" equ "%COMPUTERNAME%" (CALL SCHTASKS /Create /RU HOFPOORT\svc_rds /RP Wr0cl@w /SC WEEKLY /TN "Scheduled Reboot" /TR "C:\LocalScripts\RebootServer.cmd" /D %DAY%,%DAY2% /ST %TIME% /SD 01/01/2011 /F )

     )

Start-up Script

The last step needed is that after the reboot the server will be added to the load balancer again and that users can connect again. Therefore in the startup script that will run during start-up (also added as a scheduled task) the command to the load balancers will be send to enable the real server again in the load balance configuration and on the server logons will be enabled.

Echo Enabling Logons

CHANGE LOGON /ENABLE >>%LOGFILE% 2>&1

IF %COMPUTERNAME%==<<COMPNAME>> %SOURCES%\curl -k -u bal:<<password>> -d "state=Enable" https://<IPMANAGENTKEMP>>/progs/showrs/enable_disable/<<IPREALSERVER>>

EXAMPLE:

IF %COMPUTERNAME%==VANBRAGTS1 %SOURCES%\curl -k -u bal:secret>> -d "state=Enable" https://172.16.77.111>>/progs/showrs/enable_disable/172.16.77.21

Conclusion

In this article I showed how a controlled reboot can be performed arranging that no users will connect to the server, which will be restarted, load balanced using the Kemp Load Balancer.