Tallan's Technology Blog

Tallan's Top Technologists Share Their Thoughts on Today's Technology Challenges

Saving BizTalk Suspended Messages in Bulk using WMI

Kevin Morillo

BizTalk is great in its ability to store messages within the MessageBox even after processing failure, however its not always so easy to get those messages back out!   I recently had a need to retrieve all messages that were currently suspended due to validation failures while attempting to generate X12 EDI messages using the Microsoft.Practices.ESB.

The solution is to use Windows Management Instrumentation (WMI) which can be used within PowerShell or C# to interface directly with BizTalk and easily perform administrative tasks programmatically.  For this scenario we will use C#.

The first step is to create a new console application and open up Server Explorer.

Next, right click on ‘Management Classes’ and select ‘Add Classes…’

image

Next add MSBTS_HostInstanceSetting, and MSBTS_MessageInstance

image

After the two WMI classes are added, we have to select them within Server Explorer\Servers\Management Classes\ and select ‘Generate Managed Class’ for both HostInstance and MessageInstance

image

This will create both classes within your solution

image

Below is my sample code that will first retrieve all suspended instances filtered on a specific message status.

ROOT.MICROSOFTBIZTALKSERVER.ServiceInstance.ServiceInstanceCollection instanceCollection =
ROOT.MICROSOFTBIZTALKSERVER.ServiceInstance.GetInstances(String.Format(“ServiceStatus='{0}'”, 4));

The message statuses possible are

  • 1 – Ready to run
  • 2 – Active
  • 4 – Suspended (resumable)
  • 8 – Dehydrated
  • 16 = Zombies (completed with discarded messages)
  • 32 – Suspended (not resumable)
  • 64 – In Breakpoint

Next, we will start to iterate through each suspended instance in the collection

For each host instance, we will then extract and iterate over each instance message

ROOT.MICROSOFTBIZTALKSERVER.MessageInstance.MessageInstanceCollection messageCollection =
ROOT.MICROSOFTBIZTALKSERVER.MessageInstance.GetInstances(
String.Format(“ServiceInstanceID='{0}'”, instance.InstanceID));

Lastly, we will save each message to the file system.

message.SaveToFile(@”C:\temp\messages”);

Below is the full codebase:


 

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

using System.Threading.Tasks;

namespace ExtractSuspendedMessages

{

classProgram

{

// sample arguments: ExtractSuspendedMessages “C:\temp\suspendedmsessages” false

staticvoid Main(string[] args)

{

if (args.Length != 2)

Console.WriteLine(“Require 2 inputs.”);

else

ExtractAllMessages(args[0], Convert.ToBoolean(args[1]));

}

privatestaticvoid ExtractAllMessages(string folderLoc, bool terminateInstancesAfterSaving = false)

{

System.IO.Directory.CreateDirectory(folderLoc);

// Use integer to filter for specific suspended service statuses

//1 – Ready to run

//2 – Active

//4 – Suspended (resumable)

//8 – Dehydrated

//16 = Zombies (completed with discarded messages)

//32 – Suspended  (not resumable)

//64 – In Breakpoint

ROOT.MICROSOFTBIZTALKSERVER.ServiceInstance.ServiceInstanceCollection instanceCollection =

ROOT.MICROSOFTBIZTALKSERVER.ServiceInstance.GetInstances(String.Format(“ServiceStatus='{0}'”, 4));

//Loop through each service instance

foreach (ROOT.MICROSOFTBIZTALKSERVER.ServiceInstance instance in instanceCollection)

{

Console.WriteLine(String.Format(“Saving suspended messages for GUID: {0} with error: {1} to folder {2}”,

instance.InstanceID, instance.ErrorDescription, folderLoc));

ROOT.MICROSOFTBIZTALKSERVER.MessageInstance.MessageInstanceCollection messageCollection =

ROOT.MICROSOFTBIZTALKSERVER.MessageInstance.GetInstances(

String.Format(“ServiceInstanceID='{0}'”, instance.InstanceID));

//Loop through each message

foreach (ROOT.MICROSOFTBIZTALKSERVER.MessageInstance message in messageCollection)

{

Console.WriteLine(String.Format(“Saving Message with ID: {0}”, message.MessageInstanceID));

try

{

message.SaveToFile(folderLoc);

}

catch (Exception) { }

}

if (terminateInstancesAfterSaving)

instance.Terminate();

}

}

}

}


 

Running the console application with input variables “C:\temp\messages” and false

Capture

1 Comment. Leave new

Thanks a lot for this post, it was very helpful! One remark though, one needs to generate the managed class for serviceInstances instead of hostInstances. Which is done correctly in the code and image, but the text mentions something different.

Leave a Reply

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

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

\\\