BizTalk DevOps: Monitor your BizTalk environment using PowerShell –Monitoring Suspended Service Instances with Auto-Healing capabilities

Welcome back to this series of articles about Monitor your BizTalk environment using PowerShell that already have several previous editions:

One of the principal needs for BizTalk Server Administrators is the ability to monitor the health of BizTalk environments and react promptly to possible problems, you can accomplish this by using certain tools such as BizTalk Administration Console; BizTalk360; SCOM, and much more… However, unfortunately, many times some of these tools are not available for us but we still need to accomplish this task.

Today we will talk about a topic that was previously covered by Jeroen: “How to monitor Suspended instance in BizTalk Server using PowerShell”, but this time, I will also add Auto Healing functionalities to the script.

There are a bunch of things that can go wrong and the longer they have in an error/failure situation, the more impact could have on your business! So, we don’t just want to be notified of failures (that will always lead to a manual human intervention) but instead, when possible, be also able to try to automatically fix it, bringing them to the desired state (running, resumed, enable – depending on the artifact)

So how can PowerShell help us?

With this script, you can be able to monitor your BizTalk environment for a suspended service instance, and automatically resume then according to certain conditions, using PowerShell.

Only if the script finds any suspended messages a mail notification will be sent.

This script allows you to set:

  • Set your email notification settings
 Set mail variables
 [STRING]$PSEmailServer = "mySMTPServer" #SMTP Server.
 [STRING]$SubjectPrefix = "Suspended Messages - "
 [STRING]$From = ""
 [array]$EmailTo = ("")
  • The Service Instances desired states to monitor
 Get suspended messages
 [ARRAY]$suspendedMessages = get-wmiobject MSBTS_ServiceInstance -namespace 'root\MicrosoftBizTalkServer' -filter '(ServiceStatus = 4 or ServiceStatus = 16 or ServiceStatus = 32 or ServiceStatus = 64)'
  • The number of hours that the script can try to automatically resume suspended messages. Only if the (Current Date – Automatic Resume hours) is less than Instance start time, the instance will be automatically resumed.
 This variable sets the amount of hours a suspended message can be resumed automatically
 [INT]$AutomaticResume = 8

Main monitoring script:

