In this multipart serie of blogposts, I will try to give some examples to keep an eye on the monitoring of BizTalk, without having the need to log on to the environment. Emails will be sent to specific users about certain information.
The second part of this serie will be tackling dehydrated messages. With some simple scripting, specific user can be notified when a service instance is in a dehydrated state for too long. Dehydrated instances can occur when a long running process for example has been developed, but every instance has a certain “maximum runtime”. When that runtime is surpassed, we want to have a notification about it that something might be wrong with the process. What also will be done in this script is, next to sending just an email, is also including an attachment containing the message which was processed last by the service instance.
Next to notifying a user, there is also the option to terminate dehydrated instances after a certain amount of time to clean out the BizTalk environment. This way, having instances dehydrated for months can be avoided. The messages are also stored and the location of this storage is communicated together with the email notification of a terminate.
First, some variables are defined and initialized. An argument is needed in this script, being ‘daily’ or ‘minutely’. This indicates which part of the script needs to be executed:
- Daily: Check for dehydrated instances (eg. Older than 2 days) and terminate them
- Minutely: Check for dehydrated instances (eg. Older than 10 minutes)
A temporary file location is used to temporarily store saved messages. The strEmailAdressesCC indicates an email address which needs to be in CC of ALL the mails that are being sent. The terminate instances option indicates whether instances need to be terminated or not.
Option Explicit DimstrBaseTempFilesDir,strEmailAdressesCC,bTerminateInstancesAndDeleteDir,strSchedule,strTimeInterval,strSubject,strBody If Wscript.Arguments.Count <> 1 Then Wscript.Echo “Need 1 argument: ‘Daily’ or ‘Minutely'” Wscript.Quit(1) End If strBaseTempFilesDir = CreateObject(“Wscript.Shell”).CurrentDirectory strEmailAdressesCC = “BizTalkAdministratorGroup@yourcompany.com” bTerminateInstancesAndDeleteDir = False strTimeInterval = “d”
The first of two large parts in the script will be handling all the ‘minutely’ processing. This involves checking if there are any instances dehydrated for a certain time, and informing certain users about this issue. Also the messages will be saved and sent. The saving and emailing is handled later. Multiple instance types can be used within one call to ‘ProcessDehydratedMessages’. In this case, two calls are being done to this function, with both a different timestamp. The first call will only be checking the provided instance types after 10 minutes of dehydration, the second call will be notifying users after 20 minutes of dehydration.
‘================================================== ‘ Alert dehydrated instances of Orchestration type(s) older than X minutes and evt. send email ‘================================================== IfUCase(Wscript.Arguments(0)) = “MINUTELY” Then bTerminateInstancesAndDeleteDir = False strTimeInterval = “n”‘ n for minutes strSubject = “Dehydrated instance of: “ strBody = ” is in a dehydrated state.” & vbCrLf & “Please find the message in attachment.”& vbCrLf & vbCrLf & “BizTalk is waiting for a response message:” & vbCrLf ProcessDehydratedInstances Array(“orcOrderManagementFlowXType”,“orcCustomerRelationsFlowXType”),10,“email@example.com;firstname.lastname@example.org” ProcessDehydratedInstances Array(“orcPeopleManagementFlowZType”,“orcInvoicingReceivalType”),20,“email@example.com;dean.burton@Dexia.com” Wscript.Quit
The second part is doing initially the same thing as the part above, but is used to indicate which instances are dehydrated for too long and will be terminated. At the end of this part, the script will also delete all currently existing folders which contain no data.
‘======================================================== ‘ Terminate dehydrated instances of Orchestration type(s) older than X days and evt. send email ‘======================================================== IfUCase(Wscript.Arguments(0)) = “DAILY” Then bTerminateInstancesAndDeleteDir = True strTimeInterval = “d” strSubject = “Terminated instance of: “ strBody = ” has been in a dehydrated state for too long and is now terminated.”& vbCrLf & “Please find the message in attachment.” & vbCrLf & vbCrLf & “BizTalk is no longer waiting for a response:”& vbCrLf ProcessDehydratedInstances Array(“orcOrderManagementFlowXType”,“orcCustomerRelationsFlowXType”),30,“firstname.lastname@example.org;email@example.com” ProcessDehydratedInstances Array(“orcPeopleManagementFlowZType”,“orcInvoicingReceivalType”),2,“firstname.lastname@example.org;dean.burton@Dexia.com” ProcessDirectoriesForNonexistentServiceInstances Wscript.Quit End If Wscript.Quit
Now, we’re going to dive deeper into the function ‘ProcessDehydratedInstances’. The function starts again with defining the WMI elements to connect with the BizTalk server and to create a current datetime object. The provided date value is deducted from the current date/time.
FunctionProcessDehydratedInstances (strOrchnames,Interval,strEmailAdresses) DimobjWMI,objDatetime,strOrcName,svcInsts,svcInst Set objWMI = GetObject(“winmgmts:rootMicrosoftBizTalkServer”) Set objDatetime = CreateObject(“WbemScripting.SWbemDateTime”) objDatetime.SetVarDate DateAdd(strTimeInterval, -Interval, Now)
All the provided instance type names, stored in the string array ‘strOrchnames’ are being looped and searched for dehydrated instances on the BizTalk environment. If an email address (or multiple) is provided, the function SaveAndEmailFiles is called. Read on to see the details of this function. Also the Boolean bTerminateInstancesAndDeleteDir is checked. If true, then the instance will be terminated.
For Each strOrcName InstrOrchnames Set svcInsts = objWMI.ExecQuery(“SELECT * FROM MSBTS_ServiceInstance WHERE ServiceStatus = 8 AND ServiceName = ‘”& strOrcName & “‘ AND ActivationTime < ‘” & objDatetime.Value & “‘”) For Each svcInst InsvcInsts IfstrEmailAdresses <> “” Then SaveAndEmailFiles strOrcName,svcInst.InstanceID,strEmailAdresses,svcInst.ActivationTime End If IfbTerminateInstancesAndDeleteDir = True Then svcInst.Terminate ‘Wscript.echo “Terminated: ” & strOrcName & ” ” & svcInst.InstanceID End If Next Set svcInsts = Nothing Next Set objDatetime = Nothing Set objWMI = Nothing End Function
The SaveAndEmailFiles function will take care of saving all messages and sending emails. It starts typically with defining the base for doing WMI calls.
Function SaveAndEmailFiles (strOrcName,ServiceInstanceID,strEmailAdresses,ActivationTime) DimobjWMI,objFSO,objFolder,strInstanceFiles,msgInsts,msgInst, objShell, strDescription, strCommand Set objWMI = GetObject(“winmgmts:rootMicrosoftBizTalkServer”) Set objFSO = CreateObject(“Scripting.FileSystemObject”)
A string is being constructed to save the messages to. This consists of the instance type name.
strInstanceFiles = strBaseTempFilesDir & “” & strOrcName & “” & ServiceInstanceID Set objShell = CreateObject(“WScript.Shell”) strDescription = strInstanceFiles
The query is being executed and the messages are being saved by calling the ‘SaveToFile’ function. Read on to see the details of this function as well. The ‘SendMail’ function is also called, as well at a save of messages as a terminate.
If Not objFSO.FolderExists(strInstanceFiles) Then objFSO.CreateFolder(strInstanceFiles) Set msgInsts = objWMI.ExecQuery(“SELECT * FROM MSBTS_MessageInstance WHERE ServiceInstanceID = ‘” & ServiceInstanceID & “‘”) For Each msgInst In msgInsts msgInst.SaveToFile strInstanceFiles Next SendEmail strInstanceFiles, strOrcName, ServiceInstanceID, strEmailAdresses,ActivationTime End If IfbTerminateInstancesAndDeleteDir = True Then SendEmail strInstanceFiles, strOrcName, ServiceInstanceID, strEmailAdresses,ActivationTime objFSO.DeleteFolder(strInstanceFiles) End If End Function
This ‘SendEmail’ function will construct an email message based on all previously queried values. It takes the name of the orchestration, the files itself, the serviceinstanceID, the activationtime and the email adressees into account. I’ll just let the code speak for itself here:
Function SendEmail (strInstanceFiles, strOrcName, ServiceInstanceID, strEmailAdresses,ActivationTime) DimobjShell,objEnv,objMessage,objFSO,objFiles,objFile,objDatetime Set objShell = CreateObject(“WScript.Shell”) Set objEnv = objShell.Environment(“Process”) Set objMessage = CreateObject(“CDO.Message”) Set objFSO = CreateObject(“Scripting.FileSystemObject”) Set objDatetime = CreateObject(“WbemScripting.SWbemDateTime”) objDatetime.Value = ActivationTime objMessage.From = “BizTalk.” & objEnv(“BTS_ENVIRONMENT”) & “@YourCompany.com” objMessage.To = strEmailAdresses objMessage.Cc = strEmailAdressesCC objMessage.Subject = strSubject & strOrcName objMessage.Textbody = vbCrLf & “An instance of “& strOrcName & strBody _ & “- Orchestration Name: “ & strOrcName & vbCrLf _ & “- Service Instance ID: “ & ServiceInstanceID & vbCrLf _ & “- Activation Time: “ & objDatetime.GetVarDate & vbCrLf objMessage.Configuration.Fields.Item(“http://schemas.microsoft.com/cdo/configuration/sendusing”) = 2 objMessage.Configuration.Fields.Item(“http://schemas.microsoft.com/cdo/configuration/smtpauthenticate”) = 2 objMessage.Configuration.Fields.Item(“http://schemas.microsoft.com/cdo/configuration/smtpserver”) = objEnv(“BTS_SMTP_HOST”) objMessage.Configuration.Fields.Item(“http://schemas.microsoft.com/cdo/configuration/smtpserverport”) = 25 objMessage.Configuration.Fields.Update Set objFiles = objFSO.GetFolder(strInstanceFiles).Files For Each objFile inobjFiles objMessage.AddAttachment objFile.Path Next objMessage.Send Set objShell = Nothing Set objEnv = Nothing Set objMessage = Nothing Set objFSO = Nothing Set objFiles = Nothing Set objDatetime = Nothing End Function
The script ends with a little cleanup function. This will remove all the ’empty’ generated folders on disk, so that no overhead of folders is created on the server running the script. If no instances for the servicename can be found, it will remove the folder which exists for this specific servicename.
‘======================================================== ‘ Function ProcessDirectoriesForNonexistentServiceInstances ‘======================================================== FunctionProcessDirectoriesForNonexistentServiceInstances () DimobjFSO,objDirs,objDir,objInstID,objWMI,svcInsts Set objFSO = CreateObject(“Scripting.FileSystemObject”) Set objWMI = GetObject(“winmgmts:rootMicrosoftBizTalkServer”) Set objDirs = objFSO.GetFolder(strBaseTempFilesDir).subFolders For Each objDir inobjDirs For Each objInstID inobjDir.subFolders SetsvcInsts = objWMI.ExecQuery(“SELECT * FROM MSBTS_ServiceInstance WHERE ServiceName = ‘” & objDir.Name & “‘ AND InstanceID = ‘” & objInstID.Name & “‘”) IfsvcInsts.Count = 0 Then objInstID.Delete End If SetsvcInsts = Nothing Next Next Set objWMI = Nothing Set objFSO = Nothing End Function ‘======================================================== Wscript.Quit
There, we’re through. There is one last post following, handling suspended instances. This last one will maybe be most of use, since it will alert users when an instance is suspended in the BizTalk environment.
Thanks for reading, if you have any remarks or questions, please leave them in the comments section!
Andrew De Bruyne