Saving Suspended Messages using WMI, PowerShell and the Microsoft.BizTalk.Operations Assembly (Part I)

Often, there’s a need to save out suspended messages out to a file, so that we can resubmit/inspect them later. From the BizTalk Admin Console, we can right-click the suspended service instance -> Show Messages. When the messages associated with that service instance opens up, we can right-click -> Save to File. However, for hundreds (possibly thousands) of suspended instances, this is not possible.

One of the options of doing this is using the wonderful BizTalk Terminator Tool (https://www.microsoft.com/en-us/download/details.aspx?id=2846). If you’re okay terminating these instances, you can use this to save out the suspended messages, before terminating the suspended service instances. The only drawback to this approach is that you have no option but to terminate the instances. [After you click Connect on the first Terminator window, you need to click the Delete button at the bottom, and then select the ‘Terminate Instances’ option to get to this screen]. 

 

What if you wanted to retain the suspended instances, and yet save the messages out to disk?
Well, time to write some WMI code. We chose to use a PowerShell script in this case. We could easily have called the same WMI queries using VBScript or, C#. So, here is the code -
[Original code courtesy - Tomas Restrepo's blog : https://winterdom.com/2006/09/btssuspendedmessaginginstanceswithpowershell]

#
# Use:
# C:\.\Save_Suspended_msgs.ps1 -action list
# C:\.\Save_Suspended_msgs.ps1 -action save
"c:\temp\Suspended_msgs" ([optional]> log.file) 

#
# declare our parameters: the action to take, and an optional
# path to save messages to
#
param(
   [string] $action=$(throw 'need action'),
   [string] $path=$(if ($action -eq 'save') { throw 'need path' })
)
$counter = 0 

function bts-get-messaging-svc-instances()
{
   get-wmiobject MSBTS_ServiceInstance `
      -namespace 'root\MicrosoftBizTalkServer'
      -filter '(ServiceClass=1 or ServiceClass=4) and ServiceStatus = 4 '

#

# save the message associated to the
# specified messaging Service Instance
#
function
bts-save-message([string]$msgid, [string]$sname)
{
   "msgid is $msgid"
   "ServiceName is $sname"
   "msg_counter is $counter"
   $msg = get-wmiobject MSBTS_MessageInstance `
      -namespace 'root\MicrosoftBizTalkServer'
      -filter "ServiceInstanceID = '$msgid'"
      $newpath = (Join-Path $path $sname)
     "new path is $newpath"
     $r_code= (test-path $newpath)
     "return code is $r_code"
     if ($r_code -eq $False)
     {
         md $newpath
        "new directory created"
     }
       if ($msg.psbase.length -gt 0)     
       {
        foreach($m in $msg)
                     {           
$m.psbase.invokemethod('SaveToFile', ($newpath))
             "Message from ServiceInstanceID=$msgid saved to $newpath."
                     }
       }

#
# main script
#
switch ( $action )
{
   'list' {
# bts-get-messaging-svc-instances   
      bts-get-messaging-svc-instances |
      bts-get-messaging-svc-instances |
         fl * 

# fl InstanceId, ServiceName, SuspendTime,HostName,
# ServiceStatus, ServiceClass, ErrorId, ErrorDescription
   }
   'save' {
      bts-get-messaging-svc-instances |
          %{ $counter++; bts-save-message $_.InstanceID $_.ServiceName }     

   }
}

In the bts-get-messaging-svc-instances() function, we have –
get-wmiobject MSBTS_ServiceInstance `  

-namespace 'root\MicrosoftBizTalkServer' `
-filter '(ServiceClass=1 or ServiceClass=4) and ServiceStatus = 4 '

 

We are filtering on Service instances with ‘ServiceClass = 1’ (this gets Orchestration suspended instances) or, ‘ServiceClass = 4’ (messaging service instances). ‘ServiceStatus = 4’ means Suspended (Resumable). These are the other Service Status codes, in case you need it:

//******** List of WMI Service Statuses ********

//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 

Usage : To use this script, save this to a file (say at the path - C:\script\Save_Suspended_msgs.ps1 ), and run this from the PowerShell command prompt:
PS C:\Users\Administrator> C:\script\Save_Suspended_msgs.ps1 -action save "c:\temp\Suspended_msgs"

 

This would create separate folders for each suspended instance type under the ‘Suspended_msgs’folder specified above. So, if you have suspended instances for two different Orchestration types, it would create folders named after those Orchestrations and save out the messages in their respective folders.
All good, right? Well, this solution works great as long as your suspended orchestration instances don’t contain multiple suspended messages. We cover in Part II of this article how to handle this specific case.

Written by
Arindam Paul Roy

Reviewed by
Jainath V R

Microsoft India GTSC

Comments

  • Anonymous
    July 23, 2013
    Can you please let me know if you have published the part 2 which discusses about saving messages when there are multiple messages (especially >50) in a single instance.
  • Anonymous
    July 25, 2013
    Srikanth, I will publish the 2nd Part of this article pretty soon (work has been hectic of late). Please check back early next week.Thanks.
  • Anonymous
    July 29, 2013
    Arindam,I work as a BizTalk Technical Application Administrator for more than 6 years. Besides saving messages, we often need certain information from (suspended) messages. For that purpose I developed BizTalk Message Decompressor which can be found on CodePlex. If you are interested, feel free to contact me via LinkedIn.
  • Anonymous
    July 16, 2014
    How do you use this with a remote server? TIA
  • Anonymous
    July 22, 2014
    The PowerShell looks to be a copy of the one provided by Tomas Restrepowinterdom.com/.../btssuspendedmessaginginstanceswithpowershell
  • Anonymous
    August 08, 2014
    Hi SteveWe get to work with many BizTalk customers - this script was the starting point for something that one of our customers had issues with, and now that I saw Tomas' blog - I agree, the customer was using his script.But, there were some issues with this script to begin with, which was fixed using a modified version here -blogs.msdn.com/.../saving-suspended-messages-using-wmi-powershell-and-the-microsoft-biztalk-operations-assembly-part-ii.aspx(the limitation with the original is mentioned in the above post as well).
  • Anonymous
    October 28, 2014
    Good post Thank you!
  • Anonymous
    October 29, 2014
    Thanks for the update and link to part 2