The new theory for placing a server off-line is to apply an “Out of service” load evaluator instead of disabling logons. The “Out of service” load evaluator consists of an empty Scheduling rule. The issue with this theory is that if you automate the move of a server into an “Out of service” load evaluator for maintenance, reboots, etc, then how do you know which load evaluator to move it back into when it’s ready to be placed back into production? I guess most would hard code this, or reference it from an ini file, etc, but that requires too much maintenance, as it can be difficult to manage in the larger farms that make use of different load evaluators across different hardware and load managed groups. So I enhanced the original version of this script to address this exact problem. It will read the existing load evaluator and write it against a registry value called PreviousLoadEvaluator under the HKLM\SOFTWARE\Citrix key. Then you can easily re-run this script with certain parameters to set the load evaluator back to what it was previously using. A simple concept that works very well.
For Example:
To move a server into the “Out of service” load evaluator, run…
cscript.exe AttachLE.vbs “Out of service”
To move a server back into its previous load evaluator, run…
cscript.exe AttachLE.vbs SetPrevious
Enjoy!
' ' Script name: AttachLE.vbs ' ' Purpose: Attaches a load evaluator to a Citrix server. ' ' Syntax: AttachLE lename ' ' lename The load evaluator's name (case sensitive) ' '--------------------------------------------------------------------------------------- ' ' Based on a script written by Frank-Peter Schultze (http://www.fpschultze.de) ' ' Version 1.0 - Written by Jeremy@jhouseconsulting on 9th July 2008. ' Version 1.1 - Updated by Jeremy@jhouseconsulting on 1st September 2008. ' ' For Example: ' ' To move a server into the "Out of service" load evaluator, run... ' cscript.exe AttachLE.vbs "Out of service" ' ' To move a server back into its previous load evaluator, run... ' cscript.exe AttachLE.vbs SetPrevious ' More Examples: ' ' To move a server into the Default load evaluator run the following command... ' cscript.exe AttachLE.vbs Default ' ' To move a server into the Advanced load evaluator run the following command... ' cscript.exe AttachLE.vbs Advanced ' '--------------------------------------------------------------------------------------- Option Explicit ' Note that the built-in Default load evaluator is MFDefaultLE, and the Advanced load evaluator is LMSDefaultLE. Const CTX_LE_DEFAULT = "MFDefaultLE" Const CTX_LE_ADVANCED = "LMSDefaultLE" Dim strCitrixServer : strCitrixServer = "" Dim strLEName : strLEName = "" Dim WshNetwork Call GetArgs(strLEName) Set WshNetwork = WScript.CreateObject("WScript.Network") strCitrixServer = UCase(WshNetwork.ComputerName) IF strLEName = "setprevious" Then Call SetPreviousLE(strCitrixServer) Else Call GetCurrentLE(strCitrixServer) Call AttachLEToServer(strCitrixServer, strLEName) End If Set WshNetwork = Nothing wscript.quit(0) Sub SetPreviousLE(strCitrixServer) Dim WshShell, strLEName, strKey, strValue Set WshShell = CreateObject("WScript.Shell") strKey = "HKLM\SOFTWARE\Citrix" strValue = "PreviousLoadEvaluator" If RegValueExists(strKey & "\" & strValue) Then strLEName = WshShell.RegRead(strKey & "\" & strValue) wscript.echo "The previous load evaluator was " & chr(34) & strLEName & chr(34) Else wscript.echo "The previous load evaluator was not set. This script will exit." Set WshShell = Nothing Exit Sub End If Select Case LCase(strLEName) Case "default" strLEName = CTX_LE_DEFAULT Case "advanced" strLEName = CTX_LE_ADVANCED Case Else End Select Call AttachLEToServer(strCitrixServer, strLEName) WshShell.RegDelete(strKey & "\" & strValue) Set WshShell = Nothing End Sub Sub AttachLEToServer(strCitrixServer, strLEName) Dim objFarm On Error Resume Next Set objFarm = WScript.CreateObject("MetaFrameCOM.MetaFrameLoadEvaluator") On Error GoTo 0 If IsObject(objFarm) Then objFarm.LEName = strLEName objFarm.LoadData(True) objFarm.AttachToServerByName False, strCitrixServer objFarm.SaveData() Set objFarm = Nothing Select Case strLEName Case "MFDefaultLE" strLEName = "Default" Case "LMSDefaultLE" strLEName = "Advanced" Case Else End Select wscript.echo "The load evaluator for " & strCitrixServer & " has now been set to " & chr(34) & strLEName & chr(34) Else WScript.Echo "Can not create MFCOM object." End If Set objFarm = Nothing End Sub Sub GetCurrentLE(strCitrixServer) Dim WshShell, ServerObj, sCurrentLE, strCurrentValue, strKey, strValue Const MetaFrameWinSrvObject = 6 Set WshShell = CreateObject("WScript.Shell") Set ServerObj = CreateObject("MetaframeCom.MetaFrameServer") ServerObj.Initialize MetaFrameWinSrvObject, strCitrixServer Set sCurrentLE=ServerObj.AttachedLE sCurrentLE.Loaddata(True) strCurrentValue=sCurrentLE.LEName Select Case strCurrentValue Case "MFDefaultLE" strCurrentValue = "Default" Case "LMSDefaultLE" strCurrentValue = "Advanced" Case Else End Select strKey = "HKLM\SOFTWARE\Citrix" strValue = "PreviousLoadEvaluator" WshShell.RegWrite strKey & "\" & strValue, StrCurrentValue wscript.echo strCitrixServer & " is currently using the " & chr(34) & StrCurrentValue & chr(34) & " load evaluator" Set WshShell = Nothing Set ServerObj = Nothing End Sub Sub GetArgs(ByRef strLEName) Dim objArgs, strTmp Set objArgs = WScript.Arguments If (objArgs.Count = 1) Then strTmp = objArgs.Item(0) Select Case LCase(strTmp) Case "default" strLEName = CTX_LE_DEFAULT Case "advanced" strLEName = CTX_LE_ADVANCED Case "setprevious" strLEName = "setprevious" Case Else strLEName = strTmp End Select Else Call Usage(True) Exit Sub End If End Sub Sub Usage(blnQuit) WScript.Echo "Attaches a load evaluator to a Citrix server." & VbCrlf & VbCrlf & _ "Usage: " & WScript.ScriptName & " ''<lename>''" & VbCrlf & VbCrlf & _ "Where lename is the load evaluator's name. It IS case sensitive" & VbCrlf & _ "and MUST be surrounded with double quotes if it contains spaces." & VbCrlf If blnQuit Then WScript.Quit(0) End Sub Function RegValueExists(sRegValue) ' Returns True or False based of the existence of a registry value. Dim oShell, RegReadReturn Set oShell = CreateObject("WScript.Shell") RegValueExists = True ' init value On Error Resume Next RegReadReturn = oShell.RegRead(sRegValue) If Err.Number <> 0 Then RegValueExists = False End if On Error Goto 0 Set oShell = Nothing End Function