Hola a todos,
En el último artículo hablábamos sobre cómo automatizar el despliegue de informes de Reporting Services de forma “automática” mediante un pequeño script de Power Shell.
En esta ocasión vamos a ver cómo podemos hacer algo similar para desplegar paquetes de Integration Services también mediante la ejecución de un script de Power Shell.
Automatizar el Despliegue de Paquetes de SSIS con PowerShell
En este caso también vamos a trabajar con 2 archivos:
- Un fichero de configuración donde están los datos de conexión al server de Integration y las rutas de los paquetes, así como las rutas de despliegue de los mismos.
- DespliegueSSIS.cfg
- El script principal Power Shell de ejecución.
- PS_Lab05_DeploySSIS.ps1
Nuestro fichero de parámetros tiene el siguiente contenido:
ServerName = SQLBI SSISCatalog = SSISDB CatalogPwd = L@TYExz$6*8>'dE^ ProjectFilePath = C:\PackagesToDeploy\ ProjectName = TheAlanParsonsProject FolderName = TAPP EnvironmentName = TAPP_Env_Test Password = 7h3P455w0rD WebServer = www.taap.com User = myUser
Donde vemos parametrizados los siguientes elementos:
- ServerName: Nombre del servidor donde está albergado el SSIS
- SSISCatalog: Nombre del catálogo donde está albergado el catálogo
- CatalogPwd: Password del catálogo (se nos pedirá a la hora de crear un catálogo en caso de que no esté creado).
- ProjectFilePath: Ruta donde están los paquetes (*.ispaq) a desplegar
- ProjectName: Nombre que le queremos dar al proyecto
- FolderName: Nombre del directorio donde desplegaremos el proyecto en el servidor
- EnvironmentName: Nombre del entorno que albergará las variables de configuración de los paquetes
A partir de esta linea del fichero de configuración van los parámetros que hay que mapear en nuestro paquete para que funcione
Como podéis ver en esta captura nuestro proyecto tiene 3 parámetros (Password, User y WebServer), por lo tanto nuestro fichero de configuración también tendrá los valores de estos parámetros para poder configurar el paquete desplegado.
Los pasos que vamos a seguir son los siguientes:
- Conectar al servidor indicado en el fichero de parámetros.
- Comprobar si existe el catalogo, si existe lo usamos para publicar en el nuestro nuevo proyecto en caso de que no exista el catalogo lo creamos.
- Comprobamos si existe la carpeta donde publicar el proyecto y si no existe la creamos.
- Publicamos el proyecto (sobrescribiendo si ya existe)
- Comprobamos si existe el entorno con las variables de configuración del paquete. si no es así lo creamos
- Por ultimo mapeamos las variables del entorno con las del paquete por nombre (las variables del paquete se llamarán igual que las del entorno).
Manos a la obra, en primer lugar asignamos en una variable la ruta del fichero de configuración e, leemos dicho fichero con la instrucción Get-Content usando el modificador foreach introducimos sus valores en variable (salvo los de los parámetros de configuración del paquete)
$pParamFilePath = "C:\PowerShell\DespliegueSSIS.cfg" $ConfigParam = @{} # Tabla de hash para guardar los pares Parametro - Valor Get-Content $pParamFilePath | foreach { $line = $_.split("=") $ConfigParam.($line[0].Trim()) = $line[1].Trim() } $ServerName =$ConfigParam.ServerName $SSISCatalog =$ConfigParam.SSISCatalog $CatalogPwd =$ConfigParam.CatalogPwd $ProjectFilePath =$ConfigParam.ProjectFilePath $ProjectName =$ConfigParam.ProjectName $FolderName =$ConfigParam.FolderName $EnvironmentName =$ConfigParam.EnvironmentName $MainPackage =$ConfigParam.MainPackage
Como podéis ver los valores de Usuario, Password y WebServer, no se asignan a variables ya que pueden variar de un proyecto a otro, los obtendremos mas adelante directamente del fichero.
Una vez tenemos los valores necesarios para trabajar en variables, cargamos el modulo de integration services en memoria, escribimos el resultado de la operación de carga del ensamblado en pantalla, y por ultimo guardamos la ruta (namespace) del ensamblado en una variable para usarla mas adelante.
$ISLoadStatus = [Reflection.Assembly]::LoadWithPartialName("Microsoft.SqlServer.Management.IntegrationServices") Write-Host (" Microsoft.SqlServer.IntegrationServices.." + "[Ok]") # Guardamos la ruta del ensamblado (para reutilizar luego) $ISNamespace = "Microsoft.SqlServer.Management.IntegrationServices"
Ahora creamos una conexión con el servidor de SQL Server usando los parametros previamente cargados del fichero de configuración, mostramos por pantalla el resultado de la conexión y creamos un objeto de tipo “IntegrationServices” con el que accederemos a los objetos del servidor.
$constr = "Data Source="+ $ServerName + ";Initial Catalog=master;Integrated Security=SSPI;" $con = New-Object System.Data.SqlClient.SqlConnection $constr Write-Host ("Conectado con el servidor: "+ $ServerName + "..." + "[Ok]") #Creamos un objeto integration services conectado al servidor $ssis = New-Object $ISNamespace".IntegrationServices" $con
El siguiente paso es comprobar si existe un catalogo (con proyectos o vacío) desplegado en el servidor de SSIS, si ya existe usamos ese catalogo para desplegar nuestro proyecto, en caso contrario lo creamos poniéndole la contraseña que leímos del fichero de configuración.
# Dentro del objeto que anteriormente definimos con la conexion a SSIS podemos # localizar todos los objetos del servidor, catalogo, carpetas, entornos... etc # Con la siguiente instruccion comprobamos si existe un catalogo con el mimsmo # nombre que el que leímos del fichero de configuración. if (($ssis.Catalogs | Where{$_.Name -eq $SSISCatalog}) -ne $null) { $catalog = $ssis.Catalogs | Where{$_.name -eq $SSISCatalog} } else { #Si no existe lo creamos. #Creamos el nuevo catalogo donde se almacenaran los paquetes $catalog = New-Object $ISNamespace".Catalog" ($ssis) $Pass = $catalog.Properties | ? {$_.Name -eq "Password"} $pass.value = $CatalogPwd $catalog.Create() Write-Host ("Se ha creado el catálogo: " + $catalog.Name + "..." + "[Ok]") }
Dentro del catálogo comprobamos si ya existe la carpeta donde se guardarán los paquetes de nuestro proyecto, si no existe la creamos
# Comprobamos si existe una carpeta con el nombre igual al almacenado # en la variable $FolderName que leimos del # fichero de configuración $folder = $catalog.Folders[$FolderName] if (!$folder) { # Si no existe la creamos $folder = New-Object "$ISNamespace.CatalogFolder" ($catalog, $FolderName, $FolderName) $folder.Create() Write-Host ("Se ha creado la carpeta: " + $FolderName + "..." + "[Ok]") }
Ahora leemos el paquete a desplegar (TheAlanParsonsProject.ispac) y lo guardamos en una variable como binario, luego lo desplegamos en la carpeta correspondiente sobrescribiendolo si ya existe.
#Leemos el fichero del proyecto y loalmacenamos en una variable y lo desplegamos [byte[]] $projectFile = [System.IO.File]::ReadAllBytes($ProjectFilePath) # Desplegamos el proyecto. $pDeployment = $folder.DeployProject($ProjectName, $projectFile) Write-Host ("Se ha desplegado el proyecto: " + $ProjectName + "..." + $pDeployment.Id + " ...[Ok]")
Ahora debemos crear (si no existe) el entorno donde se guardarán los parámetros con los que se ejecutará el paquete.
#Creamos un entorno de almacenamiento de variables (si no existe) $environment = $folder.Environments[$EnvironmentName] if (!$environment) { $environment = New-Object "$ISNamespace.EnvironmentInfo" ($folder, $EnvironmentName, $EnvironmentName) $environment.Create() Write-Host ("Se ha creado el entorno: " + $EnvironmentName + "..." + "[Ok]") }
En este punto como podemos ver en la captura ya se nos ha creado la carpeta con el proyecto y el entorno con nombre TAPP_Env_Test.
Ahora debemos asociar el proyecto con el entorno recién creado para que nuestro paquete pueda usar las variables de ese entorno para ejecutarse.
#Vinculamos el proyecto y el entorno para que se puedan usar sus variables #----------------------------------------------------------------------------- $project = $folder.Projects[$ProjectName] $ref = $project.References[$EnvironmentName, $folder.Name] if (!$ref) { $project.References.Add($EnvironmentName, $folder.Name) $project.Alter() Write-Host ("Se ha creado una referencia entre el proyecto : " + $ProjectName + " y el entorno: " + $EnvironmentName) }
Por último vinculamos las variables del entorno con los parámetros de ejecución del nuestro paquete, el mapeo se hace por nombre, se llaman igual las variables del entorno que los parámetros del paquete.
#Recorremos la coleccion de parametros en el paquete principal #y lo mapeamos con su correspondiente variabel de entorno foreach ($Var in $project.Parameters) { #Leemos el valor del parameto del fichero de configuracion $valparam = $ConfigParam[$Var.Name] #Obtenemos la la variable del entorno a la que vamos a poner valor $EnvVar = $environment.Variables[$Var.Name] #si se localiza la variable se le asocia al parametro del paquete con el mismo nombre esa variable del entorno if (!$EnvVar) { $environment.Variables.Add($Var.Name, $Var.DataType, $valparam, $false, $Var.Name) $environment.Alter() $customerID = $environment.Variables[$Var.Name]; Write-Host ("Se ha creado la variable de entorno: " + $Var.Name + " con valor: " + $valparam) } $Var.Set([Microsoft.SqlServer.Management.IntegrationServices.ParameterInfo+ParameterValueType]::Referenced, $Var.Name) $package.Alter() }
Como se puede observar en esta otra captura se ha creado correctamente la asociación entre nuestro proyecto y el entorno con las variables
y por ultimo vemos como también nuestras variables del entorno están disponibles en el proyecto para ser usadas:
Y con esto ya tendríamos desplegado y listo para ejecutar nuestro proyecto.
Espero que os sirva de utilidad.
Un saludo 🙂