SkyWire-PSDatabase.psm1
<#
.SYNOPSIS Creates a new database for a SkyWire Point of Sale product. .DESCRIPTION Publishes the dacpac for a specified app and tag (as well as optional bacpac to include test data) to a specified server. .PARAMETER app The app to establish a database for. Valid values: POS, SRDM, Reporting. .PARAMETER tag The tag (ticket number) for the build to download and deploy. This tag will be used in the db name. .PARAMETER dbServer The database server (default: localhost). .PARAMETER dbUser The database user id. .PARAMETER dbPassword The database password. .PARAMETER rootDir Specify the root directory where all data will reside for the current deployment (default: %PROGRAMDATA%\SkyWire-PSInstaller). .PARAMETER bacpacUrl If the app parameter is "BACPAC", the URL to download the .bacpac file from. .PARAMETER force If a bacpac is supplied, and a database for the specified tag already exists, force it to be dropped and recreated without prompting. .PARAMETER refresh Indicates that any currently cached copy of this file should be refreshed. .NOTES This script requires the use of the PublishDacPac module. Run Install-Module -Name PublishDacPac if you do not have this. By default, the database will use Trusted Connection. Provide dbUser and dbPassword if user/password need to be used. .EXAMPLE New-SWDatabase -app POS -tag POS-0000-beta .EXAMPLE New-SWDatabase -app POS -tag POS-0000-beta -dbServer remoteSqlHost -dbUser sa -dbPassword password -bacpac "C:\MyStartingData.bacpac" -force #> function New-SWDatabase { param( [Parameter(Mandatory=$true)] [ValidateSet("POS","SRDM","Reporting")] [string] $app, [Parameter(Mandatory=$true)] [string] $tag, [Parameter(Mandatory=$false)] [string] $dbServer = "localhost", [Parameter(Mandatory=$false)] [string] $dbName = "$tag-$app", [Parameter(Mandatory=$false)] [string] $dbUser = "", [Parameter(Mandatory=$false)] [string] $dbPassword = "", [Parameter(Mandatory=$false)] [string] $rootDir = "$env:PROGRAMDATA\SkyWire-PSInstaller", [Parameter(Mandatory=$false)] [string] $bacpacUrl, [Parameter(Mandatory=$false)] [switch] $force, [Parameter(Mandatory=$false)] [switch] $refresh ) $trustedConnection = !$dbUser -and !$dbPassword $connectionString = "Data Source=$dbServer;Initial Catalog=$dbName;Integrated Security=$trustedConnection;" if (!($trustedConnection)) { $connectionString = "$($connectionString)User Id=$dbUser;Password=$dbPassword;" } if ($bacpacUrl) { $bacpac = Get-SWInstallPackage -app "BACPAC" -bacpacUrl $bacpacUrl -tag $tag -rootDir $rootDir -refresh:$refresh try { if (Test-Path $bacpac) { $version = Select-SqlPackageVersion -PreferredVersion "120"; $sqlPackageExe = Get-SqlPackagePath -Version $version; if (!(Test-Path $sqlPackageExe)) { Write-Error "Could not find SqlPackage.exe in order to import the database BacPac!" 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 import the database BacPac!" } #See if the database already exists: $sqlDbCheck = "SELECT [create_date] FROM [Sys].[databases] WHERE [Name] = '$dbName'" if ($trustedConnection) { $sqlDbCheckResult = Invoke-SqlCmd -Query $sqlDbCheck -ServerInstance $dbServer } else { $sqlDbCheckResult = Invoke-SqlCmd -Query $sqlDbCheck -ServerInstance $dbServer -Username $dbUser -Password $dbPassword } $dbCreatedDate = $sqlDbCheckResult.create_date $applyBacpac = 1 if ($dbCreatedDate) { Write-Warning "The database $dbName already exists!" if (!($force)) { $newDbNo = New-Object System.Management.Automation.Host.ChoiceDescription "&No", "Uses the existing database and ignores the specified bacpac" $newDbYes = New-Object System.Management.Automation.Host.ChoiceDescription "&Yes", "Deletes the existing database and creates a new one from the specified bacpac" $options = [System.Management.Automation.Host.ChoiceDescription[]]($newDbNo, $newDbYes) $promptMessage = "A database named '$dbName' was previously created at $dbCreatedDate. Would you like to delete it and create a new version from your bacpac?" $applyBacpac = $host.ui.PromptForChoice("Delete Previous Database", $promptMessage, $options, 0) } if ($applyBacpac -eq 1) { if ($trustedConnection) { Remove-SWDatabase -dbName $dbName -dbServer $dbServer } else { Remove-SWDatabase -dbName $dbName -dbServer $dbServer -dbUser $dbUser -dbPassword $dbPassword } } } if ($applyBacpac -eq 1) { #Create database from bacpac, then apply dacpac to update $argList = @( "/Action:Import", "/SourceFile:$bacpac", "/TargetConnectionString:$connectionString" ); Invoke-ExternalCommand -Command "$sqlPackageExe" -Arguments $argList; } } } catch { Write-Error "An error occurred while attempting to apply the bacpac. Please verify the URL is correct and try restarting the SQL Service, verifying yoru credentials, and running this script again." throw $_.Exception } } #Apply the dacpac to create a new DB, or upgrade the one we just imported try { $dacpac = Get-SWInstallPackage -app "$($app)DAC" -tag $tag -rootDir $rootDir -refresh $refresh $tempPublishProfile = New-TemporaryFile Rename-Item -Path $tempPublishProfile.FullName -NewName "$tempPublishProfile.publish.xml" $publishProfile = "$($tempPublishProfile.FullName).publish.xml" $xml = New-Object System.Collections.ArrayList $xml.Add('<?xml version="1.0" encoding="utf-8"?>') > $null $xml.Add('<Project ToolsVersion="Current" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">') > $null $xml.Add(" <PropertyGroup>") > $null $xml.Add(" <IncludeCompositeObjects>True</IncludeCompositeObjects>") > $null $xml.Add(" <TargetDatabaseName>$tag-$app</TargetDatabaseName>") > $null $xml.Add(" <TargetConnectionString>$($connectionString)Pooling=False;Connect Timeout=60;Encrypt=False;TrustServerCertificate=False;</TargetConnectionString>") > $null $xml.Add(" <BlockOnPossibleDataLoss>False</BlockOnPossibleDataLoss>") > $null $xml.Add(" <ProfileVersionNumber>1</ProfileVersionNumber>") > $null $xml.Add(" </PropertyGroup>") > $null $xml.Add("</Project>") > $null $xml|Out-File $publishProfile #Create database from dacpac Publish-DacPac -DacPacPath $dacpac -DacPublishProfile $publishProfile -Server $dbServer -Database $dbName Remove-Item $publishProfile -Force } catch { Write-Error "An error occurred while attempting to apply the dacpac. This typically happens when the database is currently in use or the authentication is incorrect. Try restarting the SQL Service, verifying yoru credentials, and running this script again." throw $_.Exception } } <# .SYNOPSIS Removes a SkyWire database. .DESCRIPTION Removes the specified database from the specified server using the provided credentials (or windows account, if no credentials are provided). .PARAMETER dbName The name of the database to remove. .PARAMETER dbServer The database server (default: localhost). .PARAMETER dbUser The SQL user. Leave blank for integrated security. .PARAMETER dbPassword The SQL password. Leave blank for integrated security. .NOTES This script requires the use of the PublishDacPac module. Run Install-Module -Name PublishDacPac if you do not have this. By default, the database will use Trusted Connection. Provide dbUser and dbPassword if user/password need to be used. .EXAMPLE Remove-SWDatabase -dbName SkyWirePOS #> function Remove-SWDatabase { param ( [Parameter(Mandatory=$true)] [string] $dbName, [Parameter(Mandatory=$false)] [string] $dbServer = "localhost", [Parameter(Mandatory=$false)] [string] $dbUser = "", [Parameter(Mandatory=$false)] [string] $dbPassword = "" ) try { Write-Warning "Dropping existing $dbName database..." if (!$dbUser -and !$dbPassword) { Invoke-SqlCmd -Query "DROP DATABASE [$dbName]" -ServerInstance $dbServer } else { Invoke-SqlCmd -Query "DROP DATABASE [$dbName]" -ServerInstance $dbServer -Username $dbUser -Password $dbPassword } } catch { Write-Error "An error occurred while attempting to remove the previous database. This typically happens when the database is currently in use. Try restarting the SQL Service and running this script again." throw $_.Exception } } |