foreach ($msgSuspended in $suspendedMessages)
    $msg = $bo.GetServiceInstance($msgSuspended.InstanceID)

    #Add mail content
    $mailBodySM += "<th>Message Instance ID: <b><font color='blue'>" + $msgSuspended.InstanceID + "</font></b></th>"
    $mailBodySM += "<table style='boder:0px 0px 0px 0px;'>"

    $mailBodySM += "<TR style='background-color:white;'><TD>Application</TD>"
    $mailBodySM += "<TD>" + $msg.Application + "</TD></TR>"

    $mailBodySM += "<TR style='background-color:rgb(245,245,245);';><TD>Service Name</TD>"
    $mailBodySM += "<TD><b><font color='red'>" + $msgSuspended.ServiceName + "</font></b></TD></TR>"

    $mailBodySM += "<TR style='background-color:white;'><TD>Class</TD>"
    $mailBodySM += "<TD>" + $msg.Class + "</TD></TR>"

    $mailBodySM += "<TR style='background-color:rgb(245,245,245);';><TD>Assembly Name</TD>"
    $mailBodySM += "<TD>" + $msgSuspended.AssemblyName + ", Version=" + $msgSuspended.AssemblyVersion + ", Culture=" + $msgSuspended.AssemblyCulture +", PublicKeyToken=" + $msgSuspended.AssemblyPublicKeyToken + "</TD></TR>"

    $spActivationTime= [datetime]::ParseExact($msgSuspended.ActivationTime.Substring(0,14),'yyyyMMddHHmmss',[Globalization.CultureInfo]::InvariantCulture )
    $mailBodySM += "<TR style='background-color:white;'><TD>Activation Time</TD>"
    $mailBodySM += "<TD>" + $spActivationTime.ToString("dd-MM-yyyy HH:mm:ss") + "</TD></TR>"

    $myDate= [datetime]::ParseExact($msgSuspended.SuspendTime.Substring(0,14),'yyyyMMddHHmmss',[Globalization.CultureInfo]::InvariantCulture )
    $mailBodySM += "<TR style='background-color:rgb(245,245,245);';><TD>Suspend Time</TD>"
    $mailBodySM += "<TD>" + $myDate.ToString("dd-MM-yyyy HH:mm:ss") + "</TD></TR>"

    #ServiceStatus = 1 - Ready To Run
    #ServiceStatus = 2 - Active
    #ServiceStatus = 4 - Suspended (Resumable)
    #ServiceStatus = 8 - Dehydrated
    #ServiceStatus = 16 - Completed With Discarded Messages' in BizTalk Server 2004
    #ServiceStatus = 32 - Suspended (Not Resumable) 
    #ServiceStatus = 64 - In Breakpoint 
    $statusMsg = ""
    if ($msgSuspended.ServiceStatus -eq 4)
        $statusMsg = "Suspended (Resumable)" 
    if ($msgSuspended.ServiceStatus -eq 16)
        $statusMsg = "Completed With Discarded Messages" 
    if ($msgSuspended.ServiceStatus -eq 32)
        $statusMsg = "Suspended (Not Resumable)" 
    if ($msgSuspended.ServiceStatus -eq 64)
        $statusMsg = "In Breakpoint" 

    $mailBodySM += "<TR style='background-color:white;'><TD>Service Name</TD>"
    $mailBodySM += "<TD><b><font color='red'>" + $statusMsg + "</font></b></TD></TR>"
    $mailBodySM += "<TR style='background-color:rgb(245,245,245);';><TD>HostName</TD>"
    $mailBodySM += "<TD>" + $msgSuspended.HostName + " (" + $msgSuspended.PSComputerName + ")</TD></TR>"

    $mailBodySM += "<TR style='background-color:white;'><TD>Error Code</TD>"
    $mailBodySM += "<TD>" + $msgSuspended.ErrorId + "</TD></TR>"

    $mailBodySM += "<TR style='background-color:rgb(245,245,245);';><TD>Error Description</TD>"
    $mailBodySM += "<TD>" + $msgSuspended.ErrorDescription + "</TD></TR>"

    $mailBodySM += "<TR style='background-color:white;'><TD>Error Category</TD>"
    $mailBodySM += "<TD>" + $msgSuspended.ErrorCategory + "</TD></TR>"

    $mailBodySM += "<TR style='background-color:rgb(245,245,245);';><TD>In Breakpoint</TD>"
    $mailBodySM += "<TD>" + $msg.InBreakpoint + "</TD></TR>"

    $mailBodySM += "<TR style='background-color:white;'><TD>Pending Operation</TD>"
    $mailBodySM += "<TD>" + $msg.PendingOperation + "</TD></TR>"

    If (($spActivationTime -ge $currentdateSI.AddHours(-$AutomaticResume)) -and ($msg.Class -like "Orchestration") -and ($msgSuspended.ServiceStatus -eq 4))

        $mailBodySM += "<TR style='background-color:rgb(245,245,245);';><TD><font color='green'>Note</font></TD>"
        $mailBodySM += "<TD><font color='green'>The suspended message was resumed automatically by this script! Please access the environment to check if the processes are running or completed.</font></TD></TR>"

    $mailBodySM += "</table>"
    $mailBodySM += "<BR><BR>"

Again, only if the script finds any suspended messages a mail notification will be sent.

Report sample:

BizTalk Suspended Instances Report

Note: This type of script must be viewed as a complement to the tools mentioned above or used in the absence of them.



Author: Sandro Pereira

Sandro Pereira lives in Portugal and works as a consultant at DevScope. In the past years, he has been working on implementing Integration scenarios both on-premises and cloud for various clients, each with different scenarios from a technical point of view, size, and criticality, using Microsoft Azure, Microsoft BizTalk Server and different technologies like AS2, EDI, RosettaNet, SAP, TIBCO etc. He is a regular blogger, international speaker, and technical reviewer of several BizTalk books all focused on Integration. He is also the author of the book “BizTalk Mapping Patterns & Best Practices”. He has been awarded MVP since 2011 for his contributions to the integration community.

3 thoughts on “BizTalk DevOps: Monitor your BizTalk environment using PowerShell –Monitoring Suspended Service Instances with Auto-Healing capabilities”

  1. This is an awesome script, but one query. How can we get non-resumable messages and how to save it and terminate it over the powershell script, can you help me in that.

  2. This solution is flawless! I barely ever have to update anything but the SMTP details, the To and From emails and that’s it. Thank you very much for this solution!

    1. Hi Sandro. When run Script generat following Message:

      Missing closing ‘}’ in statement block or type definition.
      + CategoryInfo : ParserError: (:) [], ParentContainsErrorRecordException
      + FullyQualifiedErrorId : MissingEndCurlyBrace

Leave a Reply

Your email address will not be published. Required fields are marked *


Back to Top