It was not possible to launch the selected application.If you run “QFarm /Load” on any one of the XenApp server in the farm, load results doesn’t list the zombie server. '”Change Logon /Query” command result shows Logon is enabled. I read the available hot fixes and none of them fixes this issue.
Please contact your administrator
The Citrix client reported error: 12
Easy fix is to restart “Citrix Independent Management architecture” aka IMA service on the problematic server. By restarting IMA service you are re-registering the server to the Farm. The load balancing algorithm starts accounting the server after IMA restart.
So I wrote the following script and run it by hour using Windows Scheduler on one of the XenApp server. This script sends emails details report to specified admins when it fixes the zombie server issue. Till I find a permanent fix from Citrix or Microsoft, This script is saving me from aches.
If you want to use this script, copy and paste this script to Notepad. Look for “<<<< Modify the value here..” and change the appropriate values according to your company. Schedule it on one of your XenApp servers.
'======================================================================' Name: Fix-XenApp-Servers.vbs' Purpose: Detect if XenApp server is dropped from Load Balancing.' If Yes, Restart the Citrix IMA server and send email alert.' Parameters: None' Written By: Anand Venkatachalapathy' Date Written: Feb 10th 2010'====================================================================== Const IMAService = "Citrix Independent Management Architecture"Dim WshShell, WshExecDim LoadData, emailSubject,emailTo,iPublic emailBodyDim XenAppServers XenAppServers = Array("CitrixSvr1","CitrixSvr2","CitrixSvr3") '<<<<<<<<< Modify the value here emailTo = "admin1@company.com;admin2@company.com" '<<<<<<<<< Modify the value hereSet WshShell = WScript.CreateObject("WScript.Shell") 'Run qfarm /load command and get the results to LoadData variableSet WshExec = WshShell.Exec("qfarm /load ") LoadData = LCase(WshExec.StdOut.ReadAll) For i = 0 To UBound(XenAppServers) 'Check if XENAPPxx server is missing If InStr(LoadData,LCase(XenAppServers(i))) = 0 Then WScript.Echo XenAppServers(i) & " is not responding" emailSubject = XenAppServers(i) & " was not responding, IMA service restarted" emailBody = XenAppServers(i) & " Server was not listed in QFarm /Load command as below" & vbCrLf emailBody = emailBody & LoadData & vbCrLf & vbCrLf & _"Trying to fix by restarting IMA service to re-register to the farm" & vbCrLf & vbCrLf 'Restart Citrix IMA service service_control XenAppServers(i),IMAService,"restart" Set WshExec = WshShell.Exec("qfarm /load ") LoadData = LCase(WshExec.StdOut.ReadAll) emailBody = emailBody & "QFarm /Load results after IMA service restart" & vbCrLf emailBody = emailBody & LoadData emailBody = emailBody & vbCrLf & vbCrLf & "--------Written By: Anand Venkatachalapathy------------" 'Send email to Citrix Admins Alert_Admins emailTo,emailSubject,emailBody End If Next '*** End of Script *** '==============================================================================' Name: Service_Control' Purpose: Restart, Stop or Start a Service on a remote server ' Input: strComputer - Remote Server Name' sname - Service Display Name' purpose - has to be "stop" or "start" or "restart"'==============================================================================Sub Service_Control(strComputer,sname,purpose) 'strComputer is the computer you want to connect to 'sname is the service name 'purpose is whether or not you want to start, stop or restart a service Dim delay, err_return delay = 20000 '20 seconds WScript.stdout.Write "*" Set objWMIService = GetObject("winmgmts:" _ & "{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2") Set colListOfServices = objWMIService.ExecQuery _ ("Select * from Win32_Service where DisplayName = '" & sname & "'") For Each objService In colListOfServices 'Just to double check we have the right service If objService.displayname = sname Then WScript.stdout.Write "*" If purpose = "stop" Or purpose = "restart" Then emailBody = emailBody & "Trying to stop " & strComputer & "\" & objService.name & vbCrLf err_return = objService.stopservice 'service has dependencies, so we need to stop those first If err_return = 3 Then 'GOTCHA - you have to use the service.name NOT service.displayname for this query!! 'even if you change Win32_Service.Name to Win32_Service.DisplayName Set colServiceList2 = objWMIService.ExecQuery("Associators of " _ & "{Win32_Service.Name='" & objService.name & "'} Where " _ & "AssocClass=Win32_DependentService " & "Role=Antecedent" ) For Each objService2 in colServiceList2 emailBody = emailBody & "Trying to stop " & strComputer & "\" & objService2.name & vbCrLf objService2.StopService() If Not objService2.state = "Stopped" Then 'you have to pause because the service wont start unless it is completely stopped WScript.Sleep delay service_control strComputer,sname,"stop" Else 'WScript.Echo objService2.displayname & " has been stopped." emailBody = emailBody & strComputer & "\" & objService2.name & "has been stopped." & vbCrLf End If Next 'stop the original service that had dependencies emailBody = emailBody & "Trying to stop " & strComputer & "\" & objService.name & vbCrLf objService.stopservice Else If Not objService.state = "Stopped" Then 'you have to pause because the service wont start unless it is completely stopped WScript.Sleep delay service_control strComputer,sname,"stop" Else 'WScript.Echo objService.displayname & " has been stopped." emailBody = emailBody & strComputer & "\" & objService.displayname & " has been stopped." & vbCrLf & vbCrLf End If End If 'if restart was sent, start service after it has stopped If purpose = "restart" Then service_control strComputer, sname, "start" End if Elseif purpose = "start" Then WScript.stdout.Write "*" emailBody = emailBody & "Trying to start " & strComputer & "\" & objService.name & vbCrLf err_return = objService.startservice If NOT err_return = 10 Then 'GOTCHA - you have to use the service.name NOT service.displayname for this query!! 'even if you change Win32_Service.Name to Win32_Service.DisplayName Set colServiceList2 = objWMIService.ExecQuery("Associators of " _ & "{Win32_Service.Name='" & objService.name & "'} Where " _ & "AssocClass=Win32_DependentService " & "Role=Antecedent" ) For Each objService2 in colServiceList2 emailBody = emailBody & "Trying to start " & strComputer & "\" & objService2.name & vbCrLf objService2.StartService() If Not objService2.state = "Running" Then 'you have to pause because the service wont start unless it is completely stopped WScript.Sleep delay service_control strComputer,sname,"start" Else WScript.Echo objService2.displayname & " has been started." emailBody = emailBody & strComputer & "\" & objService2.displayname & " has been started" & vbCrLf End If Next emailBody = emailBody & "Trying to start " & strComputer & "\" & objService.name & vbCrLf err_return = objService.startservice 'service has dependencies, so we need to start those first If err_return = 3 Then 'start the original service that had dependencies emailBody = emailBody & "Trying to start " & strComputer & "\" & objService.name & vbCrLf objService.startservice 'End If If Not objService.state = "Running" then 'you have to pause because the service wont start unless it is completely stopped WScript.Sleep delay service_control strComputer,sname,"start" Else 'WScript.Echo objService.displayname & " has been started." emailBody = emailBody & strComputer & "\" & objService.displayname & " has been started." & vbCrLf End If End If End If 'WScript.Echo objService.displayname & " has been started." emailBody = emailBody & strComputer & "\" & objService.displayname & " has been started" & vbCrLf End If End If Next End Sub '*** End of service_control sub *** '======================================================================' Name: Alert_Admins' Purpose: Sends email ' Input: strTo - Who to send to, strSub - Subject of the message' strBody - Body of the message' Output: Sends the emails to the strTO recipients'======================================================================Sub Alert_Admins( strTo,strSub,strBody) 'WScript.Echo strBody '* iMsg - holds CDO.Message object '* Flds - Enumeration for CDO SMTP object properties '* iConf - holds CDO.Configuration Dim iMsg, Flds, iConf '* sSMTPServerName - SMTP Server Name Dim sSMTpServerName '* Assign corpml servers as SMTP server sSMTPServerName = "smtp.company.com" '<<<<<<<<< Modify the value here '* Assign cdoSendUsingPort is set to 2, i.e., send using SMTP (25) port Const cdoSendUsingPort = 2 '* Create CDO Objects and assign to variables Set iMsg = CreateObject("CDO.Message") Set iConf = CreateObject("CDO.Configuration") Set Flds = iConf.Fields '* Assign values to Flds class properties With Flds .Item("http://schemas.microsoft.com/cdo/configuration/sendusing") = cdoSendUsingPort .Item("http://schemas.microsoft.com/cdo/configuration/smtpserver") = sSMTPServerName .Item("http://schemas.microsoft.com/cdo/configuration/smtpconnectiontimeout") = 25 .Update End With '* Assign message properties and Send the mail With iMsg Set .Configuration = iConf .Fields("urn:schemas:httpmail:importance").Value = 2 'Setting Mail importance to High (2) .Fields.Update .To = strTo 'Fake, but make-sense email FROM address .From = "XenApp-Fixer@company.com" '<<<<<<<<< Modify the value here 'Return Email address .Sender = "XenApp-Fixer@company.com" '<<<<<<<<< Modify the value here .Subject = strSub .TextBody = strBody .Send End With End Sub'*** End of Alert_Admins Sub ***
No comments:
Post a Comment