Deploy ispac SSIS project from a package

Octopus.Script exported 2019-04-18 by suxstellino belongs to ‘SQL Server’ category.

This step template will deploy SSIS ispac projects to SQL Server Integration Services Catalog

Parameters

When steps based on the template are included in a project’s deployment process, the parameters below can be set.

Database server name (\instance)

ServerName =

Name of the SQL Server you are deploying to.

Enable SQL CLR

EnableCLR = False

This will reconfigure SQL Server to enable the SQL CLR. It is highly recommended that this be previously authorized by your Database Administrator.

Catalog name

CatalogName = SSISDB

Name of the catalog to create in Integration Services Catalogs on SQL Server. When using the GUI, this value gets hardcoded to SSISDB and cannot be changed. It is recommended that you do not change the default value.

Catalog password

CatalogPwd =

Password to the Integration Services Catalog.

Folder name

FolderName =

Name of the folder to use within the Integration Services Catalog

Project name

ProjectName =

Name of the project within the folder of the Integration Services catalog

Use environment

UseEnvironment = False

This will make a project reference to the defined environment.

Environment name

EnvironmentName =

Name of the environment to reference the project to. If the environment doesn’t exist, it will create it.

Reference project parameters to environment variables

ReferenceProjectParametersToEnvironmentVairables = False

Checking this box will make Project Parameters reference Environment Variables. If the Environment Variable doesn’t exist, it will create it. This expects that an Octopus variable of the same name exists.

Reference package parameters to environment variables

ReferencePackageParametersToEnvironmentVairables = False

Checking this box will make Package Parameters reference Environment Variables. If the Environment Variable doesn’t exist, it will create it. This expects than an Octopus variable of the same name exists.

NuGet package step

NugetPackageStepName =

The step that uploaded the NuGet package to the server.

Use Fully Qualified Variable Names

UseFullyQualifiedVariableNames = False

When true the package variables names must be represented in dtsx_name_without_extension.variable_name

Use Custom Filter for connection manager properties

UseCustomFilter = False

Custom filter should contain the regular expression for ignoring properties when setting will occur during the auto-mapping

Custom Filter for connection manager properties

CustomFilter =

Regular expression for filtering out the connection manager properties during the auto-mapping process. This string is used when UseCustomFilter is set to true

Clean obsolete variables from environment

SyncEnvironment = False

When true synchronizes the environment:

  • Removes obsolete variables
  • Removes renamed variables
  • Replaces values of valid variables (also when false)

Script body

Steps based on this template will execute the following PowerShell script.

#region Functions

#region Get-Catalog
Function Get-Catalog
{
     # define parameters
    Param ($CatalogName)
    # NOTE: using $integrationServices variable defined in main
    
    # define working varaibles
    $Catalog = $null
    # check to see if there are any catalogs
    if($integrationServices.Catalogs.Count -gt 0 -and $integrationServices.Catalogs[$CatalogName])
    {
    	# get reference to catalog
    	$Catalog = $integrationServices.Catalogs[$CatalogName]
    }
    else
    {
    	if((Get-CLREnabled) -eq 0)
    	{
    		if(-not $EnableCLR)
    		{
    			# throw error
    			throw "SQL CLR is not enabled."
    		}
    		else
    		{
    			# display sql clr isn't enabled
    			Write-Warning "SQL CLR is not enabled on $($sqlConnection.DataSource).  This feature must be enabled for SSIS catalogs."
    
    			# enablign SQLCLR
    			Write-Host "Enabling SQL CLR ..."
    			Enable-SQLCLR
    			Write-Host "SQL CLR enabled"
    		}
    	}
    
    	# Provision a new SSIS Catalog
    	Write-Host "Creating SSIS Catalog ..."
    
    	$Catalog = New-Object "$ISNamespace.Catalog" ($integrationServices, $CatalogName, $CatalogPwd)
    	$Catalog.Create()
    
    
    }
    
    # return the catalog
    return $Catalog
}
#endregion

#region Get-CLREnabled
Function Get-CLREnabled
{
    # define parameters
    # Not using any parameters, but am using $sqlConnection defined in main
    
    # define working variables
    $Query = "SELECT * FROM sys.configurations WHERE name = 'clr enabled'"
    
    # execute script
    $CLREnabled = Invoke-Sqlcmd -ServerInstance $sqlConnection.DataSource -Database "master" -Query $Query | Select value
    
    # return value
    return $CLREnabled.Value
}
#endregion

#region Enable-SQLCLR
Function Enable-SQLCLR
{
    $QueryArray = "sp_configure 'show advanced options', 1", "RECONFIGURE", "sp_configure 'clr enabled', 1", "RECONFIGURE "
    # execute script
    
    foreach($Query in $QueryArray)
    {
    	Invoke-Sqlcmd -ServerInstance $sqlConnection.DataSource -Database "master" -Query $Query
    }
    
    # check that it's enabled
    if((Get-CLREnabled) -ne 1)
    {
    	# throw error
    	throw "Failed to enable SQL CLR"
    }
}
#endregion

#region Get-Folder
Function Get-Folder
{
 # parameters
    Param($FolderName, $Catalog)
    
    $Folder = $null
    # try to get reference to folder
    
    if(!($Catalog.Folders -eq $null))
    {
    	$Folder = $Catalog.Folders[$FolderName]
    }
    
    # check to see if $Folder has a value
    if($Folder -eq $null)
    {
    	# display
    	Write-Host "Folder $FolderName doesn't exist, creating folder..."
    
    	# create the folder
    	$Folder = New-Object "$ISNamespace.CatalogFolder" ($Catalog, $FolderName, $FolderName) 
    	$Folder.Create() 
    }
    
    # return the folde reference
    return $Folder
}
#endregion

