BizTalk Deployment-Automatisierung mit Powershell

07.08.2018

Einer unserer Kunden, der mehrere BizTalk Server mit verschiedenen Konfigurationen im Einsatz hat, wollte eine Deployment-Automatisierung dieser Server. Die Ziele: Zeit sparen, die Fehleranfälligkeit durch manuelle Konfiguration senken, den sogenannten Bus-Faktor (https://de.wikipedia.org/wiki/Truck_Number) senken und im Fehlerfall „Rollbacks“ ermöglichen.

Dafür sollte nur auf PowerShell sowie die mitgelieferten Tools und Bibliotheken zurückgegriffen werden. Sprich: Um die Abhängigkeiten niedrig zu halten, waren Tools oder Bibliotheken Dritter von vornherein ausgeschlossen.

Bevor ich auf die von uns gewählte Lösung eingehe, hier noch eine kleine Einschränkung: Aus Gründen der Einfachheit wird jedes Mal ein Full-Deployment gemacht, d.h. alles wird immer komplett entfernt und dann wieder neu hinzugefügt. Uns ist bewusst, dass er gerade den Zeitfaktor des Deployments nach oben treibt, jedoch aber verhindert, dass zuvor ungetestete Kombinationen, die durch manuelle Änderungen ins System gelangt sind, ausgerollt werden.

Für unsere Lösung haben wir folgenden Tools und Bibliotheken benutzt:

  • PowerShell 5.0 (x86 / x64)
  • WMI
  • BizTalkfactory.PowerShell.Extensions
  • System.EnterpriseServices.Internal.Publish
  • Microsoft.BizTalk.ExplorerOM
  • Btstask

Für die Konfiguration unseres Deployments gibt es eine simple XML-Konfigurationsdatei.

Mittels „@@[Key]@@“ werden später Werte eingesetzt, die aus einem Key-Value-Store kommen und die für jeden Rechner anders sind. Dadurch kann jeder Server individuell konfiguriert werden, ohne das sich die Grundstruktur des Deployments unterscheidet.

<DeployConfig>

<Host Name="AutoDeployTestBizTalkServerApplication" HostType="InProcess"

NtGroupName="@@Host_BizTalkServerPrc_GroupName@@" Delete="false">

<Property Name="IsDefault" Value="false" />

<Property Name="IsHost32BitOnly" Value="false" />

<Property Name="HostTracking" Value="false" />

<Property Name="AuthTrusted" Value="false" />

<Property Name="GlobalMemoryThreshold" Value="0" />

<Property Name="ProcessMemoryThreshold" Value="50" />

<HostInstance ServerName="@@Host_BizTalkServerPrc_HostInstance_ServerName@@" Logon="@@Host_BizTalkServerPrc_HostInstance_Username@@" Password="@@Host_BizTalkServerPrc_HostInstance_Password@@" Delete="false" Start="false" >

<Property Name="IsDisabled" Value="false"/>

</HostInstance>

</Host>

 

<BizTalkApplication Name="TFS-Deploy-Test" Description="TFS-Deploy-Test" Delete="true">

<Resource Path="TFS-Deploy-Test.dll" />

<Binding Path="TFS-Deploy-Test.BindingInfo.xml">

<Replacement

NodeXPath="//SendPort[@Name = 'SP_Output']/PrimaryTransport/Address"

ValuePattern="^.*$"

ValueReplacement="@@BizTalkApplication_SendPortAddress@@" />

<Replacement

NodeXPath="//ReceiveLocation[@Name = 'RPL_Input']/Address"

ValuePattern="^.*$"

ValueReplacement="@@BizTalkApplication_ReceivePortAddress@@" />

</Binding>

</BizTalkApplication>

</DeployConfig>


Ablauf des Deployment-Skripts
 

  1. X86 PowerShell starten da die BizTalkFactory.Powershell.Extensions leider nicht für x64 zur Verfügung stehen
  2. BizTalkFactory.PowerShell.Extensions.dll installieren
    ."$env:windir\Microsoft.NET\Framework\v4.0.30319\InstallUtil.exe" "$env:BTSINSTALLPATH\SDK\Utilities\PowerShell\BizTalkFactory.PowerShell.Extensions.dll"
  3. Konfigurations-Datei einlesen und die Wertersetzungen vornehmen
  4. Alle in der Konfigurations-Datei gelisteten BizTalk Applikationen, sofern die bereits bestehen, entfernen
    1. Alle noch laufenden Service Instanzen stoppen
      1. Mittels “BizTalk:\Health and Activity\Service Instances” alle noch laufenden Instanzen zu der Applikation finden
      2. “Terminate-ServiceInstance” auf diese Instanze aufrufen
    2. Alle noch nicht „unenlisted“ Orchestrierungen unenlisten
      1. Mittels “Biztalk:\Applications\$ApplicationName\Orchestrations\” alle noch nicht „unenlisted“ Orchestrations zu der Applikation finden
      2. “ Unenlist-Orchestration” auf diese Orchestrations aufrufen
    3. Alle noch nicht „unenlisted“ SendPorts unenlisten
      1. Mittels “Biztalk:\Applications\$ApplicationName\Send Ports\” alle noch nicht „unenlisted“ SendPorts zu der Applikation finden
      2. “ Unenlist- SendPort” auf diese SendPorts aufrufen
    4. Die Applikation entfernen
      1. Mittels BTSTask die Applikation entfernen da BizTalkFactory.PowerShell.Extensions leider kein equivalent anbietet
        „btstask RemoveApp“
    5. GAC bereinigen
      1. Assemblies aus dem GAC entfernen
        „System.EnterpriseServices.Internal.Publish.GacRemove(…)“
  5. Alle in der Konfigurations-Datei gelisteten BizTalk Hosts sofern die bereits bestehen diese entfernen
    1. Alle Adapterhandler entfernen
      1. “DeleteAdapterHandler” aufrufen für jeden gelisteten Adapter der Hostinstanz
    2. Alle Hostinstanzen entfernen
      1. “DeleteHostInstance” aufrufen für jede gelistete Instanz des Hosts
    3. Alle Hosts entfernen
      1. “DeleteHost” aufrufen für jeden gelisteten Host
  6. Alle in der Konfigurations-Datei gelisteten BizTalk Hosts wieder hinzufügen
    1. Host hinzufügen
      1. Mit Hilfe des Microsoft.BizTalk.ExplorerOM eine neue Instance von „root/MicrosoftBizTalkServer:MSBTS_HostSetting“ anlegen und hinzufügen
      2. Eine neue Instanz von „root/MicrosoftBizTalkServer:MSBTS_ServerHost“ anlegen und hinzufügen sofern sie noch nicht existiert, bzw. nicht „IsMapped=‘True‘“ ist
    2. Hostinstanz hinzufügen
      1. Eine neue Instanz von „root/MicrosoftBizTalkServer:MSBTS_HostInstance“ anlegen
      2. Die Install-Methode auf diese Instanz aufrufen um die Instanz unter einen anderen Nutzer laufen zulassen
      3. Die zugehörige Instanz von „root/MicrosoftBizTalkServer: MSBTS_HostInstanceSetting“ mittels WMI-Query holen und alle Einstellungen der Hostinstanz setzen
      4. Die Hostinstanz starten
        „Start-HostInstance“
    3. Adapterhandler hinzufügen
      1. Den Adapternamen nach folgendem Schema bestimmen “$($adapter.Type) $($adapter.Direction) Handler ($($hostItem.Name))“
      2. Neue Instanz unter “BizTalk:\Platform Settings\Adapters\$($adapter.Type)” anlegen
        “New-Item”
      3. Die Individuelleneinstellungen des Adapters setzen
        „Set-ItemProperty”
  7. Alle in der Konfigurations-Datei gelisteten BizTalk Applikationen wieder hinzufügen
    1. BizTalk Applikation hinzufügen
      1. Mittels BTSTask die Applikation hinzufügen da BizTalkFactory.PowerShell.Extensions leider kein equivalent anbietet „btstask AddApp“
    2. Gegebenenfalls die benötigten Ressourcen hinzufügen
      1. Die Ressource zur BizTalk Applikation hinzufügen
        “Add-ApplicationResource”
      2. Nicht vergessen die Assembly auch zum GAC hinzuzufügen „System.EnterpriseServices.Internal.Publish.GacInstall(…)“
    3. Gegebenenfalls die benötigten Applikationsreferenzen hinzufügen
      1. Die Referenz zur BizTalk Applikation hinzufügen
        “Add-ApplicationReference”
    4. Binding importieren
      1. Da das Binding auf jeden Rechner etwas anders sein soll führen wir die in der Konfigurations-Datei definierten Ersetzungen durch
      2. Die Bindings zur BizTalk Applikation einbinden
        “Import-Bindings”
    5. BizTalk Applikation starten
      „Start-Application”
  8. Sofern keine Fehler aufgetreten sind und auch „$error“ leer ist sollte die neue Version ihrer BizTalk Platformsettings und Applikationen da sein und laufen

Nachwort

Unsere letztendliche Lösung war noch etwas umfassender, da der Kunde auch noch QUIBIF von uns eingesetzte, was wiederum bedeutete das noch ein paar Handgriffe mehr nötig waren wie z.B. QUIBIF sowie IIS konfigurieren oder auch DacPacs einspielen.
Für die Zukunft ist angedacht auch ein inkrementelles Deployment zu ermöglichen, aber mit dem ersten Schritt war unser Kunde schon sehr zufrieden. 

Wenn Sie Interesse habe ihre BizTalk Anwendungen ebenfalls automatisiert zu deployen, sprechen sie uns gerne an, wir helfen ihnen.

 

 

 

zurück