Luca Zavarella Blog

How to update all the SSIS packages’ Connection Managers in a BIDS project with PowerShell

During the development of a BI solution, we all know that 80% of the time is spent during the ETL (Extract, Transform, Load) phase. If you use the BI Stack Tool provided by Microsoft SQL Server, this step is accomplished by the development of n Integration Services (SSIS) packages. In general, the number of packages made ​​in the ETL phase for a non-trivial solution of BI is quite significant.

An SSIS package, therefore, extracts data from a source, it "hammers" :) the data and then transfers it to a specific destination. Very often it happens that the connection to the source data is the same for all packages. Using Integration Services, this results in having the same Connection Manager (perhaps with the same name) for all packages:

The source data of my BI solution comes from an Helper database (HLP), then, for each package tha import this data, I have the HLP Connection Manager (the use of a Shared Data Source is not recommended, because the Connection String is wired and therefore you have to open the SSIS project and use the proper wizard change it...). In order to change the HLP Connection String at runtime, we could use the Package Configuration, or we could run our packages with DTLoggedExec by Davide Mauri (a must-have if you are developing with SQL Server 2005/2008). But my need was to change all the HLP connections in all packages within the SSIS Visual Studio project, because I had to version them through Team Foundation Server (TFS).

A good scribe with a lot of patience should have changed by hand all the connections by double-clicking the HLP Connection Manager of each package, and then changing the referenced server/database:

Not being endowed with such virtues :) I took just a little of time to write a small script in PowerShell, using the fact that a SSIS package (a .dtsx file) is nothing but an xml file, and therefore can be changed quite easily. I'm not a guru of PowerShell, but I managed more or less to put together the following lines of code:

$LeftDelimiterString = "Initial Catalog="
$RightDelimiterString = ";Provider="
$ToBeReplacedString = "AstarteToBeReplaced"
$ReplacingString = "AstarteReplacing"
$MainFolder = "C:\MySSISPackagesFolder"

$files = get-childitem "$MainFolder" *.dtsx `
      | Where-Object {!($_.PSIsContainer)}

foreach ($file in $files)
{
      (Get-Content $file.FullName)
`
            | % {$_ -replace "($LeftDelimiterString)($ToBeReplacedString)($RightDelimiterString)", "`$1$ReplacingString`$3"}
`
| Set-Content $file.FullName;
}

The script above just opens any SSIS package (.dtsx) in the supplied folder, then for each of them goes in search of the following text:

Initial Catalog=AstarteToBeReplaced;Provider=

and it replaces the text found with this:

Initial Catalog=AstarteReplacing;Provider=

I don’t enter into the details of each cmdlet used. I leave the reader to search for these details.

Alternatively, you can use a specific object model exposed in some .NET assemblies provided by Integration Services, or you can use the Pacman utility:

Enjoy! :)

P.S. Using TFS as versioning system, before running the script I checked out the packages and, after the script executed succesfully, I checked in them.