#region Get-Environment
Function Get-Environment
{
     # define parameters
    Param($Folder, $EnvironmentName)
    
    $Environment = $null
    # get reference to Environment
    if(!($Folder.Environments -eq $null) -and $Folder.Environments.Count -gt 0)
    {
    	$Environment = $Folder.Environments[$EnvironmentName]
    }
    
    # check to see if it's a null reference
    if($Environment -eq $null)
    {
    	# display
    	Write-Host "Environment $EnvironmentName doesn't exist, creating environment..."
    
    	# create environment
    	$Environment = New-Object "$ISNamespace.EnvironmentInfo" ($Folder, $EnvironmentName, $EnvironmentName)
    	$Environment.Create() 
    }
    
    # return the environment
    return $Environment
}
#endregion

#region Set-EnvironmentReference
Function Set-EnvironmentReference
{
     # define parameters
    Param($Project, $Environment, $Folder)
    
    # get reference
    $Reference = $null
    
    if(!($Project.References -eq $null))
    {
    	$Reference = $Project.References[$Environment.Name, $Folder.Name]
    
    }
    
    # check to see if it's a null reference
    if($Reference -eq $null)
    {
    	# display
    	Write-Host "Project does not reference environment $($Environment.Name), creating reference..."
    
    	# create reference
    	$Project.References.Add($Environment.Name, $Folder.Name)
    	$Project.Alter() 
    }
}
#endregion

#region Set-ProjectParametersToEnvironmentVariablesReference
Function Set-ProjectParametersToEnvironmentVariablesReference
{
     # define parameters
    Param($Project, $Environment)
    
    $UpsertedVariables = @()

    if($Project.Parameters -eq $null)
    {
        Write-Host "No project parameters exist"
        return
    }

    # loop through project parameters
    foreach($Parameter in $Project.Parameters)
    {
        # skip if the parameter is included in custom filters
        if ($UseCustomFilter) 
        {
            if ($Parameter.Name -match $CustomFilter)
            {
                Write-Host "- $($Parameter.Name) skipped due to CustomFilters."            
                continue
            }
        }

        # Add variable to list of variable
        $UpsertedVariables += $Parameter.Name

        $Variable = $null
        if(!($Environment.Variables -eq $null))
        {
    	    # get reference to variable
    	    $Variable = $Environment.Variables[$Parameter.Name]
        }
    
    	# check to see if variable exists
    	if($Variable -eq $null)
    	{
    		# add the environment variable
    		Add-EnvironmentVariable -Environment $Environment -Parameter $Parameter -ParameterName $Parameter.Name
    
    		# get reference to the newly created variable
    		$Variable = $Environment.Variables[$Parameter.Name]
    	}
    
    	# set the environment variable value
    	Set-EnvironmentVariableValue -Variable $Variable -Parameter $Parameter -ParameterName $Parameter.Name
    }
    
    # alter the environment
    $Environment.Alter()
    $Project.Alter()

    return $UpsertedVariables
}
#endregion

Function Set-PackageVariablesToEnvironmentVariablesReference
{
    # define parameters
    Param($Project, $Environment)

    $Variables = @()
    $UpsertedVariables = @()

    # loop through packages in project in order to store a temp collection of variables
    foreach($Package in $Project.Packages)
    {
    	# loop through parameters of package
    	foreach($Parameter in $Package.Parameters)
    	{
    		# add to the temporary variable collection
    		$Variables += $Parameter.Name
    	}
    }

    # loop through packages in project
    foreach($Package in $Project.Packages)
    {
    	# loop through parameters of package
    	foreach($Parameter in $Package.Parameters)
    	{
            if ($UseFullyQualifiedVariableNames)
            {
                # Set fully qualified variable name
                $ParameterName = $Parameter.ObjectName.Replace(".dtsx", "")+"."+$Parameter.Name
            }
            else
            {
                # check if exists a variable with the same name
                $VariableNameOccurrences = $($Variables | Where-Object { $_ -eq $Parameter.Name }).count
                $ParameterName = $Parameter.Name
                
                if ($VariableNameOccurrences -gt 1)
                {
                    $ParameterName = $Parameter.ObjectName.Replace(".dtsx", "")+"."+$Parameter.Name
                }
            }
            
            if ($UseCustomFilter)
            {
                if ($ParameterName -match $CustomFilter)
                {
                    Write-Host "- $($Parameter.Name) skipped due to CustomFilters."            
                    continue
                }
            }

            # get reference to variable
    		$Variable = $Environment.Variables[$ParameterName]

            # Add variable to list of variable
            $UpsertedVariables += $ParameterName

            # check to see if the parameter exists
    		if(!$Variable)
    		{
    			# add the environment variable
    			Add-EnvironmentVariable -Environment $Environment -Parameter $Parameter -ParameterName $ParameterName
    
    			# get reference to the newly created variable
    			$Variable = $Environment.Variables[$ParameterName]
    		}
    
    		# set the environment variable value
    		Set-EnvironmentVariableValue -Variable $Variable -Parameter $Parameter -ParameterName $ParameterName
    	}
    
    	# alter the package
    	$Package.Alter()
    }
    
    # alter the environment
    $Environment.Alter()

    return $UpsertedVariables
}

