Archive for the ‘PowerShell’ Category

I just updated three of my useful BizTalk PowerShell scripts in some cases fixing some small bugs, improving performance and in other cases adding also new capabilities.

PowerShell to configure Default Dynamic Send Port Handlers for each Adapter: This is a simple script that allows you to configure the default send handlers associated with all the existing Dynamic Send ports in your environment

  • In this new release I fixed some small bugs in the code that were not allowing the script to work as expected.

Check more about the script here: BizTalk DevOps: How to configure Default Dynamic Send Port Handlers with PowerShell

The full script can be found and download on Microsoft TechNet Gallery:
PowerShell to configure Default Dynamic Send Port Handlers for each Adapter (3.0 KB)
Microsoft TechNet Gallery

 

PowerShell to Configure the Default Send Handler for each static Send Port: This is a simple script that allows you to configure the Send handler associated with all the existing Static Send Ports in your environment independently of the adapter that is configured.

  • In this new release I fixed some small inconsistencies in the code, nevertheless in this case the previous script was working fine.

Check more about the script here: BizTalk DevOps: Configure the Default Send Handler as the Send Handler for each existing static Send Ports with PowerShell

The full script can be found and download on Microsoft TechNet Gallery:
PowerShell to Configure the Default Send Handler for each static Send Port (3.0 KB)
Microsoft TechNet Gallery

 

Monitoring BizTalk Server Ports with Auto-Healing capabilities with PowerShell: This is a simple script that allows you to monitor your BizTalk environment for disabled receive locations and stopped or unenlisted send ports, and automatically resume then according to certain conditions, using PowerShell.

In this new release:

  • I improved the general performance of the script
  • And add a new feature to the script: the ability to save a copy of the monitor report in the hard drive or a shared folder.

Check more about the script here: BizTalk DevOps: Monitor your BizTalk environment using PowerShell –Monitoring Ports (Stopped/disabled/unelisted) with Auto-Healing capabilities

The script can be found and download on Microsoft TechNet Gallery:
Monitoring BizTalk Server Ports with Auto-Healing capabilities with PowerShell (14.0 KB)
Microsoft TechNet Gallery

 

So, why these script are important?

All of these task can be easily made manually but they are time consuming tasks, special the monitor task if you don’t have the proper monitor tools like BizTalk360 or other tools available in the market. These PowerShell scripts allows you to automate and streamline these tasks saving us a considerable amount of time.

THESE POWERSHELL ARE PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND.

We cannot rely on documentation, if they exist, to be accurate, special regarding to the status of the machines present in the environment – I never found this kind of document that tell me what is installed on the machine, what are the updates (or CU) or service pack installed and so on… and regarding to BizTalk Server I do not remember another simple task like this, get or check the list of all BizTalk Cumulative Updates installed in your machine/environment, being so painful to perform!

Of course, there are some ways to check that, for example:

  • you can do it manually by checking “Control Panel\Programs\Programs and Features” and then view the “Installed Updates”, however, this can be a very annoying task and sometimes time consuming just to try find them in that huge list because they are not organized in a category BizTalk

BizTalk-CU1-In-RosettaNet-Category

BizTalk-CU2-and-3-In-UDDI-Category

  • you can use BizTalk MsgBoxViewer but still if you only want to check what CU are installed, or you need to analyze your entire system with this tool, or you need to uncheck all the select default queries and check only for the cumulative updates – which can also be an annoying and time consuming task

Check-BizTalk-CU-with-MsgBoxViewer

Check-BizTalk-CU-with-MsgBoxViewer-result

Probably there are other ways, nevertheless, I just want a quick and very easy way, because this is a basic and very simple task, to know what are the BizTalk Cumulative Updates installed likeConfused smile

This is the list of BizTalk Cumulative Update installed in this machine: BTS2013R2LAB01
- Microsoft BizTalk Server 2013 R2 CU1
- Microsoft BizTalk Server 2013 R2 CU2
- Microsoft BizTalk Server 2013 R2 CU3

This way I know that I need to install the last CU available: “Microsoft BizTalk Server 2013 R2 CU4”. Yehhh!

PowerShell script overview

So how can we easily automate tasks? and reuse them whenever necessary and at the same time saving significant time for other tasks?

Using PowerShell is a good option. Windows PowerShell is a Windows command-line shell designed especially for system administrators and can be used by BizTalk administrators to help them in automating repetitive tasks or tasks that are time consuming to perform manually.

This is a simple script that allows you to configure the template name of the cumulative updates, that will change from version to version, and will give you the list of all cumulative updates installed in your machine:

$keyResults = Get-ChildItem -path HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\ -Recurse -ErrorAction SilentlyContinue | where { $_.Name -match $CUNameTemplate}

foreach($keyItem in $keyResults)
{
    if ($keyItem.GetValue("DisplayName") -like "*$CUNameTemplate*")
    {
        write-host "-" $keyItem.GetValue("DisplayName").ToString().Substring(0,$keyItem.GetValue("DisplayName").ToString().IndexOf(" CU")+4)
    }
}

THIS SQL SCRIPT IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND.

After install the CU4 in my machine the result was what I was expecting:

This is the list of BizTalk Cumulative Update installed in this machine: BTS2013R2LAB01
- Microsoft BizTalk Server 2013 R2 CU1
- Microsoft BizTalk Server 2013 R2 CU2
- Microsoft BizTalk Server 2013 R2 CU3
- Microsoft BizTalk Server 2013 R2 CU4

You can download the PowerShell Script used here from:

Check all BizTalk Cumulative Updates installed in server with PowerShell (2 KB)
Microsoft | TechNet Gallery

In the previous post I provide a fix to the PowerShell script to that is able to configure the Deployment Properties of a BizTalk project, keeping my word, at least half of it, because I also found the same problems in the PowerShell script to fix or configure the Signing Properties of a BizTalk Project, i.e., it only worked if the signing properties already existed in the file(s) (.btproj). This means that:

  • if we obtain a copy of the project from the source control that have already have these properties defined, it will work otherwise the script was unable to properly set these properties.
  • if we were working on a new project then definitely the script didn’t set up the signing properties.

