Skip to content

Instantly share code, notes, and snippets.

@bseebacher
Last active February 14, 2024 23:01
Show Gist options
  • Save bseebacher/e088e5a2d3c4325d279c2ed9a8b28197 to your computer and use it in GitHub Desktop.
Save bseebacher/e088e5a2d3c4325d279c2ed9a8b28197 to your computer and use it in GitHub Desktop.
Exports all SSIS projects and packages from a SQL Server 2012 and above SSISDB catalog.
function Export-SsisPackages
{
[CmdletBinding()]param(
[parameter(ValueFromPipeline)]
[ValidateScript({Test-Path $_})]
[string]$OutputPath,
[string]$DatabaseServerName = ".",
[string]$SsisCatalogDatabaseName = "SSISDB"
)
# Create session working directory
$outputDirectoryName = [System.DateTime]::Now.ToString("yyyyMMddHHmmss")
$workingPath = Join-Path $OutputPath $outputDirectoryName
New-Item -Path $workingPath -ItemType directory -Force | Out-Null
# Connect to SQL Server
# Assuming Windows Integrated (SSPI) security.
# Need something different? See https://www.connectionstrings.com/sql-server/ for many more examples.
$sqlConnectionString = "Integrated Security=SSPI;Persist Security Info=False;Database=" + $SsisCatalogDatabaseName +
";Data Source=" + $DatabaseServerName
$catalogDbConnection = New-Object System.Data.SqlClient.SqlConnection
$catalogDbConnection.ConnectionString = $sqlConnectionString
$sqlCatalogQuery = "SELECT fld.[name] AS FolderName, proj.[name] AS ProjectName " +
"FROM [catalog].[projects] AS proj " +
"INNER JOIN [catalog].[folders] AS fld " +
"ON proj.folder_id = fld.folder_id;"
$sqlCatalogExport = "EXEC [catalog].[get_project] " +
"@folder_name=@folder, @project_name = @project"
$zipFilePaths = @()
try {
$catalogDbConnection.Open()
#Load Catalog Contents from SQL
Write-Host "Loading SSIS Catalog Entries"
$cmdCatalogQuery = New-Object System.Data.SqlClient.SqlCommand
$cmdCatalogQuery.Connection = $catalogDbConnection
$cmdCatalogQuery.CommandText = $sqlCatalogQuery
$dtCatalog = New-Object System.Data.DataTable
$dtCatalog.Load($cmdCatalogQuery.ExecuteReader())
# Loop over catalog entries; export ISPAC files.
Write-Host "Begin Extracting SSIS Projects and Packages from Catalog"
foreach($ci in $dtCatalog)
{
$cmdExport = New-Object System.Data.SqlClient.SqlCommand
$cmdExport.Connection = $catalogDbConnection
$cmdExport.CommandText = $sqlCatalogExport
$cmdExport.Parameters.AddWithValue("@folder", $ci.FolderName) | Out-Null
$cmdExport.Parameters.AddWithValue("@project", $ci.ProjectName) | Out-Null
$bReader = $cmdExport.ExecuteScalar()
$zipFileOutputPath = Join-Path -Path $workingPath ($ci.FolderName + "-" + $ci.ProjectName + ".zip")
$zipFilePaths += $zipFileOutputPath
[System.IO.File]::WriteAllBytes($zipFileOutputPath, [byte[]]$bReader) | Out-Null
}
Write-Host "Begin Expanding Archives"
foreach($zipFilePath in $zipFilePaths)
{
$zipFile = Get-Item $zipFilePath
$projectName = $zipFile.Name.Replace(".zip", "")
$decompressedPathOut = Join-Path $workingPath $projectName
Write-Host "Expanding" $projectName
# NOTE - Expand-Archive cmdlet requires PowerShell v5 or above.
# https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.archive/expand-archive
Expand-Archive -Path $zipFile -DestinationPath $decompressedPathOut | Out-Null
Remove-Item -Path $zipFilePath -Force | Out-Null
}
Write-Host "Projects and Packages Extracted to " $workingPath
}
catch{
Write-Error -Message "An error occurred while processing this request."
$Error[0]
}
finally {
if($catalogDbConnection.State -eq [System.Data.ConnectionState]::Open){
$catalogDbConnection.Close()
}
}
}
# Uncomment below for simple one liner batch execution using defaults and current directory
#Export-SsisPackages -OutputPath ((Get-Item -Path ".\" -Verbose).FullName)
@NodeJSmith
Copy link

FYI - If you change line 59 "zip" to "ispac" you can comment out lines 65 - 78 and you're left with ispac files that you can redeploy directly.

@bseebacher
Copy link
Author

That's cool. When I wrote this I was more interested in getting at the contents of the packages, but I could see how having the ISPAC files would be handy for a dump/redeploy use case.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment