Dynamically detect the BizTalk Servers of a BizTalk Group during automated deployment

This post was originally published here.

Microsoft BizTalk Server 2010 ships with some assemblies that assist you with the administration and deployment of your BizTalk environment. There was a small challenge to dynamically detect the BizTalk Servers of a BizTalk Group, during an automated deployment.

Microsoft BizTalk Server 2010 ships with some assemblies that assist you with the administration and deployment of your BizTalk environment.  During the development of an automated deployment plan, we were able to perform most of the deployment tasks at a BizTalk application level, by using these assemblies:

Microsoft.BizTalk.ExplorerOM

  • Create/delete applications
  • Control receive locations
  • Control orchestrations
  • Control send ports
  • Control send port groups
  • Control application references

Microsoft.BizTalk.ApplicationDeployment

  • Add/remove resources

Microsoft.BizTalk.Deployment

  • Import/export bindings

Microsoft.BizTalk.Operations

  • Query for active service instances

Remark that all of the used objects can be initialized by three parameters:

  • SqlServerName
  • BizTalkMgmtDbName
  • ApplicationName

The object “BizTalk Group” is defined by the SqlServerName and the BizTalkMgmtDbName.  A “BizTalk Application” is defined by its BizTalk Group and the ApplicationName.  However, these assemblies have totally no notion of the object “BizTalk Server“.  They only support operations at a database level (BizTalk Group), but some deployment tasks need to be executed on a BizTalk Server level:

  • Install/uninstall assemblies to the Global Assembly Cache
  • Control host instances

For both actions we needed to be able to dynamically determine which BizTalk Servers are part of the already defined BizTalk Group. After some research, we found two options to implement this logic:

Windows Management Instrumentation

WMI has some support for BizTalk via the WMI namespace “root\\MicrosoftBizTalkServer”.  We are able to loop though all configured host instances, by executing a query on the MSBTS_HostInstance class.  As each host instance runs on a BizTalk Server, it’s easy to implement some logic that retrieves all BizTalk Servers.

private List<string> GetBizTalkServers()
{
   List<string> btsServers = new List<string>();
 
   EnumerationOptions wmiEnumerationOptions = new EnumerationOptions { ReturnImmediately = false };
   ObjectQuery wmiQuery = new ObjectQuery("SELECT * FROM MSBTS_HostInstance");
   using (ManagementObjectSearcher wmiSearcher = new ManagementObjectSearcher("root\\MicrosoftBizTalkServer", wmiQuery.QueryString, wmiEnumerationOptions))
   {
      ManagementObjectCollection hostInstanceCollection = wmiSearcher.Get();
      foreach (ManagementObject hostInstance in hostInstanceCollection.Cast<ManagementObject>())
      {
         string btsServer = hostInstance["Name"].ToString().Split(' ').Last();
         if (btsServers.Contains(btsServer) == false)
         {
            btsServers.Add(btsServer);
         }
      }
   } 
   return btsServers;
}

Custom SQL Server query

Another option is to retrieve the information directly from the BizTalkMgmtDb.  The table adm_Server actually contains a list of all BizTalk Servers that are part of the BizTalk Group.  So this simple .NET code is able to return us the needed information:

private List<string> GetBizTalkServers()
{
   List<string> btsServers = new List<string>();
 
   SqlConnection sqlConnection = new SqlConnection(String.Format(CultureInfo.CurrentCulture, "Server={0};Database={1};Integrated Security=SSPI;", SqlServerName, MgmtDatabase));
   SqlCommand sqlCommand = new SqlCommand("SELECT Name FROM [dbo].[adm_Server]", sqlConnection);
 
   sqlConnection.Open();
   SqlDataReader sqlDataReader = sqlCommand.ExecuteReader();
 
   while (sqlDataReader.Read())
   {
      btsServers.Add(sqlDataReader["Name"].ToString());
   }
  
   sqlConnection.Close();
   return btsServers;
}

Conclusion

It’s pretty easy to retrieve a list of all BizTalk Servers that are part of a BizTalk Group.  A limitation of the WMI approach is that this will only work when it’s executed on one of the BizTalk Servers.  So I prefer the SQL approach, because this will also work for remote execution.

 

About me

Hi! I’m Toon Vanhoutte, a hands-on Azure architect – based in Belgium – with a big passion for teaching and helping people out. I’m happy to assist you during your Azure journey with high-quality advisory and I would love to teach you Azure’s possibilities via my tailored training courses.

Subscribe to the blog