Again, I promised that I would fix it and now I’m keeping the rest of my word. Along with the previous, this is probably one of scripts that I use the most and the reason why is…

So, why this script is important?

Again, and this is nothing new, before deploying a BizTalk project we must first strongly sigh the assemblies involved in the project to give them a unique identification for allowing them to be installed into the GAC.

GAC (Global Assembly Cache) is a machine code cache that stores assemblies that can be shared by multiple applications on the computer. This assemblies needs to be strongly signed so that they can have a unique identification in the GAC.

A strong-named assembly provides several security benefits:

  • A strong name guarantees the uniqueness of the assembly by assigning a digital signature and a unique key pair.
  • A strong name protects the lineage of the assembly by ensuring that no one else can generate a subsequent version of the assembly.
  • A strong name provides a strong integrity check to guarantee that the contents of the assembly have not changed since the last build.

In the process of deploying a BizTalk solution, Visual Studio first builds the assemblies. The deployment process requires that each assembly is strongly signed. You can strongly sign your assemblies by associating each project in the solution with a strong name assembly key file. That is an easy and rapid task (non-time consuming task). However, if a solution in Visual Studio contains multiple projects, you must separately configure properties for each project.

This seems a slight and easy task but now imagine that you have almost 200 projects inside a unique Visual Studio Solution! It will be an insane operation and the most likely to happen is you to fall asleep in front of the pc… once again.

With this PowerShell you will be able to parameterize all projects inside a Visual Studio Solution running a single line of code and avoid spending numerous hours doing this task manually.

PowerShell script overview
    $allPropertyGroup = $xml.Project.PropertyGroup
    foreach($node in $allPropertyGroup)
    {
        if($node.AssemblyOriginatorKeyFile -ne $null)
        {
            $addNewKeyNodeFlag = $false;
            $node.AssemblyOriginatorKeyFile= $keyName;
        }

        if($node.SignAssembly -ne $null)
        {
            $addNewSignNodeFlag = $false;
            $node.SignAssembly= $true;
        }
    }

    if($addNewKeyNodeFlag -eq $true)
    {
        $childItemGroup = $xml.CreateElement("PropertyGroup",$xdNS)
        $childNone = $xml.CreateElement("AssemblyOriginatorKeyFile",$xdNS)
        $childNone.AppendChild($xml.CreateTextNode($keyName));
        $childItemGroup.AppendChild($childNone)
        $xml.Project.InsertBefore($childItemGroup, $xml.Project.ItemGroup[0])
    }

    if($addNewSignNodeFlag -eq $true)
    {
        $childItemGroup = $xml.CreateElement("PropertyGroup",$xdNS)
        $childNone = $xml.CreateElement("SignAssembly",$xdNS)
        $childNone.AppendChild($xml.CreateTextNode($true));
        $childItemGroup.AppendChild($childNone)
        $xml.Project.InsertBefore($childItemGroup, $xml.Project.ItemGroup[0])
    }

    $allItemGroup = $xml.Project.ItemGroup.None;
    foreach($node in $allItemGroup)
    {
        if($node.Include -eq $keyName)
        {
            $addKeyToSolutionFlag = $false;
        }
    }

    if($addKeyToSolutionFlag -eq $true)
    {
        $childItemGroup = $xml.CreateElement("ItemGroup",$xdNS)
        $childNone = $xml.CreateElement("None",$xdNS)
        $childNone.SetAttribute("Include", $keyName)
        $childItemGroup.AppendChild($childNone)
        $xml.Project.InsertBefore($childItemGroup, $xml.Project.Import[0])
    }
THIS SQL SCRIPT IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND.

You can download the PowerShell Script used here from:

BizTalk Server: Fixing BizTalk Project Signing Properties with PowerShell (2 KB)
Microsoft | TechNet Gallery

It is nothing new that before you can deploy a solution from Visual Studio into a BizTalk application, you must first set project properties, especially the Server and the Configuration Database. Otherwise two things may happen:

  • Deployment will fail when you try do to deploy it through Microsoft Visual Studio or will you are redeploying a previously deployed BizTalk project.
  • The assemblies and all their artifacts will be deployed to and unwanted BizTalk Application (normally BizTalk Application 1)

Previous I wrote a post regarding how to fix the Deployment Properties of a Visual Studio BizTalk Project with PowerShell, you can know more about it here. However, during my talks about tips and tricks I realize that the previous script was a little limited, it only worked if the deployment properties already exist in the file. This means that, if we were working on a new project or we obtaining a copy of the project from the source control, the script didn’t correctly setup or fix the deployment settings.

I promised that I would fix it and now I’m keeping my word. And I have to say that, this is probably one of scripts that I use the most and the reason why is…

So, why this script is important?

Well, if a solution in Visual Studio contains multiple projects, you need to manually configure the deployment properties for each project.

And you must keep in mind that these setting are under the Project user option file(s) (“*.btproj.user”) that are typically not under source control. The reason is that the Visual Studio deployment feature main focus is for development scenarios where one user settings might differ from another. And it will be up to you, or your client, to decide if you want these files to be checked in and available to all of the developers on your team. (you can read it more about this here)

So, this seems a slight and easy task but now imagine that you have almost 200 projects inside a unique Visual Studio Solution! It will be an insane and consuming task to do and most likely to happen is you to fall asleep in front of the pc.

With this PowerShell you will be able to parameterize all projects inside a Visual Studio Solution running a single line of code and avoid spending numerous hours doing this task manually.