Function Sync-EnvironmentVariables
{
    # define parameters
    Param($Environment, $VariablesToPreserveInEnvironment)

    foreach($VariableToEvaluate in $Environment.Variables)
    {
        if ($VariablesToPreserveInEnvironment -notcontains $VariableToEvaluate.Name)
        {
            Write-Host "- Removing environment variable: $($VariableToEvaluate.Name)"
            $VariableToRemove = $Environment.Variables[$VariableToEvaluate.Name]
            $Environment.Variables.Remove($VariableToRemove) | Out-Null
        }
    }

    # alter the environment
    $Environment.Alter()
}

#region Add-EnvironmentVariable
Function Add-EnvironmentVariable
{
    # define parameters
    Param($Environment, $Parameter, $ParameterName)
    
    # display 
    Write-Host "- Adding environment variable $($ParameterName)"
    
    # check to see if design default value is emtpy or null
    if([string]::IsNullOrEmpty($Parameter.DesignDefaultValue))
    {
    	# give it something
    	$DefaultValue = "" # sensitive variables will not return anything so when trying to use the property of $Parameter.DesignDefaultValue, the Alter method will fail.
    }
    else
    {
    	# take the design
    	$DefaultValue = $Parameter.DesignDefaultValue
    }
    
    # add variable with an initial value
    $Environment.Variables.Add($ParameterName, $Parameter.DataType, $DefaultValue, $Parameter.Sensitive, $Parameter.Description)
}
#endregion

#region Set-EnvironmentVariableValue
Function Set-EnvironmentVariableValue
{
     # define parameters
    Param($Variable, $Parameter, $ParameterName)

    # check to make sure variable value is available
    if($OctopusParameters -and $OctopusParameters.ContainsKey($ParameterName))
    {
        # display 
        Write-Host "- Updating environment variable $($ParameterName)"

    	# set the variable value
    	$Variable.Value = $OctopusParameters["$($ParameterName)"]
    }
    else
    {
    	# warning
    	Write-Host "**- OctopusParameters collection is empty or $($ParameterName) not in the collection -**"
    }
    
    # Set reference
    $Parameter.Set([Microsoft.SqlServer.Management.IntegrationServices.ParameterInfo+ParameterValueType]::Referenced, "$($ParameterName)")
}
#endregion


#endregion

#region Dependent assemblies

# Load the IntegrationServices Assembly
[Reflection.Assembly]::LoadWithPartialName("Microsoft.SqlServer.Management.IntegrationServices") | Out-Null # Out-Null supresses a message that would normally be displayed saying it loaded out of GAC

# Store the IntegrationServices Assembly namespace to avoid typing it every time
$ISNamespace = "Microsoft.SqlServer.Management.IntegrationServices"

#endregion

#region Main
try
{
	# ensure all boolean variables are true booleans
    $EnableCLR = [System.Convert]::ToBoolean("$EnableCLR")
    $UseEnvironment = [System.Convert]::ToBoolean("$UseEnvironment")
    $ReferenceProjectParametersToEnvironmentVairables = [System.Convert]::ToBoolean("$ReferenceProjectParametersToEnvironmentVairables")
    Write-Host "Value is $ReferencePackageParametersToEnvironmentVairables"
    $ReferencePackageParametersToEnvironmentVairables = [System.Convert]::ToBoolean("$ReferencePackageParametersToEnvironmentVairables")
    $UseFullyQualifiedVariableNames = [System.Convert]::ToBoolean("$UseFullyQualifiedVariableNames")
    $SyncEnvironment = [System.Convert]::ToBoolean("$SyncEnvironment")
    # custom names for filtering out the excluded variables by design
    $UseCustomFilter = [System.Convert]::ToBoolean("$UseCustomFilter")
    $CustomFilter = [System.Convert]::ToString("$CustomFilter")
    # list of variables names to keep in target environment
    $VariablesToPreserveInEnvironment = @()
        
    # Get file path where Octopus deployed it
    $DeployedPath = $OctopusParameters["Octopus.Action[$NugetPackageStepName].Output.Package.InstallationDirectoryPath"]

    
    # display the path where it's referencing
    Write-Host "Package deployed to $DeployedPath"

	# Get all .ispac files from the deployed path
	$IsPacFiles = Get-ChildItem -Recurse -Path $DeployedPath | Where {$_.Extension.ToLower() -eq ".ispac"}

	# display number of files
	Write-Host "$($IsPacFiles.Count) .ispac file(s) found."

	Write-Host "Connecting to server ..."

	# Create a connection to the server
    $sqlConnectionString = "Data Source=$ServerName;Initial Catalog=master;Integrated Security=SSPI;"
    $sqlConnection = New-Object System.Data.SqlClient.SqlConnection $sqlConnectionString

	# create integration services object
	$integrationServices = New-Object "$ISNamespace.IntegrationServices" $sqlConnection

	# get reference to the catalog
	Write-Host "Getting reference to catalog $CataLogName"
	$Catalog = Get-Catalog -CatalogName $CataLogName

	# get folder reference
	$Folder = Get-Folder -FolderName $FolderName -Catalog $Catalog

	# loop through ispac files
	foreach($IsPacFile in $IsPacFiles)
	{
		# read project file
		$ProjectFile = [System.IO.File]::ReadAllBytes($IsPacFile.FullName)

		# deploy project
		Write-Host "Deploying project $($IsPacFile.Name)..."
		$Folder.DeployProject($ProjectName, $ProjectFile) | Out-Null

		# get reference to deployed project
		$Project = $Folder.Projects[$ProjectName]

		# check to see if they want to use environments
		if($UseEnvironment)
		{
			# get environment reference
			$Environment = Get-Environment -Folder $Folder -EnvironmentName $EnvironmentName

			# set environment reference
			Set-EnvironmentReference -Project $Project -Environment $Environment -Folder $Folder

			# check to see if the user wants to convert project parameters to environment variables
			if($ReferenceProjectParametersToEnvironmentVairables)
			{
				# set environment variables
				Write-Host "Referencing Project Parameters to Environment Variables..."
				$VariablesToPreserveInEnvironment += Set-ProjectParametersToEnvironmentVariablesReference -Project $Project -Environment $Environment
			}

			# check to see if the user wants to convert the package parameters to environment variables
			if($ReferencePackageParametersToEnvironmentVairables)
			{
				# set package variables
				Write-Host "Referencing Package Parameters to Environment Variables..."
				$VariablesToPreserveInEnvironment += Set-PackageVariablesToEnvironmentVariablesReference -Project $Project -Environment $Environment
			}
            
            # Removes all unused variables from the environment
            if ($SyncEnvironment)
            {
                Write-Host "Sync package environment variables..."
                Sync-EnvironmentVariables -Environment $Environment -VariablesToPreserveInEnvironment $VariablesToPreserveInEnvironment
            }
		}
	}
}

