Introduction

BizTalk Server provides great flexibility for addressing high availability, because you can strategically dedicate logical hosts to run specific areas of functionality such as receiving messages, sending messages or processing orchestrations.

By default the BizTalk configuration will create two BizTalk Host and Host Instances:
  • BizTalkServerApplication: This is the default Host and Host Instance created during configuration that will do all the work on the BizTalk Server, i.e. is the default send and receive handler for all installed adapters (other than HTTP, WCF (BasicHttp, CustomIsolated, WebHttp and WSHttp) and SOAP Receive Handlers), and is also used for processing orchestration and tracking.

  • BizTalkServerIsolatedHost: The logical container for HTTP, WCF (BasicHttp, CustomIsolated, WebHttp and WSHttp) and SOAP Receive Handlers.

Although a single BizTalk Host can contain items that receive, send, and process messages, it is considered a best practice to create different hosts for each function to create security boundaries and for easier management and scalability. In particular, we recommend that you use different hosts for processing and for receive/send operations, and that you separate trusted and non-trusted items.

What are Host, Host Instances and Adapter Handlers?

The BizTalk Host is a logical process and security boundary within BizTalk Server that represents a logical set of zero or more run-time processes in which you can deploy BizTalk Server services and artifacts (such as adapter handlers, receive locations, and orchestrations). Each host has a security group assigned to it and may contain multiple host instances, each on an individual machine, that perform the work of the host. The Host object also represents a collection of runtime instances (zero or more) where the deployed items physically run. Hosts have the following characteristics:

  • Only one instance of a specific host can exist on each server.
  • You can map one host to multiple servers.
In turn, a host instance is the physical instance of a host on a computer running BizTalk Server. Each host instance belongs to exactly one host, and the service account of the host instance belongs to the security group of the host. The security group may be used to grant permissions to physical resources such as databases for use by any host instances in the host. Host instances have the following characteristics:
  • Host instances running on the servers are the physical containers of BizTalk objects.
  • You create a host instance when you map a server to a host.
  • Multiple host instances (of different hosts) can exist on a server.
Note: After you create a host (a logical container), you can add physical BizTalk servers (host instances) to the host. You cannot add a BizTalk server to the same host more than once. A single host instance can be added to multiple hosts. More about hosts here.

The following figure will provide you with a general overview of the relationship between servers, hosts and host instances, however is not intended to be the best practices. This architecture will depend from many factors and will change from client to client:

An adapter handler is an instance of a BizTalk host in which the adapter code runs. When you specify a send or receive handler for an adapter you are specifying which host instance the adapter code will run in the context of. An adapter handler is responsible for executing the adapter and contains properties for a specific instance of an adapter. A default BizTalk Server configuration will create adapter handlers for all of the installed adapters, but you may want to create additional adapter handlers for purposes of load balancing or to provide process isolation for a particular adapter handler.

Types of Hosts

Based on the physical configuration and type of adapter hosted, there are two types of hosts: in-process hosts and isolated hosts.

In-process hosts

In-process hosts represent service instances that an administrator creates, deletes, and fully controls with WMI and the BizTalk Administration console.

In-process hosts have the following characteristics:

  • You can enlist any orchestration into an in-process host.
  • An in-process host can host any send handler.
  • An in-process host can host any receive handlers with the exception of isolated-type adapters (HTTP, WCF-BasicHttp, WCF-CustomIsolated, WCF-WebHttp, WCF-WSHttp and SOAP).
    • FILE
    • FTP
    • MQSeries
    • MSMQ
    • POP3
    • SB-Messaging
    • SFTP
    • SQL
    • Windows SharePoint Services
    • WCF adapters (BasicHttpRelay, Custom, NetMsmq, NetNamedPipe, NetTcp, NetTcpRelay, OracleDB, OracleEBS, SAP, SIEBEL and SQL, )
    • and so on.
  • The first in-process host you create in a BizTalk Server deployment is the default host (BizTalkServerApplication) and you cannot delete it unless, you create other in-process host(s) and unbind all artifact from the default host. Adding an adapter automatically creates a receive and send handler for the default host.
  • After you create other in-process host(s) you can change the default host by setting the property "Make this the default host in the group"

Isolated hosts

Isolated hosts represent service instances that a solutions developer programmatically creates, deletes, and controls. An administrator uses WMI and the BizTalk Administration console to configure these hosts (for example, to configure the host service account and authentication trust).

