wiki

Codit Wiki

Loading information... Please wait.

Codit Blog

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

 

Posted on Wednesday, February 22, 2012 11:22 AM

Toon Vanhoutte by Toon Vanhoutte

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.

 

Toon Vanhoutte

Categories: BizTalk Deployment
written by: Toon Vanhoutte