public/Publish-DacPac.ps1
function Publish-DacPac { <# .SYNOPSIS Publish-DacPac allows you to deploy a SQL Server Database using a DACPAC to a SQL Server instance. .DESCRIPTION Publishes a SSDT DacPac using a specified DacPac publish profile from your solution. Basically deploys the DACPAC by invoking SqlPackage.exe using a DacPac Publish profile Written by (c) Dr. John Tunnicliffe, 2019 https://github.com/DrJohnT/PublishDacPac This PowerShell script is released under the MIT license http://www.opensource.org/licenses/MIT .PARAMETER DacPacPath Full path to your database DACPAC (e.g. C:\Dev\YourDB\bin\Debug\YourDB.dacpac) .PARAMETER DacPublishProfile Name of the DAC Publish Profile to be found in the same folder as your DACPAC (e.g. YourDB.CI.publish.xml) You can also provide the full path to an alternative DAC Publish Profile. .PARAMETER TargetServerName Name of the target server, including instance and port if required. .PARAMETER TargetDatabaseName Normally, the database will be named the same as your DACPAC. However, by adding the -TargetDatabaseName parameter, you can name the database anything you like. .PARAMETER PreferredVersion Defines the preferred version of SqlPackage.exe you wish to use. Use 'latest' for the latest version, or do not provide the parameter. .PARAMETER TestMode For use with Pester tests, this simply switches off the actual deployment of the database with SqlPackage.exe. .EXAMPLE Publish-DacPac -DacPacPath "C:\Dev\YourDB\bin\Debug\YourDB.dacpac" -DacPublishProfile "YourDB.CI.publish.xml" -TargetServerName "YourDBServer" #> [CmdletBinding()] param ( [String] [Parameter(Mandatory = $true)] $DacPacPath, [String] [Parameter(Mandatory = $true)] $DacPublishProfile, [String] [Parameter(Mandatory = $true)] $TargetServerName, [String] [Parameter(Mandatory = $false)] $TargetDatabaseName, [String] [Parameter(Mandatory = $false)] $PreferredVersion, [Boolean] [Parameter(Mandatory = $false)] $TestMode ) $global:ErrorActionPreference = 'Stop'; try { # find the specific version of SqlPackage or the latest if not available $Version = Select-SqlPackageVersion -PreferredVersion $PreferredVersion; $SqlPackageExePath = Get-SqlPackagePath -Version $Version; if (!(Test-Path -Path $SqlPackageExePath)) { Write-Error "Could not find SqlPackage.exe in order to deploy the database DacPac!"; Write-Warning "For install instructions, see https://www.microsoft.com/en-us/download/details.aspx?id=57784/"; throw "Could not find SqlPackage.exe in order to deploy the database DacPac!"; } [String]$ProductVersion = (Get-Item $SqlPackageExePath).VersionInfo.ProductVersion; if (!(Test-Path -Path $DacPacPath)) { throw "DacPac path does not exist in $DacPacPath"; } $DacPacName = Split-Path $DacPacPath -Leaf; $OriginalDbName = $DacPacName -replace ".dacpac", "" $DacPacFolder = Split-Path $DacPacPath -Parent; if ($TargetDatabaseName -eq "") { $TargetDatabaseName = $OriginalDbName; } # figure out if we have a full path to the DAC Publish Profile or just the filename of the DAC Publish Profile in the same folder as the DACPAC if (Test-Path($DacPublishProfile)) { $DacPacPublishProfilePath = $DacPublishProfile; } else { try { $DacPacPublishProfilePath = Resolve-Path "$DacPacFolder\$DacPublishProfile"; } catch { throw "DAC Publish Profile does not exist"; } } $ProfileName = Split-Path $DacPacPublishProfilePath -Leaf; Write-Verbose "Publish-DacPac: Target database '$TargetDatabaseName'"; Write-Verbose "Publish-DacPac: Target server '$TargetServerName'"; Write-Verbose "Publish-DacPac: DacPac '$DacPacName' from '$DacPacFolder'"; Write-Verbose "Publish-DacPac: Dac Profile '$ProfileName' from '$DacPacPublishProfilePath'"; Write-Verbose "Publish-DacPac: SqlPackage.exe version $ProductVersion from '$SqlPackageExePath'"; #Write-Verbose "Publish-DacPac: DacPacDacPublishProfileTemplate = $DacPacPublishProfilePath"; [xml]$DacPacDacPublishProfile = [xml](Get-Content $DacPacPublishProfilePath); $DacPacDacPublishProfile.Project.PropertyGroup.TargetDatabaseName = "$TargetDatabaseName"; $DacPacDacPublishProfile.Project.PropertyGroup.TargetConnectionString = "Data Source=$TargetServerName;Integrated Security=True"; $DacPacUpdatedProfilePath = "$DacPacFolder\$OriginalDbName.deploy.publish.xml"; $DacPacDacPublishProfile.Save($DacPacUpdatedProfilePath); $global:lastexitcode = 0; if (!(Ping-SqlServer -ServerName $TargetServerName)) { throw "Server '$TargetServerName' does not exist!"; } else { #if ($global:Debug) { if ($TestMode) { Write-Information "In 'Don't Deploy' Mode, so will not deploy"; } else { Write-Verbose "Publish-DacPac: Deploying database '$TargetDatabaseName' to server '$TargetServerName' using DacPac '$DacPacName'" #Write-Verbose "$SqlPackageExePath /Action:Publish /SourceFile:$DacPacPath /Profile:$DacPacUpdatedProfilePath"; &"$SqlPackageExePath" /Action:Publish /SourceFile:"$DacPacPath" /Profile:"$DacPacUpdatedProfilePath" if ($lastexitcode -ne 0) { Write-Error "Error executing $SqlPackageExePath deployment"; } } } } catch { Write-Error "Error: $_"; } } |