Isolated hosts primarily host adapters that must run outside of the normal BizTalk Server runtime process. For example, you use isolated hosts to host adapters for external processes such as ISAPI extensions and ASP.NET.

Isolated hosts have the following characteristics:

  • You cannot enlist orchestrations into an isolated host.
  • An isolated host cannot host send handlers.
  • An isolated host can host only the receive handlers associated with HTTP, WCF-BasicHttp, WCF-CustomIsolated, WCF-WebHttp, WCF-WSHttp and SOAP adapters (the isolated-type adapters).
  • An isolated host cannot host tracking.
  • An isolated host cannot be the default host.
  • The status of an isolated host is always Status Unavailable. BizTalk Server does not access the status information for external processes.
  • You cannot started, stopped or restarted Isolated hosts from the BizTalk Administration Console because BizTalk doesn't manage the lifetime of an isolated host. Generally or most common is that an isolated host is mapped into IIS (Internet Information Services), in this case you control the isolated host through the IIS manager.  However any process can be an isolated host.

Note: Host instances can share the same service account as long as they share the same security configuration (authentication trust).

Important Note: An isolated host instance can run only one adapter. If you configure the receive handlers of HTTP and SOAP adapters with the one isolated host, you must create two application pools, one application pool for each adapter.

Best practices to Configuring Hosts and Host Instances

As the official documentation specify, in addition to the high availability aspects of the host instance configuration, you should separate sending, receiving, processing, and tracking functionality into multiple hosts, in other words, you should created dedicated hosts. This provides flexibility when configuring the workload in your BizTalk group and is the primary means of distributing processing across a BizTalk group.

This also allows you to stop one host without affecting other hosts. For example, you may want to stop sending messages to let them queue up in the MessageBox database, while still allowing the inbound receiving of messages to occur.

Separating host instances by functionality also provides some of the following benefits:

  • Each host instance has its own set of resources such as memory, handles, and threads in the .NET thread pool.
  • Multiple BizTalk Hosts will also reduce contention on the MessageBox database host queue tables since each host is assigned its own work queue tables in the MessageBox database.
  • Throttling is implemented in BizTalk Server at the host level. This allows you to set different throttling characteristics for each host.
  • Security is implemented at the host level; each host runs under a discrete Windows identity.

However this also may bring some potential drawbacks if too many host instances are created because each host instance is a Windows service (BTSNTSvc.exe or BTSNTSvc64.exe), which generates additional load against the MessageBox database and consumes computer resources (such as CPU, memory, threads), so you need to be careful.

