Powershell script to administer messages in BizTalk

The below script does everything from resume to terminate the suspended messages. It also allows you to get counts and save suspended messages into dedicated folders.

# Script to save, resume and list suspended messages. To be used by BizTalk admin ONLY!
# Created on 30/01/2014 by Dipesh A.
# Commands:
   # Note: CD to script path first.

    # To get count of all suspended messages
    # PS > .\GetSuspended.ps1 -action counts

    # To list all suspended messages
    # PS > .\GetSuspended.ps1 -action list

    # To save all suspended messages
    # PS> .\GetSuspended.ps1 -action save -path 'X:\[Path]'

    # To resume resumable suspended messages
    # PS> .\GetSuspended.ps1 -action resume

    # To terminate non-resumable suspended messages
    # PS> .\GetSuspended.ps1 -action terminate

# -----------------------------------------------------------------

# declare params: 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' })
)

#
# get all suspended messaging service instances,
# both resumable and not-resumable
#
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, $homepath)
{

    #save each message within respective folders.

    "msgid is $msgid"
    "ServiceName is $sname"
    "msg_counter is $counter"
    $msg = get-wmiobject MSBTS_MessageInstance `
    -namespace 'root\MicrosoftBizTalkServer' `
    -filter "ServiceInstanceID = '$msgid'"

    $newpath = (Join-Path $homepath $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"
    }

    foreach($m in $msg)
    {
       $m.psbase.invokemethod('SaveToFile', ($newpath))
       "Message from ServiceInstanceID=$msgid saved to $newpath."
   }

}

#
# save the message associated to the
# specified messaging Service Instance
#
function bts-save-message1([string]$msgid)
{

    $msg = get-wmiobject MSBTS_MessageInstance `
    -namespace 'root\MicrosoftBizTalkServer' `
    -filter "ServiceInstanceID = '$msgid'"
    $msg.psbase.InvokeMethod('SaveToFile', ($path))
    "Message from ServiceInstanceID=$msgid saved."
}

#
# list resumable suspended instances
#
function bts-get-resumable-suspended()
{
    get-wmiobject MSBTS_ServiceInstance -namespace 'root\MicrosoftBizTalkServer' -filter 'ServiceStatus=4'
}

#
# list resumable suspended instances
#
function bts-get-nonresumable-suspended()
{
    get-wmiobject MSBTS_ServiceInstance -namespace 'root\MicrosoftBizTalkServer' -filter 'ServiceStatus=32'
}

#
# resume instance
#
function bts-resume-instance([string]$msgId)
{
    if(!($msgId -eq “”))
    {
       "Resume {0}" -f $msgId
       $msg = get-wmiobject MSBTS_ServiceInstance -namespace 'root\MicrosoftBizTalkServer' -filter “InstanceID = '$msgId'”
       $msg.Resume() | Out-Null
    "- Done"
    }
    else
    {
       "MessageId missing"
    }
}

#
# terminate non resumable instance
#
function bts-terminate-instance([string]$msgId)
{
    if(!($msgId -eq “”))
    {
       "Terminate {0}" -f $msgId
       $msg = get-wmiobject MSBTS_ServiceInstance -namespace 'root\MicrosoftBizTalkServer' -filter “InstanceID = '$msgId'”
       $msg.Terminate() | Out-Null
       "- Done"
   }
   else
    {
       "MessageId missing"
   }
}

#
# main script
#
switch ( $action )
{
    'counts' {
       bts-get-messaging-svc-instances |
       %{ $counter++; }

       "Total: $counter"

       $counterrr = 0
       bts-get-resumable-suspended | %{ $counterrr++; }

       "Resumable: $counterrr"

       $counternr = 0
       bts-get-nonresumable-suspended | %{ $counternr++; }

       "Non resumable: $counternr"
    }

   'list' {
        bts-get-messaging-svc-instances |
       fl InstanceId, ServiceName, SuspendTime, HostName,
       ServiceStatus, ErrorId, ErrorDescription
    }
    'save'
    {

       #Set home path
       $timestamp = Get-Date -UFormat "%Y%m%d%H%M%S"
       $newpath = (Join-Path $path $timestamp)
       "Home path is $newpath"

       $r_code= (test-path $newpath)
       "return code is $r_code"

       if ($r_code -eq $False)
       {
          md $newpath
          "new directory created"
       }

        #save summary
       $wmi = get-wmiobject MSBTS_ServiceInstance `
       -namespace 'root\MicrosoftBizTalkServer' `
       -filter '(ServiceClass=1 or ServiceClass=4) and ServiceStatus = 4' | out-string

       $file = New-Item -Type File -Name "Summary.txt" -Path $newpath
       Add-Content $file -Value $wmi

       bts-get-messaging-svc-instances |
       %{ $counter++; bts-save-message $_.InstanceID $_.ServiceName $newpath }

    }
    'resume'
    {
      bts-get-resumable-suspended | %{ bts-resume-instance($_.InstanceID) }
    }
    'terminate'
    {
      bts-get-nonresumable-suspended | %{ bts-terminate-instance($_.InstanceID) }
    }
}