PowerShell script overview
    $allPropertyGroup = $xml.Project.PropertyGroup
    foreach($node in $allPropertyGroup)
    {
        if($node.Server -ne $null)
        {
            #If the Deployment Setting already exists, then we just need to update them
            $addNewNodeFlag = $false
            $node.Server= $ServerName;
            $node.ConfigurationDatabase= $DatabaseName;
            $node.ApplicationName= $ApplicationName;
            $node.Redeploy= $RedeployFlag;
            $node.Register= $RegisterFlag;
            $node.RestartHostInstances= $RestartHostInstancesFlag;
        }
    }

    if($addNewNodeFlag -eq $true)
    {
        #Add a PropertyGroup node if the Deployment Setting doesn't exist
        $newXmlPropertyGroup = $xml.CreateElement("PropertyGroup", "http://schemas.microsoft.com/developer/msbuild/2003")
        $newXmlPropertyGroup.SetAttribute(“Condition”,”'`$(Configuration)|`$(Platform)' == 'Debug|AnyCPU'”);

        $newXmlElement = $newXmlPropertyGroup.AppendChild($xml.CreateElement("Server", "http://schemas.microsoft.com/developer/msbuild/2003"));
        $newXmlTextNode = $newXmlElement.AppendChild($xml.CreateTextNode($ServerName));
 
        $newXmlElement = $newXmlPropertyGroup.AppendChild($xml.CreateElement("ConfigurationDatabase", "http://schemas.microsoft.com/developer/msbuild/2003"));
        $newXmlTextNode = $newXmlElement.AppendChild($xml.CreateTextNode($DatabaseName));

        $newXmlElement = $newXmlPropertyGroup.AppendChild($xml.CreateElement("ApplicationName", "http://schemas.microsoft.com/developer/msbuild/2003"));
        $newXmlTextNode = $newXmlElement.AppendChild($xml.CreateTextNode($ApplicationName));

        $newXmlElement = $newXmlPropertyGroup.AppendChild($xml.CreateElement("Redeploy", "http://schemas.microsoft.com/developer/msbuild/2003"));
        $newXmlTextNode = $newXmlElement.AppendChild($xml.CreateTextNode($RedeployFlag));

        $newXmlElement = $newXmlPropertyGroup.AppendChild($xml.CreateElement("Register", "http://schemas.microsoft.com/developer/msbuild/2003"));
        $newXmlTextNode = $newXmlElement.AppendChild($xml.CreateTextNode($RegisterFlag));

        $newXmlElement = $newXmlPropertyGroup.AppendChild($xml.CreateElement("RestartHostInstances", "http://schemas.microsoft.com/developer/msbuild/2003"));
        $newXmlTextNode = $newXmlElement.AppendChild($xml.CreateTextNode($RestartHostInstancesFlag));

        $xml.Project.InsertAfter($newXmlPropertyGroup, $xml.Project.PropertyGroup[1])
    }

THIS SQL SCRIPT IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND.

You can download the PowerShell Script used here from:

BizTalk Server: Fixing BizTalk Project Deployment Properties with PowerShell (1 KB)
Microsoft | TechNet Gallery

In the sequence of my last two post (here and here) and following the same topic, in order to finalize it, let’s talk about the last option and see how we can accomplish the same goal but this type configuring the Send Handler for existing static Send Ports in your environment.

Well, the two previous post are, in my opinion, more critical than this one for se simple reason that the default BizTalk installation will had ports in your environment that needs to be configure if you want to configure BizTalk Host in a High Availability way, i.e., dedicate logical hosts to run specific areas of functionality such as receiving messages, sending messages, processing orchestrations or tracking data.

However, and although less critical, static send ports can also be a problem in some scenarios, for example:

  • If you install ESB Toolkit before configuring your hosts for each functionality, because during the ESB Toolkit installation it will also be created a static send port call “ALL.Exceptions” that connects with SQL “EsbExceptionDb” database. And this port will be configured with the default send handler (at that time) configured in your environment, that is by default the “BizTalkServerApplication”
  • but also if you reach to an existing environment, already containing several BizTalk Applications running, that is not configured according to best practices in terms of host and host instances (dedicate logical hosts for each functionality).

Once again, we need to do basically do the same steps described in my last two posts to accomplish the task of deleting “BizTalkServerApplication”, this time as a send handler of each adapter:

  • Manually reconfigure the Send handler for each the existing Static Send Port first, configuring them with the new or correct Send Handler;
  • and then manually delete the “BizTalkServerApplication” as a Send handler for each adapter;

You may have heard this before, but it never hurts, all of these tasks are time consuming, and a little boring to do after a while or if we need to do it several times;

So how can we automate tasks? and reuse them whenever necessary and at the same time saving significant time for other tasks?

Using PowerShell is a good option J. Windows PowerShell is a Windows command-line shell designed especially for system administrators and can be used by BizTalk administrators to help them in automating repetitive tasks or tasks that are time consuming to perform manually.

This is a simple script that allows you to configure the Send handler associated with all the existing Static Send Ports in your environment independently of the adapter that is configured:

$catalog = New-Object Microsoft.BizTalk.ExplorerOM.BtsCatalogExplorer
$catalog.ConnectionString = "SERVER=$bizTalkDbServer;DATABASE=$bizTalkDbName;Integrated Security=SSPI"

foreach($SendPort in $catalog.SendPorts)
{
    # For each receive location in your environment
    if($sendPort.IsDynamic -eq $False)
    {
        # Let's look for send handlers associated with Adapter configured in the send port
        foreach ($handler in $catalog.SendHandlers)
        {
            # if the Send Handler is associated with the Adapter configured in the send port
            if ($handler.TransportType.Name -eq $sendPort.PrimaryTransport.TransportType.Name)
            {
                # We will configured the port with the default send handler associated in each adapter in you system  
                # independently if it is "BizTalkServerApplication" or not.
                # Note: it's is recomended that you first configure the default send handlers for each adapter 
                #       and also not to use the "BizTalkServerApplication" (my personal recomendation)
                if($handler.IsDefault)
                { 
                    $sendPort.PrimaryTransport.SendHandler = $handler
                    break
                }
            }
        }
    }
}
$catalog.SaveChanges()

Prerequisites for this script: The host, host instances and Receive handlers needs to be already configured in your environment before you run the script;

THIS POWERSHELL IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND.

The full script can be found and download on Microsoft TechNet Gallery:
PowerShell to Configure the Default Send Handler for each static Send Port (3.0 KB)
Microsoft TechNet Gallery

Following the topic from my previous post, when we are configuring/optimizing a new environment, if some features are installed like EDI features or RosettaNet Accelerator, if we create different or dedicated host and host instances for each functionality, for example a host instance for receive, send, process (orchestrations), tracking and so on; of course then we need to associate them as a specific handler of each adapter (receive or send handler) and if we want to delete the “BizTalkServerApplication” as a receive handler from each adapter… we can’t!

