Showing posts with label BizTalkExplorerOM. Show all posts
Showing posts with label BizTalkExplorerOM. Show all posts

Tuesday, November 15, 2016

Update all binding thumbprints

We have 20+ applications and have to update to a new certificate. To avoid having to do a new build and release of all of these applications, some of which haven't been updated for some time, I chose to create a powershell script to update all send ports on the fly.

The script does not stop or start host instances. This could easily be incorporated; check my other blog entry on starting and stopging host instances.

The script uses the BizTalk ExplorerOM to access the settings which means nothing extra needs to be installed on the BizTalk servers.

This script looks long because it includes so much confirmation in the way of output for testing before the final run. The real logic is only 8 lines, including 4 lines of variable declarations.

This example changes two thumbprints at once. It could easily be modified up or down.

$oldClientCert = "ee aa bb 11 22 33 44 55 66 77 88 99 00 ff dd cc ab cd ef 01"
$newClientCert = "ne wt hu mb pr in tg oe si nh er e0 00 00 00 00 00 00 00 00"
$oldServiceCert = "aa bb cc dd ee ff 00 11 22 33 44 55 66 77 88 99 12 23 34 56"
$newServiceCert = "34 2a 15 53 3e 7d 6a 0c 51 20 e4 50 6b 53 df 72 84 55 aa 6a"
  
[void] [System.reflection.Assembly]::LoadWithPartialName("Microsoft.BizTalk.ExplorerOM")  
$Catalog = New-Object Microsoft.BizTalk.ExplorerOM.BtsCatalogExplorer  
$Catalog.ConnectionString = "SERVER=DBINSTANCENAME;DATABASE=BizTalkMgmtDb;Integrated Security=SSPI"

#EnumerateSendPorts $Catalog  
 $port = $catalog.SendPorts[1]
 Write-host "B4 ----> " $port.PrimaryTransport.TransportTypeData

 $catalog.SendPorts | % {

# Line below replaces thumbprints  - UPDATES ORIGINAL VALUE - BUT NO SAVE
$_.PrimaryTransport.TransportTypeData=_
($_.PrimaryTransport.TransportTypeData.Replace($oldServiceCert,$newServiceCert)).Replace($oldClientCert,$newClientCert);

# Line below replaces thumbprints and prints out the new TransportTypeData string - NO UPDATE TO ORIGINAL VALUE
#($_.PrimaryTransport.TransportTypeData.Replace($oldServiceCert,$newServiceCert)).Replace($oldClientCert,$newClientCert);
   }
$port = $catalog.SendPorts[1] 
Write-host "After ----> " $port.PrimaryTransport.TransportTypeData

#No changes are saved until the following line is run
$Catalog.SaveChanges(); 

When testing comment out the the last line to skip saving the updates. To just output the updates, comment out the row updating the original value and uncomment the No Update line.

Don't forget to change the connection string to point to the correct management database instance!

Blog software may force some line breaks - and I added one underscore (_) to indicate I broke the line there.

Friday, October 18, 2013

Powershell to create BizTalk applications with references

The latest script to undergo migration to powershell is my application creation script. Our applications have references to each other so this script takes command line parameters for the application name and the references. If the application already exists the references will be added.

As usual for my latest blog entries, this script uses WMI and the BizTalk ExplorerOM. I also have minimized the error handling in order make the code easier to read.

Watch out for line wrapping from the blog software!
# define parameters: $app is application name
# $ref is a comma delimited string of references to create "Common,Schemas"
param([string] $app, [string[]] $ref)
 
 # Get local BizTalk DBName and DB Server from WMI
 $btsSettings = get-wmiobject MSBTS_GroupSetting -namespace 'root\MicrosoftBizTalkServer'
 $dbInstance = $btsSettings.MgmtDbServerName
 $dbName = $btsSettings.MgmtDbName
 
 # Load BizTalk ExplorerOM
 [void] [System.reflection.Assembly]::LoadWithPartialName("Microsoft.BizTalk.ExplorerOM")
 $BizTalkOM = New-Object Microsoft.BizTalk.ExplorerOM.BtsCatalogExplorer
 $BizTalkOM.ConnectionString = "SERVER=$dbInstance;DATABASE=$dbName;Integrated Security=SSPI"

#check incoming parameter for application name exists
 if (! $app)
{ 'Syntax is: Add_References -app "NewAppName" -ref Common,Schemas'; exit}

#create the application if it doesn't exist already 
if ($BizTalkOM.Applications[$app] -eq $null)
{
   $result =( btstask addapp /application:$app)
   "btstask result:" + $result
   $BizTalkOM.Refresh()
}

#add application references
foreach ($reference in $ref)
{
   "adding reference to " + $reference
   $BizTalkOM.Applications[$app].AddReference($BizTalkOM.Applications[$reference])
}

# Commit changes
$BizTalkOM.SaveChanges()  

I couldn't find a way to add an application without using btstask. Let me know if you know of a way, without using the Powershell Provider.

Friday, October 4, 2013

Powershell scripts to stop/start BizTalk Applications

We are finally almost finished with a migration project from BizTalk 2006 to BizTalk 2010. Some of my 'tools' need updating. First up is my application start/stop utility since this is the only one that flat out doesn't work.

Out of curiosity I wanted to test different methods of accessing the BizTalk applications. WMI was automatically out because it doesn't expose BizTalk applications. My options were using the BizTalk Explorer OM which is part of the BizTalk installation or the BizTalkFactory Powershell Provider on CodePlex which requires an installation. It is pretty common for production environments to have strict limitations on what third-party code can be installed so the BizTalkFactory route is not always an option.