Advertisements

Determining Process IDs of multiple BizTalk Host Instances

For debugging, it is neccessary to attach the BizTalk host instance process to Visual Studio. However, if you have multple host instances, you cant tell which one is which.

I have found a PS script which gives you the process Ids of multiple host instances.
32Bit Hosts:
TASKLIST /FI “USERNAME ne NT AUTHORITYSYSTEM” /FI “IMAGENAME eq BTSNTSvc.exe” /SVC

64Bit Hosts:
TASKLIST /FI “USERNAME ne NT AUTHORITYSYSTEM” /FI “IMAGENAME eq BTSNTSvc64.exe” /SVC

BizTalk 2010 Certification Guide

If you are looking at getting BT 2010 certified, there is just the book out there that you will need to prepare for the exam 70-595. Authors include Johan Hedberg, Kent Weare & Morten La Cour. The book covers everything from BizTalk basics to WCF to RFID to BAM. Having said that, the book is to the point and compact enough to get you scoring soon!

Get a copy here:

http://www.packtpub.com/mcts-microsoft-biztalk-server-2010-certification-guide/book

Cheers!

Retry pattern and Suspend shape – the gotchas!

I have just come out a frustration moment with BizTalk where it was behaving differently when compared to a similar environment. I have a retry pattern in one of my orchestrations and a suspend shape within the catch block. See screenshot below:

One would hope that when the administrator resubmits the suspended message, it would continue from the point it left of (that is continue in the loop). However, what I saw was, the orchestration would go into the “active” state indefinately.  Also, when trying to terminate this active instance, the terminate job would show as pending and the service wouldnt terminate unless the host was restarted.

Further investigation revealed that the suspended orchestration has no related message (or context). See screenshot below.

To eliminate any false positives, I deployed the same app on our test environment and saw that there was a message linked to the suspended orchestration.

This is where I was stumped!

After hours of pondering, I thought of the famous MBV! I ran some analysis via the MBV and I found this in the report:

The value “Missing Restart Msg in the Spool table…” was the light at the end of the tunnel. I quickly ran the Terminator tool to clean the messagebox.

Once done, I ran the MBV analysis again and all critical warnings were gone in relation to “Control Messages”.

I then tried my test again and saw the messages were now linked to suspended orchestrations….

On resubmitting, I would see the message continue from where it left off…

Hope this helps someone having similar issues.

WCF-SQL Adapter and permissions

If you are using a WCF SQL adapter in your solution, it is imperitive to set permissions on the stored procedures you call from within BizTalk. However, if you havent set permissions, the error message can be a little misleading.

The adapter failed to transmit message going to send port “WcfSendPort_SqlAdapterBinding_TypedProcedures_MyDB” with URL “mssql://MYSRVSQ01//MyDB?”. It will be retransmitted after the retry interval specified for this Send Port. Details:”Microsoft.ServiceModel.Channels.Common.MetadataException: Object [dbo].[uspInsertRecords] of type StoredProcedure does not exist

The above message can be quite confusing especially when the stored procedure does exist in your database. The above basically means the BT host account does not have execute permissions on the stored procedure being called. You need to restart the BT host instance after setting permissions.

Now, lets see what happens when I have a working solution (my permissions are set) and I revoke the execute permission on the same stored proc (remember, I havent restarted the BT host after revoking the permission). I now see this error message:

The adapter failed to transmit message going to send port “WcfSendPort_SqlAdapterBinding_TypedProcedures_MyDB” with URL “mssql://MYSRVSQ01//MyDB?”. It will be retransmitted after the retry interval specified for this Send Port. Details:”System.Data.SqlClient.SqlException: The EXECUTE permission was denied on the object ‘uspInsertRecords’, database ‘MyDB’, schema ‘dbo’.

This seems to be a much more clear message, isint it? However, if you restart the BT host and try processing your file again, you will see the first error.

BizTalk with ReST

There is a great article posted by Microsoft which explains how BizTalk can be configured to call a ReST service. You can find it here.

Althought this article is based on BizTalk 2010 (.net 4.0), I have tested this with BizTalk 2009 (.net 3.5) and it works.

Check it out!

BizTalk – Overlapped I/O operation is in progress

While configuring BizTalk features (BAM Tools or Sharepoint Adapter), you may have issues getting the cofiguration process to succeed with the error below:

“Overlapped I/O operation is in progress”

Certain blogs suggest that registry changes be made to force it to work. This is a bit risky once it comes to prod environments. The best approach to fix such issues is to repair the BizTalk installation and try configuring BizTalk again.