This happens because, at least, both EDI and RosettaNet will create during the installation some Receive Ports:

  • BatchControlMessageRecvPort with a receive location BatchControlMessageRecvLoc using SQL Adapter
  • ResendReceivePort with a receive location ResendReceiveLocation using SQL Adapter
  • LOB_To_PrivateInitiator with a receive location LOB_To_PrivateInitiator using SQL Adapter
  • LOB_To_PrivateResponder with a receive location LOB_To_PrivateResponder using SQL Adapter

And all these ports, by default during the installation, are configured with the only existing Receive handler available at the time: “BizTalkServerApplication”.

To accomplish the task of deleting “BizTalkServerApplication” as a receive handler of each adapter, we need to do basically the same steps described in my last post:

  • Manually reconfigure the Receive handler for each the existing receive location first, configuring them with the new Receive Handler;
  • and then manually delete the “BizTalkServerApplication” as a Receive handler for each adapter;

This task can be more normal to happen on the first time we configure/optimize the environment – day one of the BizTalk Server – but can be more critical if you reach to an existing environment, already containing several BizTalk Applications running, that is not configured according to best practices in terms of host and host instances.

Once again, all of these tasks are time consuming, and to be fair… again…, they are a little boring to do after we know how to do it manually;

So how can we automate tasks? and reuse them whenever necessary and at the same time saving significant time for other tasks?

Using PowerShell is a good option J. Windows PowerShell is a Windows command-line shell designed especially for system administrators and can be used by BizTalk administrators to help them in automating repetitive tasks or tasks that are time consuming to perform manually.

This is a simple script that allows you to configure the receive handlers associated with all the existing Receive Ports in your environment that are using the SQL Adapter, but this can be easily changed to cover all the Receive Locations independently of the configured adapter:

$catalog = New-Object Microsoft.BizTalk.ExplorerOM.BtsCatalogExplorer
$catalog.ConnectionString = "SERVER=$bizTalkDbServer;DATABASE=$bizTalkDbName;Integrated Security=SSPI"

foreach($receivePort in $catalog.ReceivePorts)
{
    # For each receive location in your environment
    foreach($recLocation in $receivePort.ReceiveLocations)
    {
        # In this case I want only Receive location that are using SQL Adapter
        if($recLocation.ReceiveHandler.TransportType.Name -eq 'SQL')
        {
            # Let's look for receive handlers associated with SQL Adapter
            foreach ($handler in $catalog.ReceiveHandlers)
            {
                # if is a SQL Adapter Receive Handler
                if ($handler.TransportType.Name -eq "SQL")
                {
                    # And is not BizTalkServerApplication, then configure that as the handler of the receive location
                    # Note: that in this case we will configure as a Receive Handler of the Receive location, the first 
                    #       receive handler that we find that is not the "BizTalkServerApplication"
                    #       because the goal is to delete this handler
                    if($handler.Name -ne 'BizTalkServerApplication')
                    { 
                        $recLocation.ReceiveHandler = $handler
                        break
                    }
                }
            }
        }
    }
}
$catalog.SaveChanges()

Prerequisites for this script: The host, host instances and Receive handlers needs to be already configured in your environment before you run the script;

THIS POWERSHELL IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND.

The full script can be found and download on Microsoft TechNet Gallery:
PowerShell to Configure Receive Handlers from existing Receive locations (3.0 KB)
Microsoft TechNet Gallery

As happens almost every year on this day (my birthday), I always try to write a post for the BizTalk community… something like a gift/present to the community… today will be automate the task of configuring default Dynamic Send ports handlers using PowerShell.

Since BizTalk Server 2013 we have available a new feature: Configurable Dynamic Send Port Handler. Which means that, when we are creating a Dynamic Send Port, an adapter Send Handler can be configurable for every installed adapter, by default it uses the default send handler associated in each adapter. This Includes both One-Way and Solicit-Response Dynamic Ports.

Note that in previous BizTalk versions, a dynamic send port uses the adapter’s default host, and we cannot change this behavior.

However, this new features also brings us some setbacks, special for BizTalk Administrators, for example:

  • When we are installing a new environment, if we install the EDI features, this will add a dynamic port call “ResendPort” (don’t need to describe the propose of this port) and the default send handler for each adapter will be the “BizTalkServerApplication”;
    • If we create different or dedicated host and host instances for each functionality, for example a host instance for receive, send, process (orchestrations), tracking and so on; of course then we need to associate them as a specific handler of each adapter (receive or send handler) and if we want to delete the “BizTalkServerApplication” as a send handler for each adapter… we can’t, we first need to:
      • Manually reconfigure the default Dynamic Send port handlers for each dynamic port first, configuring them with the new default send handler;
      • and then manually delete the “BizTalkServerApplication” as a send handler for each adapter;
  • The same happens when we install a new adapter. By default, it assumes the default host in the group as the default send handler of the adapter and in consequence the default send handler associated with this adapter in the existing dynamic send ports. Which means that once again we need to manually reconfigure the send handler in all the existing dynamic send ports for this new adapter;
  • And so on;

All of these tasks are time consuming, and to be fair, they are a little boring to do after we know how to do it manually;

So how can we automate tasks? and reuse them whenever necessary and at the same time saving significant time for other tasks?

Using PowerShell is a good option. Windows PowerShell is a Windows command-line shell designed especially for system administrators and can be used by BizTalk administrators to help them in automating repetitive tasks or tasks that are time consuming to perform manually.

This is a simple script that allows you to configure the default send handlers associated with all the existing Dynamic Send ports in your environment:

[string] $sendHost32bits = "BizTalkServerSend32Host"
[string] $sendHost64bits = "BizTalkServerSendHost"

$catalog = New-Object Microsoft.BizTalk.ExplorerOM.BtsCatalogExplorer
$catalog.ConnectionString = "SERVER=$bizTalkDbServer;DATABASE=$bizTalkDbName;Integrated Security=SSPI"