finally
{
	# check to make sure sqlconnection isn't null
	if($sqlConnection)
	{
		# check state of sqlconnection
		if($sqlConnection.State -eq [System.Data.ConnectionState]::Open)
		{
			# close the connection
			$sqlConnection.Close()
		}

		# cleanup
		$sqlConnection.Dispose()
	}
}
#endregion

Provided under the Apache License version 2.0.

Report an issue

To use this template in Octopus Deploy, copy the JSON below and paste it into the Library → Step templates → Import dialog.

{
  "Id": "bf005449-60c2-4746-8e07-8ba857f93605",
  "Name": "Deploy ispac SSIS project from a package",
  "Description": "This step template will deploy SSIS ispac projects to SQL Server Integration Services Catalog",
  "Version": 15,
  "ExportedAt": "2019-04-18T13:43:05.493Z",
  "ActionType": "Octopus.Script",
  "Author": "suxstellino",
  "Parameters": [
    {
      "Id": "da92ad6a-23ac-4f24-b243-b42507737422",
      "Name": "ServerName",
      "Label": "Database server name (\\instance)",
      "HelpText": "Name of the SQL Server you are deploying to.",
      "DefaultValue": "",
      "DisplaySettings": {
        "Octopus.ControlType": "SingleLineText"
      }
    },
    {
      "Id": "a3e3e7e5-aa53-429c-b63b-166ddc875e45",
      "Name": "EnableCLR",
      "Label": "Enable SQL CLR",
      "HelpText": "This will reconfigure SQL Server to enable the SQL CLR.  It is highly recommended that this be previously authorized by your Database Administrator.",
      "DefaultValue": "False",
      "DisplaySettings": {
        "Octopus.ControlType": "Checkbox"
      }
    },
    {
      "Id": "bb659731-de74-470b-94fe-24b61e27e176",
      "Name": "CatalogName",
      "Label": "Catalog name",
      "HelpText": "Name of the catalog to create in Integration Services Catalogs on SQL Server.  When using the GUI, this value gets hardcoded to SSISDB and cannot be changed.  It is recommended that you do not change the default value.",
      "DefaultValue": "SSISDB",
      "DisplaySettings": {
        "Octopus.ControlType": "SingleLineText"
      }
    },
    {
      "Id": "af66e1ad-3631-4d4b-99d4-215a1b2beb9d",
      "Name": "CatalogPwd",
      "Label": "Catalog password",
      "HelpText": "Password to the Integration Services Catalog.",
      "DefaultValue": "",
      "DisplaySettings": {
        "Octopus.ControlType": "Sensitive"
      }
    },
    {
      "Id": "db080c05-a746-4c27-b964-d98b63b00a29",
      "Name": "FolderName",
      "Label": "Folder name",
      "HelpText": "Name of the folder to use within the Integration Services Catalog",
      "DefaultValue": "",
      "DisplaySettings": {
        "Octopus.ControlType": "SingleLineText"
      }
    },
    {
      "Id": "c6264016-2c14-4e24-949c-d8a9d73599ac",
      "Name": "ProjectName",
      "Label": "Project name",
      "HelpText": "Name of the project within the folder of the Integration Services catalog",
      "DefaultValue": "",
      "DisplaySettings": {
        "Octopus.ControlType": "SingleLineText"
      }
    },
    {
      "Id": "f628a71c-5399-4137-926b-3c8d170ba61c",
      "Name": "UseEnvironment",
      "Label": "Use environment",
      "HelpText": "This will make a project reference to the defined environment.",
      "DefaultValue": "False",
      "DisplaySettings": {
        "Octopus.ControlType": "Checkbox"
      }
    },
    {
      "Id": "66eee7ee-7f89-4675-a32a-f33dac895311",
      "Name": "EnvironmentName",
      "Label": "Environment name",
      "HelpText": "Name of the environment to reference the project to. If the environment doesn't exist, it will create it.",
      "DefaultValue": "",
      "DisplaySettings": {
        "Octopus.ControlType": "SingleLineText"
      }
    },
    {
      "Id": "a014a370-9b9d-4284-b6be-a603f9f97942",
      "Name": "ReferenceProjectParametersToEnvironmentVairables",
      "Label": "Reference project parameters to environment variables",
      "HelpText": "Checking this box will make Project Parameters reference Environment Variables.  If the Environment Variable doesn't exist, it will create it.  This expects that an Octopus variable of the same name exists.",
      "DefaultValue": "False",
      "DisplaySettings": {
        "Octopus.ControlType": "Checkbox"
      }
    },
    {
      "Id": "4441ed46-3cc3-42bb-9baa-5753cd4d6d5c",
      "Name": "ReferencePackageParametersToEnvironmentVairables",
      "Label": "Reference package parameters to environment variables",
      "HelpText": "Checking this box will make Package Parameters reference Environment Variables.  If the Environment Variable doesn't exist, it will create it.  This expects than an Octopus variable of the same name exists.",
      "DefaultValue": "False",
      "DisplaySettings": {
        "Octopus.ControlType": "Checkbox"
      }
    },
    {
      "Id": "3d4e78ec-fe77-4221-be40-1b3d2fbfc3c4",
      "Name": "NugetPackageStepName",
      "Label": "NuGet package step",
      "HelpText": "The step that uploaded the NuGet package to the server.",
      "DefaultValue": "",
      "DisplaySettings": {
        "Octopus.ControlType": "StepName"
      }
    },
    {
      "Id": "7c9d808d-60f3-4648-b8a4-e4865268740b",
      "Name": "UseFullyQualifiedVariableNames",
      "Label": "Use Fully Qualified Variable Names",
      "HelpText": "When true the package variables names must be represented in `dtsx_name_without_extension.variable_name`",
      "DefaultValue": "False",
      "DisplaySettings": {
        "Octopus.ControlType": "Checkbox"
      }
    },
    {
      "Id": "fef889a5-1f5b-48c7-bb65-2f2c3498e6cd",
      "Name": "UseCustomFilter",
      "Label": "Use Custom Filter for connection manager properties",
      "HelpText": "Custom filter should contain the regular expression for ignoring properties when setting will occur during the auto-mapping",
      "DefaultValue": "False",
      "DisplaySettings": {
        "Octopus.ControlType": "Checkbox"
      }
    },
    {
      "Id": "ebefb099-ce7a-45bf-b52a-bb8ea9915b1b",
      "Name": "CustomFilter",
      "Label": "Custom Filter for connection manager properties",
      "HelpText": "Regular expression for filtering out the connection manager properties during the auto-mapping process. This string is used when `UseCustomFilter` is set to true",
      "DefaultValue": "",
      "DisplaySettings": {
        "Octopus.ControlType": "SingleLineText"
      }
    },
    {
      "Id": "dbe29935-d3c6-4b77-b796-26347abdbf2c",
      "Name": "SyncEnvironment",
      "Label": "Clean obsolete variables from environment",
      "HelpText": "When `true` synchronizes the environment:\n- Removes obsolete variables\n- Removes renamed variables\n- Replaces values of valid variables (also when `false`)",
      "DefaultValue": "False",
      "DisplaySettings": {
        "Octopus.ControlType": "Checkbox"
      }
    }
  ],
  "Properties": {
    "Octopus.Action.Script.Syntax": "PowerShell",
    "Octopus.Action.Script.ScriptBody": "#region Functions\n\n#region Get-Catalog\nFunction Get-Catalog\n{\n     # define parameters\n    Param ($CatalogName)\n    # NOTE: using $integrationServices variable defined in main\n    \n    # define working varaibles\n    $Catalog = $null\n    # check to see if there are any catalogs\n    if($integrationServices.Catalogs.Count -gt 0 -and $integrationServices.Catalogs[$CatalogName])\n    {\n    \t# get reference to catalog\n    \t$Catalog = $integrationServices.Catalogs[$CatalogName]\n    }\n    else\n    {\n    \tif((Get-CLREnabled) -eq 0)\n    \t{\n    \t\tif(-not $EnableCLR)\n    \t\t{\n    \t\t\t# throw error\n    \t\t\tthrow \"SQL CLR is not enabled.\"\n    \t\t}\n    \t\telse\n    \t\t{\n    \t\t\t# display sql clr isn't enabled\n    \t\t\tWrite-Warning \"SQL CLR is not enabled on $($sqlConnection.DataSource).  This feature must be enabled for SSIS catalogs.\"\n    \n    \t\t\t# enablign SQLCLR\n    \t\t\tWrite-Host \"Enabling SQL CLR ...\"\n    \t\t\tEnable-SQLCLR\n    \t\t\tWrite-Host \"SQL CLR enabled\"\n    \t\t}\n    \t}\n    \n    \t# Provision a new SSIS Catalog\n    \tWrite-Host \"Creating SSIS Catalog ...\"\n    \n    \t$Catalog = New-Object \"$ISNamespace.Catalog\" ($integrationServices, $CatalogName, $CatalogPwd)\n    \t$Catalog.Create()\n    \n    \n    }\n    \n    # return the catalog\n    return $Catalog\n}\n#endregion\n\n#region Get-CLREnabled\nFunction Get-CLREnabled\n{\n    # define parameters\n    # Not using any parameters, but am using $sqlConnection defined in main\n    \n    # define working variables\n    $Query = \"SELECT * FROM sys.configurations WHERE name = 'clr enabled'\"\n    \n    # execute script\n    $CLREnabled = Invoke-Sqlcmd -ServerInstance $sqlConnection.DataSource -Database \"master\" -Query $Query | Select value\n    \n    # return value\n    return $CLREnabled.Value\n}\n#endregion\n\n#region Enable-SQLCLR\nFunction Enable-SQLCLR\n{\n    $QueryArray = \"sp_configure 'show advanced options', 1\", \"RECONFIGURE\", \"sp_configure 'clr enabled', 1\", \"RECONFIGURE \"\n    # execute script\n    \n    foreach($Query in $QueryArray)\n    {\n    \tInvoke-Sqlcmd -ServerInstance $sqlConnection.DataSource -Database \"master\" -Query $Query\n    }\n    \n    # check that it's enabled\n    if((Get-CLREnabled) -ne 1)\n    {\n    \t# throw error\n    \tthrow \"Failed to enable SQL CLR\"\n    }\n}\n#endregion\n\n#region Get-Folder\nFunction Get-Folder\n{\n # parameters\n    Param($FolderName, $Catalog)\n    \n    $Folder = $null\n    # try to get reference to folder\n    \n    if(!($Catalog.Folders -eq $null))\n    {\n    \t$Folder = $Catalog.Folders[$FolderName]\n    }\n    \n    # check to see if $Folder has a value\n    if($Folder -eq $null)\n    {\n    \t# display\n    \tWrite-Host \"Folder $FolderName doesn't exist, creating folder...\"\n    \n    \t# create the folder\n    \t$Folder = New-Object \"$ISNamespace.CatalogFolder\" ($Catalog, $FolderName, $FolderName) \n    \t$Folder.Create() \n    }\n    \n    # return the folde reference\n    return $Folder\n}\n#endregion\n\n#region Get-Environment\nFunction Get-Environment\n{\n     # define parameters\n    Param($Folder, $EnvironmentName)\n    \n    $Environment = $null\n    # get reference to Environment\n    if(!($Folder.Environments -eq $null) -and $Folder.Environments.Count -gt 0)\n    {\n    \t$Environment = $Folder.Environments[$EnvironmentName]\n    }\n    \n    # check to see if it's a null reference\n    if($Environment -eq $null)\n    {\n    \t# display\n    \tWrite-Host \"Environment $EnvironmentName doesn't exist, creating environment...\"\n    \n    \t# create environment\n    \t$Environment = New-Object \"$ISNamespace.EnvironmentInfo\" ($Folder, $EnvironmentName, $EnvironmentName)\n    \t$Environment.Create() \n    }\n    \n    # return the environment\n    return $Environment\n}\n#endregion\n\n#region Set-EnvironmentReference\nFunction Set-EnvironmentReference\n{\n     # define parameters\n    Param($Project, $Environment, $Folder)\n    \n    # get reference\n    $Reference = $null\n    \n    if(!($Project.References -eq $null))\n    {\n    \t$Reference = $Project.References[$Environment.Name, $Folder.Name]\n    \n    }\n    \n    # check to see if it's a null reference\n    if($Reference -eq $null)\n    {\n    \t# display\n    \tWrite-Host \"Project does not reference environment $($Environment.Name), creating reference...\"\n    \n    \t# create reference\n    \t$Project.References.Add($Environment.Name, $Folder.Name)\n    \t$Project.Alter() \n    }\n}\n#endregion\n\n#region Set-ProjectParametersToEnvironmentVariablesReference\nFunction Set-ProjectParametersToEnvironmentVariablesReference\n{\n     # define parameters\n    Param($Project, $Environment)\n    \n    $UpsertedVariables = @()\n\n    if($Project.Parameters -eq $null)\n    {\n        Write-Host \"No project parameters exist\"\n        return\n    }\n\n    # loop through project parameters\n    foreach($Parameter in $Project.Parameters)\n    {\n        # skip if the parameter is included in custom filters\n        if ($UseCustomFilter) \n        {\n            if ($Parameter.Name -match $CustomFilter)\n            {\n                Write-Host \"- $($Parameter.Name) skipped due to CustomFilters.\"            \n                continue\n            }\n        }\n\n        # Add variable to list of variable\n        $UpsertedVariables += $Parameter.Name\n\n        $Variable = $null\n        if(!($Environment.Variables -eq $null))\n        {\n    \t    # get reference to variable\n    \t    $Variable = $Environment.Variables[$Parameter.Name]\n        }\n    \n    \t# check to see if variable exists\n    \tif($Variable -eq $null)\n    \t{\n    \t\t# add the environment variable\n    \t\tAdd-EnvironmentVariable -Environment $Environment -Parameter $Parameter -ParameterName $Parameter.Name\n    \n    \t\t# get reference to the newly created variable\n    \t\t$Variable = $Environment.Variables[$Parameter.Name]\n    \t}\n    \n    \t# set the environment variable value\n    \tSet-EnvironmentVariableValue -Variable $Variable -Parameter $Parameter -ParameterName $Parameter.Name\n    }\n    \n    # alter the environment\n    $Environment.Alter()\n    $Project.Alter()\n\n    return $UpsertedVariables\n}\n#endregion\n\nFunction Set-PackageVariablesToEnvironmentVariablesReference\n{\n    # define parameters\n    Param($Project, $Environment)\n\n    $Variables = @()\n    $UpsertedVariables = @()\n\n    # loop through packages in project in order to store a temp collection of variables\n    foreach($Package in $Project.Packages)\n    {\n    \t# loop through parameters of package\n    \tforeach($Parameter in $Package.Parameters)\n    \t{\n    \t\t# add to the temporary variable collection\n    \t\t$Variables += $Parameter.Name\n    \t}\n    }\n\n    # loop through packages in project\n    foreach($Package in $Project.Packages)\n    {\n    \t# loop through parameters of package\n    \tforeach($Parameter in $Package.Parameters)\n    \t{\n            if ($UseFullyQualifiedVariableNames)\n            {\n                # Set fully qualified variable name\n                $ParameterName = $Parameter.ObjectName.Replace(\".dtsx\", \"\")+\".\"+$Parameter.Name\n            }\n            else\n            {\n                # check if exists a variable with the same name\n                $VariableNameOccurrences = $($Variables | Where-Object { $_ -eq $Parameter.Name }).count\n                $ParameterName = $Parameter.Name\n                \n                if ($VariableNameOccurrences -gt 1)\n                {\n                    $ParameterName = $Parameter.ObjectName.Replace(\".dtsx\", \"\")+\".\"+$Parameter.Name\n                }\n            }\n            \n            if ($UseCustomFilter)\n            {\n                if ($ParameterName -match $CustomFilter)\n                {\n                    Write-Host \"- $($Parameter.Name) skipped due to CustomFilters.\"            \n                    continue\n                }\n            }\n\n            # get reference to variable\n    \t\t$Variable = $Environment.Variables[$ParameterName]\n\n            # Add variable to list of variable\n            $UpsertedVariables += $ParameterName\n\n            # check to see if the parameter exists\n    \t\tif(!$Variable)\n    \t\t{\n    \t\t\t# add the environment variable\n    \t\t\tAdd-EnvironmentVariable -Environment $Environment -Parameter $Parameter -ParameterName $ParameterName\n    \n    \t\t\t# get reference to the newly created variable\n    \t\t\t$Variable = $Environment.Variables[$ParameterName]\n    \t\t}\n    \n    \t\t# set the environment variable value\n    \t\tSet-EnvironmentVariableValue -Variable $Variable -Parameter $Parameter -ParameterName $ParameterName\n    \t}\n    \n    \t# alter the package\n    \t$Package.Alter()\n    }\n    \n    # alter the environment\n    $Environment.Alter()\n\n    return $UpsertedVariables\n}\n\nFunction Sync-EnvironmentVariables\n{\n    # define parameters\n    Param($Environment, $VariablesToPreserveInEnvironment)\n\n    foreach($VariableToEvaluate in $Environment.Variables)\n    {\n        if ($VariablesToPreserveInEnvironment -notcontains $VariableToEvaluate.Name)\n        {\n            Write-Host \"- Removing environment variable: $($VariableToEvaluate.Name)\"\n            $VariableToRemove = $Environment.Variables[$VariableToEvaluate.Name]\n            $Environment.Variables.Remove($VariableToRemove) | Out-Null\n        }\n    }\n\n    # alter the environment\n    $Environment.Alter()\n}\n\n#region Add-EnvironmentVariable\nFunction Add-EnvironmentVariable\n{\n    # define parameters\n    Param($Environment, $Parameter, $ParameterName)\n    \n    # display \n    Write-Host \"- Adding environment variable $($ParameterName)\"\n    \n    # check to see if design default value is emtpy or null\n    if([string]::IsNullOrEmpty($Parameter.DesignDefaultValue))\n    {\n    \t# give it something\n    \t$DefaultValue = \"\" # sensitive variables will not return anything so when trying to use the property of $Parameter.DesignDefaultValue, the Alter method will fail.\n    }\n    else\n    {\n    \t# take the design\n    \t$DefaultValue = $Parameter.DesignDefaultValue\n    }\n    \n    # add variable with an initial value\n    $Environment.Variables.Add($ParameterName, $Parameter.DataType, $DefaultValue, $Parameter.Sensitive, $Parameter.Description)\n}\n#endregion\n\n#region Set-EnvironmentVariableValue\nFunction Set-EnvironmentVariableValue\n{\n     # define parameters\n    Param($Variable, $Parameter, $ParameterName)\n\n    # check to make sure variable value is available\n    if($OctopusParameters -and $OctopusParameters.ContainsKey($ParameterName))\n    {\n        # display \n        Write-Host \"- Updating environment variable $($ParameterName)\"\n\n    \t# set the variable value\n    \t$Variable.Value = $OctopusParameters[\"$($ParameterName)\"]\n    }\n    else\n    {\n    \t# warning\n    \tWrite-Host \"**- OctopusParameters collection is empty or $($ParameterName) not in the collection -**\"\n    }\n    \n    # Set reference\n    $Parameter.Set([Microsoft.SqlServer.Management.IntegrationServices.ParameterInfo+ParameterValueType]::Referenced, \"$($ParameterName)\")\n}\n#endregion\n\n\n#endregion\n\n#region Dependent assemblies\n\n# Load the IntegrationServices Assembly\n[Reflection.Assembly]::LoadWithPartialName(\"Microsoft.SqlServer.Management.IntegrationServices\") | Out-Null # Out-Null supresses a message that would normally be displayed saying it loaded out of GAC\n\n# Store the IntegrationServices Assembly namespace to avoid typing it every time\n$ISNamespace = \"Microsoft.SqlServer.Management.IntegrationServices\"\n\n#endregion\n\n#region Main\ntry\n{\n\t# ensure all boolean variables are true booleans\n    $EnableCLR = [System.Convert]::ToBoolean(\"$EnableCLR\")\n    $UseEnvironment = [System.Convert]::ToBoolean(\"$UseEnvironment\")\n    $ReferenceProjectParametersToEnvironmentVairables = [System.Convert]::ToBoolean(\"$ReferenceProjectParametersToEnvironmentVairables\")\n    Write-Host \"Value is $ReferencePackageParametersToEnvironmentVairables\"\n    $ReferencePackageParametersToEnvironmentVairables = [System.Convert]::ToBoolean(\"$ReferencePackageParametersToEnvironmentVairables\")\n    $UseFullyQualifiedVariableNames = [System.Convert]::ToBoolean(\"$UseFullyQualifiedVariableNames\")\n    $SyncEnvironment = [System.Convert]::ToBoolean(\"$SyncEnvironment\")\n    # custom names for filtering out the excluded variables by design\n    $UseCustomFilter = [System.Convert]::ToBoolean(\"$UseCustomFilter\")\n    $CustomFilter = [System.Convert]::ToString(\"$CustomFilter\")\n    # list of variables names to keep in target environment\n    $VariablesToPreserveInEnvironment = @()\n        \n    # Get file path where Octopus deployed it\n    $DeployedPath = $OctopusParameters[\"Octopus.Action[$NugetPackageStepName].Output.Package.InstallationDirectoryPath\"]\n\n    \n    # display the path where it's referencing\n    Write-Host \"Package deployed to $DeployedPath\"\n\n\t# Get all .ispac files from the deployed path\n\t$IsPacFiles = Get-ChildItem -Recurse -Path $DeployedPath | Where {$_.Extension.ToLower() -eq \".ispac\"}\n\n\t# display number of files\n\tWrite-Host \"$($IsPacFiles.Count) .ispac file(s) found.\"\n\n\tWrite-Host \"Connecting to server ...\"\n\n\t# Create a connection to the server\n    $sqlConnectionString = \"Data Source=$ServerName;Initial Catalog=master;Integrated Security=SSPI;\"\n    $sqlConnection = New-Object System.Data.SqlClient.SqlConnection $sqlConnectionString\n\n\t# create integration services object\n\t$integrationServices = New-Object \"$ISNamespace.IntegrationServices\" $sqlConnection\n\n\t# get reference to the catalog\n\tWrite-Host \"Getting reference to catalog $CataLogName\"\n\t$Catalog = Get-Catalog -CatalogName $CataLogName\n\n\t# get folder reference\n\t$Folder = Get-Folder -FolderName $FolderName -Catalog $Catalog\n\n\t# loop through ispac files\n\tforeach($IsPacFile in $IsPacFiles)\n\t{\n\t\t# read project file\n\t\t$ProjectFile = [System.IO.File]::ReadAllBytes($IsPacFile.FullName)\n\n\t\t# deploy project\n\t\tWrite-Host \"Deploying project $($IsPacFile.Name)...\"\n\t\t$Folder.DeployProject($ProjectName, $ProjectFile) | Out-Null\n\n\t\t# get reference to deployed project\n\t\t$Project = $Folder.Projects[$ProjectName]\n\n\t\t# check to see if they want to use environments\n\t\tif($UseEnvironment)\n\t\t{\n\t\t\t# get environment reference\n\t\t\t$Environment = Get-Environment -Folder $Folder -EnvironmentName $EnvironmentName\n\n\t\t\t# set environment reference\n\t\t\tSet-EnvironmentReference -Project $Project -Environment $Environment -Folder $Folder\n\n\t\t\t# check to see if the user wants to convert project parameters to environment variables\n\t\t\tif($ReferenceProjectParametersToEnvironmentVairables)\n\t\t\t{\n\t\t\t\t# set environment variables\n\t\t\t\tWrite-Host \"Referencing Project Parameters to Environment Variables...\"\n\t\t\t\t$VariablesToPreserveInEnvironment += Set-ProjectParametersToEnvironmentVariablesReference -Project $Project -Environment $Environment\n\t\t\t}\n\n\t\t\t# check to see if the user wants to convert the package parameters to environment variables\n\t\t\tif($ReferencePackageParametersToEnvironmentVairables)\n\t\t\t{\n\t\t\t\t# set package variables\n\t\t\t\tWrite-Host \"Referencing Package Parameters to Environment Variables...\"\n\t\t\t\t$VariablesToPreserveInEnvironment += Set-PackageVariablesToEnvironmentVariablesReference -Project $Project -Environment $Environment\n\t\t\t}\n            \n            # Removes all unused variables from the environment\n            if ($SyncEnvironment)\n            {\n                Write-Host \"Sync package environment variables...\"\n                Sync-EnvironmentVariables -Environment $Environment -VariablesToPreserveInEnvironment $VariablesToPreserveInEnvironment\n            }\n\t\t}\n\t}\n}\n\nfinally\n{\n\t# check to make sure sqlconnection isn't null\n\tif($sqlConnection)\n\t{\n\t\t# check state of sqlconnection\n\t\tif($sqlConnection.State -eq [System.Data.ConnectionState]::Open)\n\t\t{\n\t\t\t# close the connection\n\t\t\t$sqlConnection.Close()\n\t\t}\n\n\t\t# cleanup\n\t\t$sqlConnection.Dispose()\n\t}\n}\n#endregion\n",
    "Octopus.Action.Script.ScriptSource": "Inline"
  },
  "Category": "SQL Server",
  "HistoryUrl": "https://github.com/OctopusDeploy/Library/commits/master/step-templates//opt/buildagent/work/75443764cd38076d/step-templates/ssis-deploy-ispac-from-package.json",
  "Website": "/step-templates/bf005449-60c2-4746-8e07-8ba857f93605",
  "Logo": "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",
  "$Meta": {
    "Type": "ActionTemplate"
  }
}

History

Page updated on Thursday, April 18, 2019