Normally we read that we need to create at least 4 host instances: sending, receiving, processing, and tracking, but that’s not absolutely true because, at least with the newer environments, we typically use 64-bits versions and in this case we also need to create at least one Host Instance that will run on 32-bits because FTP adapter, SQL adapter, POP3 adapter and MIME Decoder on 64-bit host instances is not supported by the product (http://technet.microsoft.com/en-us/library/aa560166.aspx)

We can define that one of the best practices for hosts and host instances is the following:

Dedicated Tracking host

A BizTalk Host that hosts tracking is responsible for moving the DTA and BAM tracking data from the MessageBox database to the BizTalk Tracking (DTA) and BAM Primary Import databases. This movement of tracking data has an impact on the performance of other BizTalk artifacts that are running in the same host that is hosting tracking. Thus, you should use a dedicated host that does nothing but host tracking. Read more here.

Using a dedicated tracking host also allows you to stop other BizTalk hosts without interfering with BizTalk Server tracking. The movement of tracking data out of the MessageBox database is critical for a healthy BizTalk Server system. If the BizTalk Host responsible for moving tracking data in the BizTalk group is stopped, the Tracking Data Decode service will not run. The impact of this is as follows:

  • HAT tracking data will not be moved from the MessageBox database to the BizTalk Tracking database.
  • BAM tracking data will not be moved from the MessageBox database to the BAM Primary Import database.
  • Because data is not moved, it cannot be deleted from the MessageBox database.
  • When the Tracking Data Decode service is stopped, tracking interceptors will still run and write tracking data to the MessageBox database. If the data is not moved, this will cause the MessageBox database to become bloated, which will affect performance over time.

Create the following host and host instances:

  • BizTalkServerTrackingHost: Only the optionAllow Host Tracking” must be selected because we only will use this host for tracking.

Dedicated Receive hosts

Dedicated receive hosts are hosts dedicated to receiving information send to BizTalk. This host will be responsible for processing messages after they are picked up in a receive location. When a host contains a receiving item, such as a receive location (with a pipeline), the message decoding and decrypting occurs in a pipeline within this host.

When a host contains a receiving item, such as a receive location or pipeline, it acts as a security boundary, and the message decoding and decrypting occurs in a pipeline within the host. To make the receiving hosts highly available, you must have two or more BizTalk Server computers that are running instances of each receiving host.

Create the following host and host instances:

  • BizTalkServerReceiveHost: All options (Allow Host Tracking”, “32-bits only” or “Make this default host in the group”) should be unselected.
    • All receive handlers, except the isolated ones like SOAP, HTTP, WCF-BasicHttp, WCF-WsHttp or WCF-CustomIsolated and 32 bit adapters (FTP,SQL and POP3) will be configured for this host. This will mean also that all receive locations will run in this host instance.
  • BizTalkServerReceive32Host: has the same goal as the previous however this must have the “32-bits only” option select so that we can run the 32-bits adapters. The receive handlers for the FTP, SQL and POP3 adapters will be configured for this host.
  • BizTalkServerIsolatedHost: The logical container for HTTP, WCF (BasicHttp, CustomIsolated, WebHttp and WSHttp) and SOAP Receive Handlers.

Dedicated Send hosts

Dedicated send hosts are hosts primarily dedicated to sending out information from BizTalk. This host will be responsible for processing messages before they are sent out to the send port. When a host contains a sending item, such as a send port, the message signing and encryption occurs in a pipeline within this host.

A scaled-out sending host makes sure that the sending functionality in BizTalk Server is highly available. If you add multiple computers to a host for sending messages, you can run multiple sending host instances for redundancy and high availability.

Create the following host and host instances:

  • BizTalkServerSendHost: All options (Allow Host Tracking”, “32-bits only” or “Make this default host in the group”) should be unselected.
    • All send handlers, except 32 bit adapters like native SQL and FTP adapter, will be configured for this host. This will mean also that all send ports will run in this host instance.
  • BizTalkServerSend32Host: has the same goal as the previous however this must have the “32-bits only” option select so that we can run the 32-bits adapters.
    • The Send handlers for the FTP and SQL adapters will be configured for this host.

Dedicated Orchestration (or Application) hosts

The dedicated orchestration (or Application) host should only be run for orchestration.  This host will be responsible for process messages based on the instructions in orchestrations that need to run in 32-bits.

A scaled-out processing host improves performance and provides high availability by isolating orchestration functionality onto two or more separate host computers. This isolation lets you add multiple computers to a processing host for redundancy. A processing host in Microsoft BizTalk Server runs one or more host instances that coordinate various business processes and creates an instance of programmatic objects for orchestrations.

Create the following host and host instances:

  • BizTalkServerApplication: Only the option32-bits only” should be selected in this host.
  • BizTalkServerApplication64Host: Only the optionMake this default host in the group” should be selected in this host. This host will be responsible for process messages based on the instructions in all or most common orchestrations.

Note: You can create other Application Hosts if you want to separate process based on application logic.

How can I automate this task?

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 tasks.

This is a simple script to configure the Host, Host Instance and Adapter Handlers described earlier in this post:

Function that will create a new BizTalk Host

function CreateBizTalkHost([string]$hostName, [int]$hostType, [string]$ntGroupName, [bool]$authTrusted, [bool]$isTrackingHost, [bool]$is32BitOnly)
{
    try
    {
        [System.Management.ManagementObject]$objHostSetting = ([WmiClass]"root/MicrosoftBizTalkServer:MSBTS_HostSetting").CreateInstance()
   
        $objHostSetting["Name"] = $hostName
        $objHostSetting["HostType"] = $hostType
        $objHostSetting["NTGroupName"] = $ntGroupName
        $objHostSetting["AuthTrusted"] = $authTrusted
        $objHostSetting["IsHost32BitOnly"] = $is32BitOnly
        $objHostSetting["HostTracking"] = $isTrackingHost
   
        $putOptions = new-Object System.Management.PutOptions
        $putOptions.Type = [System.Management.PutType]::CreateOnly;
   
        [Type[]] $targetTypes = New-Object System.Type[] 1
        $targetTypes[0] = $putOptions.GetType()
   
        $sysMgmtAssemblyName = "System.Management"
        $sysMgmtAssembly = [System.Reflection.Assembly]::LoadWithPartialName($sysMgmtAssemblyName)
        $objHostSettingType = $sysMgmtAssembly.GetType("System.Management.ManagementObject")
   
        [Reflection.MethodInfo] $methodInfo = $objHostSettingType.GetMethod("Put", $targetTypes)
        $methodInfo.Invoke($objHostSetting, $putOptions)
   
        Write-Host "Host $hostName was successfully created" -Fore DarkGreen
    }
    catch [System.Management.Automation.RuntimeException]
    {
        if ($_.Exception.Message.Contains("Another BizTalk Host with the same name already exists in the BizTalk group.") -eq $true)
        {
            Write-Host "$hostName can't be created because another BizTalk Host with the same name already exists in the BizTalk group." -Fore DarkRed
        }
        else{
            write-Error "$hostName host could not be created: $_.Exception.ToString()"
        }
    }
}

Function that will update an existent BizTalk Host

function UpdateBizTalkHost([string]$hostName, [int]$hostType, [string]$ntGroupName, [bool]$authTrusted, [bool]$isTrackingHost, [bool]$is32BitOnly, [bool]$isDefaultHost)
{
    try
    {
        [System.Management.ManagementObject]$objHostSetting = ([WmiClass]"root/MicrosoftBizTalkServer:MSBTS_HostSetting").CreateInstance()
   
        $objHostSetting["Name"] = $hostName
        $objHostSetting["HostType"] = $hostType
        $objHostSetting["NTGroupName"] = $ntGroupName
        $objHostSetting["AuthTrusted"] = $authTrusted
        $objHostSetting["IsHost32BitOnly"] = $is32BitOnly
        $objHostSetting["HostTracking"] = $isTrackingHost
        $objHostSetting["IsDefault"] = $isDefaultHost
   
        $putOptions = new-Object System.Management.PutOptions
        $putOptions.Type = [System.Management.PutType]::UpdateOnly; # This tells WMI it's an update.
   
        [Type[]] $targetTypes = New-Object System.Type[] 1
        $targetTypes[0] = $putOptions.GetType()
   
        $sysMgmtAssemblyName = "System.Management"
        $sysMgmtAssembly = [System.Reflection.Assembly]::LoadWithPartialName($sysMgmtAssemblyName)
        $objHostSettingType = $sysMgmtAssembly.GetType("System.Management.ManagementObject")
   
        [Reflection.MethodInfo] $methodInfo = $objHostSettingType.GetMethod("Put", $targetTypes)
        $methodInfo.Invoke($objHostSetting, $putOptions)
   
        Write-Host "Host $hostName was successfully updated" -Fore DarkGreen
    }
    catch [System.Management.Automation.RuntimeException]
    {
        write-Error "$hostName host could not be updated: $_.Exception.ToString()"
    }
}

Function that will create a new BizTalk Host Instance

function CreateBizTalkHostInstance([string]$hostName, [string]$serverName, [string]$username, [string]$password)
{
    try
    {
        [System.Management.ManagementObject]$objServerHost = ([WmiClass]"root/MicrosoftBizTalkServer:MSBTS_ServerHost").CreateInstance()
   
        $objServerHost["HostName"] = $hostName
        $objServerHost["ServerName"] = $serverName
        $objServerHost.Map()
   
        [System.Management.ManagementObject]$objHostInstance = ([WmiClass]"root/MicrosoftBizTalkServer:MSBTS_HostInstance").CreateInstance()
   
        $name = "Microsoft BizTalk Server " + $hostName + " " + $serverName
        $objHostInstance["Name"] = $name
        $objHostInstance.Install($username, $password, $true)
   
        Write-Host "HostInstance $hostName was mapped and installed successfully. Mapping created between Host: $hostName and Server: $Server);" -Fore DarkGreen
    }
    catch [System.Management.Automation.RuntimeException]
    {
        if ($_.Exception.Message.Contains("Another object with the same key properties already exists.") -eq $true)
        {
            Write-Host "$hostName host instance can't be created because another object with the same key properties already exists." -Fore DarkRed
        }
        else{
            write-Error "$hostName host instance on server $Server could not be created: $_.Exception.ToString()"
        }
    }
}

Function that will delete an existent host handlers in the adapters

function DeleteBizTalkAdapterHandler([string]$adapterName, [string]$direction, [string]$hostName)
{
    try
    {
        if($direction -eq 'Receive')
        {
            [System.Management.ManagementObject]$objHandler = get-wmiobject 'MSBTS_ReceiveHandler' -namespace 'root\MicrosoftBizTalkServer' -filter "HostName='$hostName' AND AdapterName='$adapterName'"
            $objHandler.Delete()
        }
        else
        {
            [System.Management.ManagementObject]$objHandler = get-wmiobject 'MSBTS_SendHandler2' -namespace 'root\MicrosoftBizTalkServer' -filter "HostName='$hostName' AND AdapterName='$adapterName'"
            $objHandler.Delete()
        }
   
        Write-Host "$direction handler for $adapterName / $hostName was successfully deleted" -Fore DarkGreen
    }
    catch [System.Management.Automation.RuntimeException]
    {
        if ($_.Exception.Message -eq "You cannot call a method on a null-valued expression.")
        {
            Write-Host "$adapterName $direction Handler for $hostName does not exist" -Fore DarkRed
        }
        elseif ($_.Exception.Message.IndexOf("Cannot delete a receive handler that is used by") -ne -1)
        {
            Write-Host "$adapterName $direction Handler for $hostName is in use and can't be deleted." -Fore DarkRed
        }
        elseif ($_.Exception.Message.IndexOf("Cannot delete a send handler that is used by") -ne -1)
        {
            Write-Host "$adapterName $direction Handler for $hostName is in use and can't be deleted." -Fore DarkRed
        }
        elseif ($_.Exception.Message.IndexOf("Cannot delete this object since at least one receive location is associated with it") -ne -1)
        {
            Write-Host "$adapterName $direction Handler for $hostName is in use by at least one receive location and can't be deleted." -Fore DarkRed
        }
        else
        {
            write-Error "$adapterName $direction Handler for $hostName could not be deleted: $_.Exception.ToString()"
        }
    }
}

Function that will create a handler for a specific adapter on the host

function CreateBizTalkAdapterHandler([string]$adapterName, [string]$direction, [string]$hostName, [string]$originalDefaulHostName, [boolean]$isDefaultHandler, [boolean]$removeOriginalHostInstance)
{
    if($direction -eq 'Receive')
    {
        [System.Management.ManagementObject]$objAdapterHandler = ([WmiClass]"root/MicrosoftBizTalkServer:MSBTS_ReceiveHandler").CreateInstance()
        $objAdapterHandler["AdapterName"] = $adapterName
        $objAdapterHandler["HostName"] = $hostName
    }
    else
    {
        [System.Management.ManagementObject]$objAdapterHandler = ([WmiClass]"root/MicrosoftBizTalkServer:MSBTS_SendHandler2").CreateInstance()
        $objAdapterHandler["AdapterName"] = $adapterName
        $objAdapterHandler["HostName"] = $hostName
        $objAdapterHandler["IsDefault"] = $isDefaultHandler
    }
   
    try
    {
        $putOptions = new-Object System.Management.PutOptions
        $putOptions.Type = [System.Management.PutType]::CreateOnly;
   
        [Type[]] $targetTypes = New-Object System.Type[] 1
        $targetTypes[0] = $putOptions.GetType()
   
        $sysMgmtAssemblyName = "System.Management"
        $sysMgmtAssembly = [System.Reflection.Assembly]::LoadWithPartialName($sysMgmtAssemblyName)
        $objAdapterHandlerType = $sysMgmtAssembly.GetType("System.Management.ManagementObject")
   
        [Reflection.MethodInfo] $methodInfo = $objAdapterHandlerType.GetMethod("Put", $targetTypes)
        $methodInfo.Invoke($objAdapterHandler, $putOptions)
   
        Write-Host "$adapterName $direction Handler for $hostName was successfully created" -Fore DarkGreen
    }
    catch [System.Management.Automation.RuntimeException]
    {
        if ($_.Exception.Message.Contains("The specified BizTalk Host is already a receive handler for this adapter.") -eq $true)
        {
            Write-Host "$hostName is already a $direction Handler for $adapterName adapter." -Fore DarkRed
        }
        elseif($_.Exception.Message.Contains("The specified BizTalk Host is already a send handler for this adapter.") -eq $true)
        {
            Write-Host "$hostName is already a $direction Handler for $adapterName adapter." -Fore DarkRed
        }
        else {
            write-Error "$adapterName $direction Handler for $hostName could not be created: $_.Exception.ToString()"
        }
    }
   
    if($removeOriginalHostInstance)
    {
        DeleteBizTalkAdapterHandler $adapterName $direction $originalDefaulHostName
    }
}

Function that will have the creation logic

Function that implement the creation and configuration logic of hosts, host instances and add configure the host instances to the various handlers that you want to implement.

function ConfiguringBizTalkServerHostAndHostInstances
{
    # Separate sending, receiving, processing, and tracking functionality into multiple hosts.
    # This provides flexibility when configuring the workload and enables you to stop one host without affecting other hosts.
    # you can use a common well use convention to define the name of the host:
    #  - <Job>_<bit support>_<seq>_<adapter/functionality>_<throughput>_<priority>_<clustered>
    # Sample 'Rcv_x32_1_FTP_L_Critical_Clustered'
    # But I will use a more simple convention
    # Defining the names of the hosts
    [string]$receiveHostName = 'BizTalkServerReceiveHost'
    [string]$sendHostName = 'BizTalkServerSendHost'
    [string]$processingHostName = 'BizTalkServerApplication64Host' # use this to create another processing host
    [string]$trackingHostName = 'BizTalkServerTrackingHost'
    # Note: why we need to create 32bits hosts? FTP, POP3 and SQL doesn't support 64bits
    [string]$receive32HostName = 'BizTalkServerReceive32Host'
    [string]$send32HostName = 'BizTalkServerSend32Host'
   
    # 'BizTalkServerApplication' is the default host instance created when you install the biztalk on your box.
    # This application will be running on "32-bit only".
    [string]$defaultHostName = 'BizTalkServerApplication'
   
    ##############################
    # Creating hosts for receiving
    # HostType: Invalid: 0, In-process: 1, Isolated: 2
    CreateBizTalkHost $receiveHostName 1 $ntHostGroupName $false $false $false
    CreateBizTalkHost $receive32HostName 1 $ntHostGroupName $false $false $true
   
    # Create a host instances for receiving associated with the previous hosts created
    CreateBizTalkHostInstance $receiveHostName $bizTalkServerName $hostCredentials.UserName $hostCredentialsPassword
    CreateBizTalkHostInstance $receive32HostName $bizTalkServerName $hostCredentials.UserName $hostCredentialsPassword
   
    # Set adapters that should be handled by receiving host instance
    CreateBizTalkAdapterHandler 'FILE' 'Receive' $receiveHostName $defaultHostName $false $removeOriginalAdapterHandler
    CreateBizTalkAdapterHandler 'MQSeries' 'Receive' $receiveHostName $defaultHostName $false $removeOriginalAdapterHandler
    CreateBizTalkAdapterHandler 'MSMQ' 'Receive' $receiveHostName $defaultHostName $false $removeOriginalAdapterHandler
    CreateBizTalkAdapterHandler 'WCF-Custom' 'Receive' $receiveHostName $defaultHostName $false $removeOriginalAdapterHandler
    CreateBizTalkAdapterHandler 'WCF-NetMsmq' 'Receive' $receiveHostName $defaultHostName $false $removeOriginalAdapterHandler
    CreateBizTalkAdapterHandler 'WCF-NetNamedPipe' 'Receive' $receiveHostName $defaultHostName $false $removeOriginalAdapterHandler
    CreateBizTalkAdapterHandler 'WCF-NetTcp' 'Receive' $receiveHostName $defaultHostName $false $removeOriginalAdapterHandler
    CreateBizTalkAdapterHandler 'Windows SharePoint Services' 'Receive' $receiveHostName $defaultHostName $false $removeOriginalAdapterHandler
    #32 bits adapters
    CreateBizTalkAdapterHandler 'FTP' 'Receive' $receive32HostName $defaultHostName $false $removeOriginalAdapterHandler
    CreateBizTalkAdapterHandler 'POP3' 'Receive' $receive32HostName $defaultHostName $false $removeOriginalAdapterHandler
    CreateBizTalkAdapterHandler 'SQL' 'Receive' $receive32HostName $defaultHostName $false $removeOriginalAdapterHandler
   
    ##############################
    # Creating hosts for sending
    # HostType: Invalid: 0, In-process: 1, Isolated: 2
    CreateBizTalkHost $sendHostName 1 $ntHostGroupName $false $false $false
    CreateBizTalkHost $send32HostName 1 $ntHostGroupName $false $false $true
   
    # Create a host instances for sending associated with the previous hosts created
    CreateBizTalkHostInstance $sendHostName $bizTalkServerName $hostCredentials.UserName $hostCredentialsPassword
    CreateBizTalkHostInstance $send32HostName $bizTalkServerName $hostCredentials.UserName $hostCredentialsPassword
   
    # Set adapters that should be handled by sending host instance
    CreateBizTalkAdapterHandler 'FILE' 'Send' $sendHostName $defaultHostName $true $removeOriginalAdapterHandler
    CreateBizTalkAdapterHandler 'HTTP' 'Send' $sendHostName $defaultHostName $true $removeOriginalAdapterHandler
    CreateBizTalkAdapterHandler 'MQSeries' 'Send' $sendHostName $defaultHostName $true $removeOriginalAdapterHandler
    CreateBizTalkAdapterHandler 'MSMQ' 'Send' $sendHostName $defaultHostName $true $removeOriginalAdapterHandler
    CreateBizTalkAdapterHandler 'SOAP' 'Send' $sendHostName $defaultHostName $true $removeOriginalAdapterHandler
    CreateBizTalkAdapterHandler 'SMTP' 'Send' $sendHostName $defaultHostName $true $removeOriginalAdapterHandler
    CreateBizTalkAdapterHandler 'WCF-BasicHttp' 'Send' $sendHostName $defaultHostName $true $removeOriginalAdapterHandler
    CreateBizTalkAdapterHandler 'WCF-Custom' 'Send' $sendHostName $defaultHostName $true $removeOriginalAdapterHandler
    CreateBizTalkAdapterHandler 'WCF-NetMsmq' 'Send' $sendHostName $defaultHostName $true $removeOriginalAdapterHandler
    CreateBizTalkAdapterHandler 'WCF-NetNamedPipe' 'Send' $sendHostName $defaultHostName $true $removeOriginalAdapterHandler
    CreateBizTalkAdapterHandler 'WCF-NetTcp' 'Send' $sendHostName $defaultHostName $true $removeOriginalAdapterHandler
    CreateBizTalkAdapterHandler 'WCF-WSHttp' 'Send' $sendHostName $defaultHostName $true $removeOriginalAdapterHandler
    CreateBizTalkAdapterHandler 'Windows SharePoint Services' 'Send' $sendHostName $defaultHostName $true $removeOriginalAdapterHandler
    #32 bits adapters
    CreateBizTalkAdapterHandler 'FTP' 'Send' $send32HostName $defaultHostName $true $removeOriginalAdapterHandler
    CreateBizTalkAdapterHandler 'SQL' 'Send' $send32HostName $defaultHostName $true $removeOriginalAdapterHandler
   
    # Create a host for tracking
    CreateBizTalkHost $trackingHostName 1 $ntHostGroupName $false $true $false
   
    # Create a host for orchestrations
    CreateBizTalkHost $processingHostName 1 $ntHostGroupName $false $false $false
   
    # Create a host instance for orchestrations
    CreateBizTalkHostInstance $processingHostName $bizTalkServerName $hostCredentials.UserName $hostCredentialsPassword
   
    # Create a host instance for tracking
    CreateBizTalkHostInstance $trackingHostName $bizTalkServerName $hostCredentials.UserName $hostCredentialsPassword
   
    # Remove "Allow Host Tracking" options from BizTalkServerApplication Host
    UpdateBizTalkHost $defaultHostName 1 $ntHostGroupName $false $false $true $true
   
    # Updating the processinh host to be the default host
    UpdateBizTalkHost $processingHostName 1 $ntHostGroupName $false $false $false $true
}

Sample of the main script

Write-Host "Starting configure the BizTalk Server environment..." -Fore DarkGreen
   
# General variables
# Defining the BizTalk Server Name, this line will read the Server name on which the script is running
$bizTalkServerName = $(Get-WmiObject Win32_Computersystem).name
   
# STEP 1
# The Windows group is used to control access of a specific host and associated host instances to databases and other
# resources. Each instance of this host must run under a user account that is a member of this group.
# Note that you can change the Windows group only if no instances of this host exist.
# Defining the name of the group the BizTalk hosts should run under
[string]$ntHostGroupName = Read-Host -Prompt "Please enter windows group to control access to Hosts and ssociated Host Instances"
   
# STEP 2
# This account must have SQL Server permissions. The recommended way to grant these permissions is to add this account
# to the BizTalk Server Host Windows group.
# BizTalk Server will add this account to the "Log on as a service" security policy.
# For domain accounts, use "domain\user" format
# Defining the credentials in which the host instance should run under.
try
{
    $domain = [System.DirectoryServices.ActiveDirectory.Domain]::GetCurrentDomain()
    $domainName = $domain.name
}
catch
{
    $domainName = $(Get-WmiObject Win32_Computersystem).name
}
$hostCredentials = $Host.ui.PromptForCredential("Logon Credentials","This account must have SQL Server permissions. The recommended way to grant these permissions is to add this account to the BizTalk Server Host Windows group.
   
BizTalk Server will add this account to the 'Log on as a service' security policy", $domainName + "\", "");
[String]$hostCredentialsPassword = [Runtime.InteropServices.Marshal]::PtrToStringAuto([Runtime.InteropServices.Marshal]::SecureStringToBSTR($hostCredentials.Password));
   
# STEP 3
# Defining the option if you want to automatically try to remove the BizTalkServerApplication Host Instance from
# the Adapters handlers
$windowsShell = new-object -comobject wscript.shell
$questionResult = $windowsShell.popup("Do you want to try to remove the BizTalkServerApplication Host Instance from the Adapters handlers?
   
Note: The script cannot remove the default host instances if there are any receiveports, sendports or orchestrations configured.",
                          0,"BizTalk Applications, Receive and Send Ports",4)
   
If ($questionResult -eq 6) {
    $removeOriginalAdapterHandler = $true
}
else {
    $removeOriginalAdapterHandler = $false
}
   
# STEP 4
# Create default hosts, host instances and handlers
Write-Host "Creating hosts and host instances..." -Fore DarkGreen
ConfiguringBizTalkServerHostAndHostInstances
   
# STEP 5
# This configurations changes requires host instances restart for the changes to take effect.
# Check if you want to restart the Host Instances
Write-Host "Host and Host Instance configuration is almost completed..." -Fore DarkGreen
$questionResult = $windowsShell.popup("This configurations changes requires host instances restart for the changes to take effect.
   
Do you want to restart the Host Instances now?", 0,"Please restart Host Instances",4)
If ($questionResult -eq 6) {
    get-service BTS* | foreach-object -process {restart-service $_.Name}
    Write-Host "Restart Host Instance completed..." -Fore DarkGreen
}
   
# STEP 6
# Check if you want to properly configure BizTalk Services and Enterprise Single Sign-On Service 'Startup type' property
# to Automatic (Delayed Start)
$questionResult = $windowsShell.popup("By default, the 'Startup type' propriety of BizTalk Services and Enterprise Single Sign-On Service are set as 'Automatic', however BizTalk Server services may not start automatically after a system restart, to avoid this behavior you must config the 'Startup type' to 'Automatic (Delayed Start)'.
   
Do you want to configure BizTalk Services to 'Automatic (Delayed Start)'?", 0,"Configure BizTalk Services to Automatic (Delayed Start)",4)
If ($questionResult -eq 6) {
    #=== Name of the Enterprise Single Sign-On Service. ===#
    $entSSOServiceName = 'ENTSSO'
   
    #=== Change the startup type for BizTalk services to Automatic (Delayed Start) ===#
    get-service BTSSvc* | foreach-object -process { SC.EXE config $_.Name start= delayed-auto}
   
    #=== Change the startup type for Enterprise Single Sign-On Service to Automatic (Delayed Start) ===#
    SC.EXE config $entSSOServiceName start= delayed-auto
   
    Write-Host "BizTalk Services and SSO configured successfully..." -Fore DarkGreen
}
   
Write-Host "Your BizTalk Server environment is now properly configured" -Fore DarkGreen

The script can be found and download on Microsoft TechNet Gallery: PowerShell to Configure BizTalk Server Host and Host Instances

Common Questions

1. After configuring receive ports or send port do I need to restart the BizTalk Services to changes take effect?

All the Receive Ports, Receive Locations and Send Port configuration is pushed out to all hosts (isolated and non-isolated) on a cache refresh schedule. In this case there isn't any reason to ever restart a host due to a configuration change.

If you find yourself waiting too long for the host settings to take effect, it might be because the default configuration cache refresh frequency is set to 60 seconds. One trick to overcome this behavior is to reduce the refresh frequency. Here's how.

See Also

Read suggested related topics:

Another important place to find  an extensive amount of BizTalk related articles is the TechNet Wiki itself. The best entry point is BizTalk Server Resources on the TechNet Wiki.