foreach($sendPort in $catalog.SendPorts)
{
    if($sendPort.IsDynamic -eq' True')
    {
        # A Dynamic send port was found so now we need to configure the send handler as desired
        # 64 bits adapters
        # Changing the default send handlers of the dynamic port
        $sendPort.SetSendHandler("FILE", $sendHost64bits)
        $sendPort.SetSendHandler("HTTP", $sendHost64bits)
        $sendPort.SetSendHandler("MQSeries", $sendHost64bits)
        $sendPort.SetSendHandler("MSMQ", $sendHost64bits)
        $sendPort.SetSendHandler("SB-Messaging", $sendHost64bits)
        $sendPort.SetSendHandler("SFTP", $sendHost64bits)
        $sendPort.SetSendHandler("SOAP", $sendHost64bits)
        $sendPort.SetSendHandler("WCF-BasicHttp", $sendHost64bits)
        $sendPort.SetSendHandler("WCF-BasicHttpRelay", $sendHost64bits)
        $sendPort.SetSendHandler("WCF-Custom", $sendHost64bits)
        $sendPort.SetSendHandler("WCF-NetMsmq", $sendHost64bits)
        $sendPort.SetSendHandler("WCF-NetNamedPipe", $sendHost64bits)
        $sendPort.SetSendHandler("WCF-NetTcp", $sendHost64bits)
        $sendPort.SetSendHandler("WCF-NetTcpRelay", $sendHost64bits)
        $sendPort.SetSendHandler("WCF-SQL", $sendHost64bits)
        $sendPort.SetSendHandler("WCF-WebHttp", $sendHost64bits)
        $sendPort.SetSendHandler("WCF-WSHttp", $sendHost64bits)
        $sendPort.SetSendHandler("Windows SharePoint Services", $sendHost64bits)       

        # 32 bits adapters
        # SMTP Supports 64 bits but I want to run in 32 because of the MIME/SMIME Encoder
        $sendPort.SetSendHandler("FTP", $sendHost32bits)
        $sendPort.SetSendHandler("SMTP", $sendHost32bits)
        $sendPort.SetSendHandler("SQL", $sendHost32bits)
    }
}

$catalog.SaveChanges() 

Prerequisites for this script: The host, host instances and send handlers needs to be already configured in your environment before you run the script;

THIS POWERSHELL IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND.

The full script can be found and download on Microsoft TechNet Gallery:
PowerShell to configure Default Dynamic Send Port Handlers for each Adapter (3.0 KB)
Microsoft TechNet Gallery

There are several ways that you can integrate and schedule Message Box Viewer or BizTalk Health Monitor, since Message Box Viewer (aka MBV) is deprecated, and it is now replaced by BizTalk Health Monitor (aka BHM).

The first option is to use BHM itself, for that, if you have BHM integrated with BizTalk Administration Console (see how to here):

  • Open BizTalk Administration Console, expand BizTalk Health Monitor
  • And then right-click on “Default” profile (or your custom profile) and select “Settings…”
  • On the Monitoring Profile Settings – [Profile name] windows
    • Select “Schedule” panel and define your scheduler

BizTalk-Healt-Monitor-Scheduler-options

    • And then select “Notifications” panel to “customize” the desired notifications and email settings. For example:
      • Mail notification or/and Eventlog Notifications
      • Send a mail only when critical warnings are raised
      • And the option to attach the complete report (compressed)

BizTalk-Healt-Monitor-Notification-options

Of course, by using the BHM, you can customize also the types of queries that you want to run and so on.

The second option is, for example, to use BizTalk360 by:

  • Click the “Settings” icon at the top of the page and then selecting “Message Box Viewer” option from the left menu bar.
  • On “Config and Schedule Message Box Viewer Integration” panel you need to:
    • In the “Message Box Viewer Download Directory” property: Enter the path to the MBV directory in the
    • In the “Schedule Execution” panel:
      • In the “Environment” property: leave the default or select your BTS environment for which the MBV execution has to be scheduled
      • In the “Days” and “Time” properties – Select the day and time when the MBV should run automatically.
      • And finally, click “Save” to save the configuration settings.

MessageBox-Viewer-BizTalk360-integration

However, I was trying to full customize my notification warnings! And I want to receive an email notification if Warnings and Critical Warnings are raised but in some environments, special in small or test environments, I know that BizTalk machines are not fully configured as High Availability or according to all the best practices… sometimes these are limitations that you need to live with it. For example:

  • SSO DB: “Not Clustered (this DB is critical as it keep encrypted ports properties)!” – for small environments sometimes I only have one BizTalk Machine so in this case I don’t need, and I can’t, cluster the SSO. So, for me sometimes this is a false warning.
  • “MDF Db Growth for BizTalkMgmtDb” or “LOG Db Growth for BizTalkMgmtDb”: “Current =102400 KB (Def=1024 KB) – Recommended for this Db=1024 KB?!” – I have the MDF and LOG grow setting defined correctly but not according to the recommended setting of this tool, again, for me sometimes this is a false warning.
  • “LDF and MDF files Location for …”: “Same Drive (Can cause disk contention)!” – Again, sometimes the tool raises these warnings even if the location is different, so in certain cases, if I’m sure of the configurations I can consider this a false warning.
  • And so on…

Don’t get me wrong I love this tool but each time the report is generated, we need to make a review to the report and analyze what is real and what is “false” warnings, special the non-critical warnings. I want to be smarter and automate this task, so for fun I decide to give it a try with PowerShell script.

So how can PowerShell help us?

With this script you can be able to easily monitor the health of your BizTalk environment (engine and architecture) by scheduling Message Box Viewer(MBV) or BizTalk Health Monitor (BHM) and customize alerts using PowerShell.

Only if the script finds any critical warning (there are no conditions in critical warnings) or any non-critical warning that is not expected (what I may consider a “false” or expected warning) a mail notification will be sent.

Additional, if a notification mail is sent, I will also want to send the completed report (compressed) attached to the email.

This script allows you to set:

  • Set your email notification settings
#Set mail variables
[STRING]$PSEmailServer = "mySMTPServer" #SMTP Server.
[STRING]$SubjectPrefix = "MBV Notification Report -  "
[STRING]$From = "biztalksupport@mail.pt"
[array]$EmailTo = ("sandro.pereira@devscope.net") 
  • Set location settings – the location of the tool and where the reports are saved can be different