This first example uses the BizTalk Explorer OM. Beware of line wrapping from the blog software.

# declare -stop -start switch parameters
param([switch] $start, [switch] $stop)
 
 # Get local BizTalk DBName and DB Server from WMI
 $btsSettings = get-wmiobject MSBTS_GroupSetting -namespace 'root\MicrosoftBizTalkServer'
 $dbInstance = $btsSettings.MgmtDbServerName
 $dbName = $btsSettings.MgmtDbName
 
 # Load BizTalk ExplorerOM
 [void] [System.reflection.Assembly]::LoadWithPartialName("Microsoft.BizTalk.ExplorerOM")
 $BizTalkOM = New-Object Microsoft.BizTalk.ExplorerOM.BtsCatalogExplorer
 $BizTalkOM.ConnectionString = "SERVER=$dbInstance;DATABASE=$dbName;Integrated Security=SSPI"


 if ($stop)
 {
   $BizTalkOM.Applications | where-object{$_.status -eq "started"}  | ForEach-Object{ $_.stop("StopAll")}
   $BizTalkOM.SaveChanges()  
 } 
 if ($start)
 {
   $BizTalkOM.Applications | where-object{$_.status -eq "stopped"}  | ForEach-Object{ $_.start("StartAll")}
   $BizTalkOM.SaveChanges()  
 }
 
The very first line sets up parameters so this script can be called with a -start or -stop switch (or both for a restart).

I prefer to have universal scripts that find their own BizTalk databases without hardcoding server names into scripts since we have multiple enironments. In this case I get the database server and management database information from WMI.

The next step is to load the BizTalk ExplorerOM and connect it to the BizTalk database.

Finally the applications are filtered on their status and then stopped or started using the ForEach-Object. Once all applications have been set to stop or start call SaveChanges to actually commit the start or stop.

The following example demonstrates using the BizTalkFactory PowerShell Provider.
# declare -start -stop switch parameters
param([switch] $start, [switch] $stop)

 # Get local BizTalk DBName and DB Server from WMI
 $btsSettings = get-wmiobject MSBTS_GroupSetting -namespace 'root\MicrosoftBizTalkServer'
 $dbInstance = $btsSettings.MgmtDbServerName
 $dbName = $btsSettings.MgmtDbName
 
 new-psdrive -name Biztalk -psprovider Biztalk -root biztalk:\ -instance $dbInstance -database $dbName

 if ($stop) { get-childitem -path biztalk:\applications\* | where-object {$_.status -eq "started"} | stop-application }
 
 if ($start) { get-childitem -path biztalk:\applications\* | where-object {$_.status -eq "stopped"} | start-application }
This script sets up the BizTalkFactory PowerShell Provider instead of the BizTalkExplorerOM.

The other difference is piping the filtered applications into the BizTalkFactory PowerShell Provider stop and start methods rather than the foreach-object loop.
Both of these scripts are pretty compact so the deciding factor becomes whether the BizTalkFactory PowerShell Provider is even an option in a specific environment.


I have a third version that follows a pattern Tomas Restrepo uses for starting and stopping host instances.

I mainly like this pattern because it allows for checking the status of an application just before starting or stopping it. In the previous examples the where-object returns a collection of applications which may be dependent on each other so some of them may be started already earlier in the loop.

In this example, I also added the functionality for specifying a specific application. Note the change to the parameter definition and the new get-applications function. If no application is specified then all applications will be processed.

# declare -stop -start switch parameters
param([switch] $start, [switch] $stop, [string] $app)
 
 function start-application($application)
 {
    # If the application is stopped, start it.
    if ( $application.status -eq "Stopped")
    {
      "Starting application " + $application.name
      $application.Start("StartAll")
    }
 }

 function stop-application($application)
 {
    # If the application is started, stop it.
    if ( $application.status -eq "Started")
    {
      "Stopping application " + $application.name
      $application.Stop("StopAll")
    }
 }

 function get-applications()
 {
    #if there is an application specified in the command line parameter, return just that application
    if ($app)
      { return $BizTalkOM.Applications[$app] }
    else
      { return $BizTalkOM.Applications }
 }

 # Get local BizTalk DBName and DB Server from WMI
 $btsSettings = get-wmiobject MSBTS_GroupSetting -namespace 'root\MicrosoftBizTalkServer'
 $dbInstance = $btsSettings.MgmtDbServerName
 $dbName = $btsSettings.MgmtDbName
 
 # Load BizTalk ExplorerOM
 [void] [System.reflection.Assembly]::LoadWithPartialName("Microsoft.BizTalk.ExplorerOM")
 $BizTalkOM = New-Object Microsoft.BizTalk.ExplorerOM.BtsCatalogExplorer
 $BizTalkOM.ConnectionString = "SERVER=$dbInstance;DATABASE=$dbName;Integrated Security=SSPI"

 # if no commandline parameters are supplied do a stop and a start
 if ( !($stop) -and !($start) )
 {
    $stop = $true
    $start = $true
 } 

 if ($stop) 
{
   get-applications | %{stop-application($_)}
   
   # Commit changes
   $BizTalkOM.SaveChanges()  
  }

 
 if ($start)
 {
   get-applications | %{start-application($_)}

   # Commit changes
   $BizTalkOM.SaveChanges()  
 }
Just like the other scripts I use stop and start switch parameters and WMI to find out what BizTalk database to use. The stop and start functions give the opportunity to do a little more with each application object. I could have crammed them into one liners but they would not have been as easy to read. Since PowerShell is not very wide-spread where I work readability is important. The drawback is it makes the script look more complicated.