Module/Administration/Copy-BCSTenantDatabase.ps1
<#
.SYNOPSIS Create new tenant database .DESCRIPTION Creates a new tenant database on SQL server using a template database .PARAMETER databaseServer SQL Server name .PARAMETER databaseServerInstance Name of the SQL Server and Instance, default BCNUP .PARAMETER databaseName Name of the new tenant/database .PARAMETER tempalteDatabase Name of the database on the server to use as a template when creating the new tenant database .PARAMETER templateDatabase Name of the template database to be restored, deafult Template (19-0) .PARAMETER tempFolder TempFolder where temporary database backup is saved, default c:\temp\ .PARAMETER databaseCredentials Your SQL login to the SQL Server, Credential information in the form of a System.Management.Automation.PSCredential object .NOTES Author: Mathias Stjernfelt Website: http://www.brightcom.se .EXAMPLE New-BCSTenantDatabase -databaseName "My New Tenant" New-BCSTenantDatabase -serverInstance myServerInstance -databaseName "My New Tenant" -templateDatabase myTemplateDatabase -credential $credentials #> function Copy-BCSTenantDatabase { Param ( [Parameter(ValueFromPipelineByPropertyName, Mandatory = $true)] $fromDatabaseServer, [Parameter(ValueFromPipelineByPropertyName, Mandatory = $false)] $fromDatabaseServerInstance, [Parameter(ValueFromPipelineByPropertyName, Mandatory = $true)] $fromDatabaseName, [Parameter(ValueFromPipelineByPropertyName, Mandatory = $true)] $fromDatabaseServerBackupFilepath, [Parameter(ValueFromPipelineByPropertyName, Mandatory = $false)] $fromDatabaseDataLogicalFileName, [Parameter(ValueFromPipelineByPropertyName, Mandatory = $false)] $fromDatabaseDataFolder, [Parameter(ValueFromPipelineByPropertyName, Mandatory = $false)] $fromDatabaseLogLogicalFileName, [Parameter(ValueFromPipelineByPropertyName, Mandatory = $false)] $fromDatabaseLogFolder, [Parameter(ValueFromPipelineByPropertyName, Mandatory = $false)] [System.Management.Automation.PSCredential]$fromDatabaseCredentials, [Parameter(ValueFromPipelineByPropertyName, Mandatory = $true)] $toDatabaseServer, [Parameter(ValueFromPipelineByPropertyName, Mandatory = $false)] $toDatabaseServerInstance, [Parameter(ValueFromPipelineByPropertyName, Mandatory = $true)] $toDatabaseName, [Parameter(ValueFromPipelineByPropertyName, Mandatory = $true)] $toDatabaseServerBackupFilepath, [Parameter(ValueFromPipelineByPropertyName, Mandatory = $false)] [System.Management.Automation.PSCredential]$toDatabaseCredentials, [Parameter(ValueFromPipelineByPropertyName, Mandatory = $false)] $toDatabaseDataLogicalFileName, [Parameter(ValueFromPipelineByPropertyName, Mandatory = $false)] $toDatabaseLogLogicalFileName, [Parameter(ValueFromPipelineByPropertyName, Mandatory = $false)] $blobStorageBackupFileURL ) begin {} process { if (-not $fromDatabaseCredentials) { $fromDatabaseCredentials = Get-BCSCredential -userName $userProfile.fromDatabaseUserName -securePassword (ConvertTo-SecureString -String $userProfile.fromDatabasePassword) } if (-not $toDatabaseCredentials) { $toDatabaseCredentials = Get-BCSCredential -userName $userProfile.databaseUserName -securePassword (ConvertTo-SecureString -String $userProfile.databasePassword) } if (-not(Get-Module -ListAvailable -Name BCSPowershellModule)) { Install-Module BCSPowershellModule -Force } $ErrorActionPreference = "Stop" if (-not(Get-Module -ListAvailable -Name SQLServer)) { Install-Module SQLServer -Force } if ([string]::IsNullOrEmpty($fromDatabaseServerInstance)) { $fromDatabaseServerInstance = $fromDatabaseServer } if ([string]::IsNullOrEmpty($toDatabaseServerInstance)) { $toDatabaseServerInstance = $toDatabaseServer } $databaseExists = $true try { Get-SqlDatabase -ServerInstance $toDatabaseServerInstance -Name $toDatabaseName -Credential $toDatabaseCredentials -ErrorAction Stop } catch { if ($_.CategoryInfo.Reason -like "SqlPowerShellObjectNotFoundException") { $databaseExists = $false } else { Write-Error "An error occurred: $($_.Exception)" } } if ($databaseExists) { Write-Error "Database $($toDatabaseName) already exists, aborting." } [String]$tenantId = $toDatabaseName.replace(' ', '') $tenantId = $tenantId.ToLower() Write-Host "Backup database $fromDatabaseName on $fromDatabaseServerInstance to folder $fromDatabaseServerBackupFilepath" Backup-SqlDatabase -ServerInstance $fromDatabaseServerInstance -Database $fromDatabaseName -BackupFile $fromDatabaseServerBackupFilepath -Credential $fromDatabaseCredentials -CopyOnly $toDatabaseServerBackupFileDirectory = Split-Path -Path $toDatabaseServerBackupFilepath -Parent Get-FileFromURLOnRemote -remoteServerName $toDatabaseServer -sourceURL $blobStorageBackupFileURL -destinationFolder $toDatabaseServerBackupFileDirectory -credentials $toDatabaseCredentials # Load the SQL Server Management Objects (SMO) assembly [System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SqlServer.Smo") # Connect to the SQL Server instance $serverInstance = New-Object Microsoft.SqlServer.Management.Smo.Server($toDatabaseServerInstance) $serverInstance.ConnectionContext.LoginSecure = $false $serverInstance.ConnectionContext.Login = $toDatabaseCredentials.GetNetworkCredential().UserName $serverInstance.ConnectionContext.Password = $toDatabaseCredentials.GetNetworkCredential().Password # Retrieve the default data and log file locations $toDatabaseDataFolder = $serverInstance.Settings.DefaultFile $toDatabaseLogFolder = $serverInstance.Settings.DefaultLog Write-Host "Relocating Data file Template_Data" $RelocateData = New-Object Microsoft.SqlServer.Management.Smo.RelocateFile($fromDatabaseDataLogicalFileName, "$($toDatabaseDataFolder)$($tenantId).mdf") Write-Host "Relocating Data file Template_Log" $RelocateLog = New-Object Microsoft.SqlServer.Management.Smo.RelocateFile($fromDatabaseLogLogicalFileName, "$($toDatabaseLogFolder)$($tenantId).ldf") Restore-SqlDatabase -ServerInstance $toDatabaseServerInstance -Database $toDatabaseName -BackupFile $toDatabaseServerBackupFilepath -RelocateFile @($RelocateData, $RelocateLog) -Credential $toDatabaseCredentials Write-Host "Changing database Logical Name $fromDatabaseDataLogicalFileName to $($toDatabaseDataLogicalFileName)_Data" Invoke-Sqlcmd -ServerInstance $toDatabaseServerInstance -Database $toDatabaseName -Query "ALTER DATABASE [$toDatabaseName] MODIFY FILE ( NAME = $fromDatabaseDataLogicalFileName, NEWNAME = $($toDatabaseDataLogicalFileName)_Data );" -Credential $toDatabaseCredentials Write-Host "Changing database Logical Name $fromDatabaseLogLogicalFileName to $($toDatabaseLogLogicalFileName)_Data" Invoke-Sqlcmd -ServerInstance $toDatabaseServerInstance -Database $toDatabaseName -Query "ALTER DATABASE [$toDatabaseName] MODIFY FILE ( NAME = $fromDatabaseLogLogicalFileName, NEWNAME = $($toDatabaseLogLogicalFileName)_Data );" -Credential $toDatabaseCredentials Write-Host "Database $toDdatabaseName has been created succesfully on SQL Server $toDatabaseServerInstance" #} -ArgumentList $databaseServerInstance, $databaseCredentials, $tenantId, $templateDatabase, $backupFilepath } end { } } Export-ModuleMember -Function Copy-BCSTenantDatabase |