#### Option to execute MBV
$mbvPath = "C:\Users\Administrator\Desktop\powerShell\MBV\"
#### Option to execute BHM
#$mbvPath = "C:\Program Files (x86)\BizTalk Support Tools\BHMv3.1\" 
$mbvReportSaveLocation = "C:\Users\Administrator\Desktop\powerShell\MBV\"
  • Critical errors we want to be notified (in this case all of them)
# Critical errors we want to be notified (in this case all of them)
if($xml.MSGBOXVIEWER.WARNINGSREPORT_RED.Count -gt 0)
{
    $mailBodyMsb += "<h3>Critical Warnings</h3> `n`n"

    Foreach ($criticalReport in $xml.MSGBOXVIEWER.WARNINGSREPORT_RED)
    {
        $countCriticalAlerts++;

        #Add mail content
        $mailBodyMsb += "<th><b>Critical Warning: " + $countCriticalAlerts + "</font></b></th>"
        $mailBodyMsb += "<table style='boder:0px 0px 0px 0px;'>"

        $mailBodyMsb += "<TR style='background-color:rgb(245,245,245);';><TD>Category</TD>"
        $mailBodyMsb += "<TD><b><font color='red'>" + $warningReport.Category + "</font><b></TD></TR>"
        
        $mailBodyMsb += "<TR style='background-color:white;'><TD>Item Caption</TD>"
        $mailBodyMsb += "<TD><b><font color='red'>" + $warningReport.ItemCaption + "</font><b></TD></TR>"
        
        $mailBodyMsb += "<TR style='background-color:rgb(245,245,245);';><TD>Details</TD>"
        $mailBodyMsb += "<TD>" + $warningReport.ItemValue + "</TD></TR>"

        $mailBodyMsb += "</table>"
        $mailBodyMsb += "<BR><BR>"
    }
}
  • Non-Critical errors we want to be notified – REPORT FILTER EXCLUSIONS
# Non-Critical errors we want to be notified - REPORT FILTER EXCLUSIONS
if($xml.MSGBOXVIEWER.WARNINGSREPORT_YELLOW.Count -gt 0)
{
    $mailBodyMsb += "<h3>Non Critical Warnings</h3> `n`n"

    Foreach ($warningReport in $xml.MSGBOXVIEWER.WARNINGSREPORT_YELLOW)
    {
        #####################################################################################
        # REPORT FILTER EXCLUSIONS
        #
        #Exclude from the report "false" warnings (like MDF Db Growth for) 
        #or warnings that you already know that you have and need to deal with it (like LDF and MDF files Location for)
        #or others that you want to exclude
        #####################################################################################
        if($warningReport.ItemCaption -eq "Errors during Collect")
        {
            continue;
        }

        if($warningReport.ItemCaption -eq "Class Settings Changed")
        {
            continue;
        }

        if(($warningReport.ItemCaption -Match "MDF Db Growth for") -or ($warningReport.ItemCaption -Match "LOG Db Growth for") -or ($warningReport.ItemCaption -Match "LDF and MDF files Location for"))
        {
            continue;
        }

        if(($warningReport.ItemCaption -Match "LDF files Location for BizTalkDTADb and BizTalkMsgBoxDb") -or ($warningReport.ItemCaption -Match "MDF files Location for BizTalkDTADb and BizTalkMsgBoxDb"))
        {
            continue;
        }

        if(($warningReport.ItemCaption -Match 'BizTalkServerApplication') -and ($warningReport.ItemValue -Match "Run Receive Location+Orchestration"))
        {
            continue;
        }

        if($warningReport.ItemCaption -Match 'SMS agent is running')
        {
            continue;
        }

        if($warningReport.ItemCaption -eq "Non WCF SQL adapter used in some Receive Locations")
        {
            continue;
        }

        if(($warningReport.ItemCaption -Match 'Server WH0') -and ($warningReport.ItemValue -Match "Running in VMware Virtual Platform "))
        {
            continue;
        }

        if($warningReport.ItemValue -eq "Custom or Third-party adapter !")
        {
            continue;
        }

        if($warningReport.ItemCaption -eq "'maxconnection' property")
        {
            continue;
        }
        #####################################################################################
        # Report Filter exclusions
        #####################################################################################

        $countWarningAlerts++;
        #Add mail content
        $mailBodyMsb += "<th><b>Warning: " + $countWarningAlerts + "</b></th>"
        $mailBodyMsb += "<table style='boder:0px 0px 0px 0px;'>"
        $mailBodyMsb += "<TR style='background-color:rgb(245,245,245);';><TD>Category</TD>"
        $mailBodyMsb += "<TD><b><font color='Orange'>" + $warningReport.Category + "</font><b></TD></TR>"
        
        $mailBodyMsb += "<TR style='background-color:white;'><TD>Item Caption</TD>"
        $mailBodyMsb += "<TD><b><font color='Orange'>" + $warningReport.ItemCaption + "</font><b></TD></TR>"
        
        $mailBodyMsb += "<TR style='background-color:rgb(245,245,245);';><TD>Details</TD>"
        $mailBodyMsb += "<TD>" + $warningReport.ItemValue + "</TD></TR>"

        $mailBodyMsb += "</table>"
        $mailBodyMsb += "<BR><BR>"
    }
}
  • Delete the reports history from “Save Report” folder (I can have the last day’s executions as history) and remove compressed files.
#remote the rip report file
Remove-Item $zipFile
#remote report folder older then X days
get-childitem $mbvReportSaveLocation |? {$_.psiscontainer -and $_.lastwritetime -le (get-date).adddays(-3)} |% {remove-item $_ -Force -Recurse}

Again, only if the script finds any Critical or non-critical warning (that is not expected) a mail notification will be sent.

Report sample:

MessageBox-Viewer-BHM-Notification-report-powershell

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

THIS POWERSHELL IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND.

The script can be found and download on Microsoft TechNet Gallery:
How to schedule MBV or BHM and customize notification alerts with PowerShell (18.0 KB)
Microsoft TechNet Gallery

In the sequence of my last two posts, welcome back, once again (probably the last one for now), to this serial of articles about Monitor your BizTalk environment using PowerShell.

