Welcome back to this series of articles about monitoring your BizTalk environment using PowerShell that already has several previous editions:
- Monitor your BizTalk environment using PowerShell – Disk Space Monitoring
- Monitor your BizTalk environment using PowerShell – SQL Agent Jobs Monitoring
- BizTalk DevOps: Monitor your BizTalk environment using PowerShell – SQL Agent Jobs Monitoring (Part 2)
- BizTalk DevOps: Monitor your BizTalk environment using PowerShell – Manage messages being archived locally into the hard drive
- BizTalk DevOps: Monitor your BizTalk environment using PowerShell – Event Viewer BizTalk related Errors
- BizTalk DevOps: Monitor your BizTalk environment using PowerShell – Manage messages being archived locally into the hard drive
One of the main responsibilities of BizTalk Server administrators is to monitor the health of BizTalk environments and respond quickly to potential issues. Administrators typically achieve this by using tools such as the BizTalk Administration Console, BizTalk360, SCOM, and others. However, in many scenarios, these tools are not available, yet administrators still need to perform effective monitoring.
In this article, I revisit a topic previously covered by Jeroen, How to monitor suspended instances in BizTalk Server using PowerShell. This time, I extend the original approach by adding auto‑healing capabilities to the script.
Many things can go wrong in a BizTalk environment, and the longer issues remain unresolved, the greater the impact on the business. For that reason, we should not limit ourselves to simple notifications that always require manual intervention. Instead, whenever possible, we should also attempt to automatically recover affected artifacts, bringing them back to their desired state—whether that means running, resumed, or enabled.
📝 One-Minute Brief
Stop manually resuming failed messages in the BizTalk Administration Console. This guide provides a robust PowerShell script to monitor suspended service instances and introduces “auto-healing” logic. By setting a specific time window, the script automatically attempts to resume instances, reducing downtime and administrative overhead while keeping your team informed via automated email reports.
So how can PowerShell help us?
With this script, you can monitor your BizTalk environment for a suspended service instance and automatically resume it according to certain conditions, using PowerShell.
Only if the script finds any suspended messages will a mail notification 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 = "biztalksupport@mail.pt"
[array]$EmailTo = ("sandro.pereira@devscope.net")
- 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 the instance start time will the instance 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))
{
$msgSuspended.InvokeMethod("Resume",$null)
$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:

Note: This type of script must be viewed as a complement to the tools mentioned above or used in the absence of them.
Download
THIS POWERSHELL IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND.
Hope you find this helpful! If you liked the content or found it useful and would like to support me in writing more, consider buying (or helping to buy) a Star Wars Lego set for my son.
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.
Thanks,
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!
Hi Sandro. When run Script generat following Message:
Missing closing ‘}’ in statement block or type definition.
+ CategoryInfo : ParserError: (:) [], ParentContainsErrorRecordException
+ FullyQualifiedErrorId : MissingEndCurlyBrace