Today we will talk about a topic that a new topic, “How to monitor Host Instance in BizTalk Server using PowerShell”, and once again, we will add Auto Healing functionalities to the script.

One of the principal needs for BizTalk 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 many more… However, unfortunately many times, some of these tools are not available for us but we still need to accomplish this task.

There are bunch of things that can go wrong and the longer they have in an error/failure situation, more impact could have in 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)

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

So how can PowerShell help us?

With this script you can be able to monitoring your BizTalk environment for Host Instance that aren’t Started (Stopped, Start pending, Stop pending, Continue pending, Pause pending, Paused or Unknown), and automatically bring them to desired state (Started) 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 = "Host instances not running - "
[STRING]$From = "biztalksupport@mail.pt"
[array]$EmailTo = ("sandro.pereira@devscope.net")

The following Windows PowerShell script is a fragment that will help us demonstrate this capabilities:

# Get Host instances not running
[ARRAY]$hostInstances = get-wmiobject MSBTS_HostInstance  -namespace 'root\MicrosoftBizTalkServer' -filter '(HostType = 1 and ServiceState != 4)'

foreach ($hostInstance in $hostInstances)
{
    #Add mail content
    $mailBodyHI += "<th><b><font color='blue'>" + $hostInstance.Name + "</font></b></th>"
    $mailBodyHI += "<table style='boder:0px 0px 0px 0px;'>"
    $mailBodyHI += "<TR style='background-color:white;'><TD>Host Name</TD>"
    $mailBodyHI += "<TD><b><font color='red'>" + $hostInstance.HostName + "</font></b></TD>
</TR>"

    $mailBodyHI += "<TR style='background-color:rgb(245,245,245);';><TD>Host Type</TD>"
    $mailBodyHI += "<TD>In-process</TD></TR>"

    $mailBodyHI += "<TR style='background-color:white;'><TD>Running Server</TD>"
    $mailBodyHI += "<TD><b><font color='red'>" + $hostInstance.RunningServer + "</font></b></TD></TR>"

    # Stopped: 1
    # Start pending: 2
    # Stop pending: 3
    # Running: 4
    # Continue pending: 5
    # Pause pending: 6
    # Paused: 7
    # Unknown: 8

    if ($hostInstance.ServiceState -eq 1)
    {
        $statusHI = "Stopped" 
    }
    if ($hostInstance.ServiceState -eq 2)
    {
        $statusHI = "Start pending" 
    }
    if ($hostInstance.ServiceState -eq 3)
    {
        $statusHI = "Stop pending" 
    }
    if ($hostInstance.ServiceState -eq 5)
    {
        $statusHI = "Continue pending" 
    }
    if ($hostInstance.ServiceState -eq 6)
    {
        $statusHI = "Pause pending" 
    }
    if ($hostInstance.ServiceState -eq 7)
    {
        $statusHI = "Paused" 
    }
    if ($hostInstance.ServiceState -eq 8)
    {
        $statusHI = "Unknown" 
    }

    $mailBodyHI += "<TR style='background-color:rgb(245,245,245);';><TD>Service State</TD>"
    $mailBodyHI += "<TD><b><font color='red'>" + $statusHI + "</font></b></TD></TR>"

    #0: UnClusteredInstance
    #1: ClusteredInstance
    #2: ClusteredVirtualInstance
    if ($hostInstance.ClusterInstanceType -eq 0)
    {
        $statusHI = "UnClustered Instance" 
    }
    if ($hostInstance.ClusterInstanceType -eq 1)
    {
        $statusHI = "Clustered Instance" 
    }
    if ($hostInstance.ClusterInstanceType -eq 2)
    {
        $statusHI = "Clustered Virtual Instance" 
    }

    $mailBodyHI += "<TR style='background-color:white;'><TD>Cluster Instance Type</TD>"
    $mailBodyHI += "<TD>" + $statusHI + "</TD></TR>"

    $mailBodyHI += "<TR style='background-color:rgb(245,245,245);';><TD>Is Disabled</TD>"
    $mailBodyHI += "<TD>" + $hostInstance.IsDisabled + "</TD></TR>"

    $mailBodyHI += "<TR style='background-color:white;'><TD>NT Group Name</TD>"
    $mailBodyHI += "<TD>" + $hostInstance.NTGroupName + "</TD></TR>"

    $mailBodyHI += "<TR style='background-color:rgb(245,245,245);';><TD>Logon</TD>"
    $mailBodyHI += "<TD>" + $hostInstance.Logon + "</TD></TR>"
    
    #Auto-Healing feature
    if($hostInstance.IsDisabled = "False")
    {
        $hostInstance.InvokeMethod("Start",$null)

        $mailBodyHI += "<TR style='background-color:white;'><TD><font color='green'>Note</font></TD>"
        $mailBodyHI += "<TD><font color='green'>The Host Instance was started automatically by this script! Please access the environment to validate if all host instances are running.</font></TD></TR>"
    }

    $mailBodyHI += "</table>"
    $mailBodyHI += "<BR><BR>"
}

Here is example expected report output from running the Windows PowerShell script sample, if any of the Host instance are in an unwanted state.

BizTalk-Host-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. The script should also be adjusted to your needs.

THIS POWERSHELL IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND.

The script can be found and download on Microsoft TechNet Gallery:
Monitoring BizTalk Host Instances with Auto-Healing with PowerShell (14.0 KB)
Microsoft TechNet Gallery

In the sequence of my last post, welcome back, once again, to this serial of articles about Monitor your BizTalk environment using PowerShell.

Today we will talk about a topic that was also previously covered by Jeroen, ” Monitor your BizTalk environment using PowerShell – Port monitoring”, but this time, I will also add Auto Healing functionalities to the script.

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

One of the principal needs for BizTalk 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 many more… However, unfortunately many times, some of these tools are not available for us but we still need to accomplish this task.

There are bunch of things that can go wrong and the longer they have in an error/failure situation, more impact could have in 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 monitoring your BizTalk environment for disabled receive locations and stopped or unenlisted send ports, and automatically resume then according to certain conditions, using PowerShell.

A mail notification will be sent only if this scripts finds any receive location or send port in a non-conform situation.

This sample will demonstrate how can you easily create a script with a set of conditions to be able to monitor and to automatically fix the receive locations and send ports to the desired state:

  • “Enable” for receive locations
  • “Started” for send ports

This script allows you to set:

  • Set your email notification settings
#Set mail variables
[STRING]$PSEmailServer = "mySMTPServer" #SMTP Server.
[STRING]$SubjectPrefix = "Port status - "
[STRING]$From = "biztalksupport@mail.pt"
[array]$EmailTo = ("sandro.pereira@devscope.net")

The following Windows PowerShell script is a fragment that will help us demonstrate this capabilities:

#Get Counters: Check if there are any disable receive locations and stopped/unelisted send ports
if ($sendports.count -ne (get-wmiobject MSBTS_SendPort -namespace 'root\MicrosoftBizTalkServer' -filter '(Status = 3)').count)
{
    [BOOL]$script:Continuescript = $True
    [INT]$countSendPorts = $sendports.count - $(get-wmiobject MSBTS_SendPort -namespace 'root\MicrosoftBizTalkServer' -filter {Status = 3}).count
}
if ($ReceiveLocations.count -ne (get-wmiobject MSBTS_ReceiveLocation -namespace 'root\MicrosoftBizTalkServer' -filter '(IsDisabled = False)').count)
{
    [BOOL]$script:Continuescript = $True
    [INT]$countReceivePorts = $ReceiveLocations.count - $(get-wmiobject MSBTS_ReceiveLocation -namespace 'root\MicrosoftBizTalkServer' -filter '(IsDisabled = False)').count
}

if($countSendPorts -gt 0)
{
    $mailTextReportPT += "" + $countSendPorts + " send ports stopped; "
    $mailBodyPT += "<h3>Send ports Stopped</h3>"

    #Add mail content for stopped send ports
    Foreach ($SendPort in $SendPorts)
    {
        #only add stopped send ports to the mail
        if ($SendPort.status -eq 2 -OR $SendPort.status -eq 1)
        {
            $StoppedSendPort = $True
            #Set status to a user friendly name
            if ($SendPort.status -eq 2)
            {
                $SendPortStatus = "Stopped"
            }
            elseif ($SendPort.status -eq 1)
            {
                $SendPortStatus = "Unelisted"
            }
    
            #Add mail content
            $mailBodyPT += "<th><b><font color='red'>" + $SendPort.name + "</font></b></th>"
            $mailBodyPT += "<table style='boder:0px 0px 0px 0px;'>"   
     
            $mailBodyPT += "<TR style='background-color:white;'><TD>Status</TD>"
            $mailBodyPT += "<TD><b><font color='red'>" + $SendPortStatus + "</font><b></TD></TR>"
        
            $mailBodyPT += "<TR style='background-color:rgb(245,245,245);';><TD>URI</TD>"
            $mailBodyPT += "<TD>" + $SendPort.PTAddress + "</TD></TR>"
        
            $mailBodyPT += "<TR style='background-color:white;'><TD>Transport type</TD>"
            $mailBodyPT += "<TD>" + $SendPort.PTTransportType + "</TD></TR>"

            if ($SendPort.status -eq 2)
            {
                #Auto-Healing feature
                $SendPort.InvokeMethod("Start",$null)

                $mailBodyPT += "<TR style='background-color:rgb(245,245,245);';><TD><font color='green'>Note</font></TD>"
                $mailBodyPT += "<TD><font color='green'>The Stopped port was automatically Started by this script! Please access the environment to check if ports are running correctly.</font></TD></TR>"
            }

            $mailBodyPT += "</table>"
            $mailBodyPT += "<BR><BR>"
        }
    }
}

if($countReceivePorts -gt 0)
{
    $mailTextReportPT += "" + $countReceivePorts + " receive locations disabled; "
    $mailBodyPT += "<h3>Receive locations Disabled</h3>"

    #Add mail content for stopped receive locations
    Foreach ($ReceiveLocation in $ReceiveLocations)
    {
        #only add stopped receive locations to the mail
        if ($ReceiveLocation.IsDisabled -eq "True")
        {
            $StoppedReceiveLocation = $True
            
            #Set status to a user friendly name
            $ReceiveLocationStatus = "Disabled"
        
            #Add mail content
            $mailBodyPT += "<th><b><font color='red'>" + $ReceiveLocation.name + "</font></b></th>"
            $mailBodyPT += "<table style='boder:0px 0px 0px 0px;'>"           
            $mailBodyPT += "<TR style='background-color:white;'><TD>Status</TD>"
            $mailBodyPT += "<TD><b><font color='red'>" + $ReceiveLocationStatus + "</font></b></TD></TR>"
            
            $mailBodyPT += "<TR style='background-color:rgb(245,245,245);';><TD>URI</TD>"
            $mailBodyPT += "<TD>" + $ReceiveLocation.InboundTransportURL + "</TD></TR>"
            
            $mailBodyPT += "<TR style='background-color:white;'><TD>Transport type</TD>"
            $mailBodyPT += "<TD>" + $ReceiveLocation.AdapterName + "</TD></TR>"

            #Auto-Healing feature
            $ReceiveLocation.InvokeMethod("Enable",$null)

            $mailBodyPT += "<TR style='background-color:rgb(245,245,245);';><TD><font color='green'>Note</font></TD>"
            $mailBodyPT += "<TD><font color='green'>The Disabled port was automatically Enable by this script! Please access the environment to check if ports are running correctly.</font></TD></TR>"

            $mailBodyPT += "</table>"
            $mailBodyPT += "<BR><BR>"
        }
    }
}

Note: The script should be adjusted to your needs. Maybe having a variable or a list of receive location and Send ports that should be excluded for the monitoring or have a different expected status.

Here is example expected report output from running the Windows PowerShell script sample, if any of the ports are in an unwanted state.

BizTalk-Ports-Status-Report

Again, this type of script must be viewed as a complement to the tools mentioned above or used in the absence of them.

THIS POWERSHELL IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND.

The script can be found and download on Microsoft TechNet Gallery:
Monitoring BizTalk Server Ports with Auto-Healing capabilities with PowerShell (14.0 KB)
Microsoft TechNet Gallery