SQL/DBdeployer.ps1
# ================================================================================================================= # Purpose: # Revisions: # 05242019 - Kevin Barlett, Microsoft - Initial creation. # # ================================================================================================================= # ----------------------------------------------------------------------------- # # Copyright (C) 2019 Microsoft Corporation # # Disclaimer: # This is SAMPLE code that is NOT production ready. It is the sole intention of this code to provide a proof of concept as a # learning tool for Microsoft Customers. Microsoft does not provide warranty for or guarantee any portion of this code # and is NOT responsible for any affects it may have on any system it is executed on or environment it resides within. # Please use this code at your own discretion! # Additional legalese: # This Sample Code is provided for the purpose of illustration only and is not intended to be used in a production environment. # THIS SAMPLE CODE AND ANY RELATED INFORMATION ARE PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, # INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE. # We grant You a nonexclusive, royalty-free right to use and modify the Sample Code and to reproduce and distribute # the object code form of the Sample Code, provided that You agree: # (i) to not use Our name, logo, or trademarks to market Your software product in which the Sample Code is embedded; # (ii) to include a valid copyright notice on Your software product in which the Sample Code is embedded; and # (iii) to indemnify, hold harmless, and defend Us and Our suppliers from and against any claims or lawsuits, including attorneys' fees, # that arise or result from the use or distribution of the Sample Code. # ----------------------------------------------------------------------------- param( [CmdletBinding()] [Parameter(ParameterSetName='Set1',Position=0,Mandatory=$true)][String]$DBserverName, [parameter(ParameterSetName='Set1',Position=1,Mandatory=$true)][String]$DatabaseName # [parameter(ParameterSetName='Set2',Position=2,Mandatory=$true)][String[]]$serverList ) $Timestamp = (get-date).ToString("MMddyyyyHHmmss") $CurTime = get-date $LogFile = ".\DBdeployLog_$Timestamp.txt" #======================================================================== # Create logging function #======================================================================== function log($string, $color) { if ($null -eq $color) {$color = "white"} #write-host $string -foregroundcolor $color $string | out-file -Filepath $logfile -append } $HeaderMessage = " /////////////////////////////////////////////////////////////////////////////// \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ PowerSTIGscan Database Installer - v0.1 $CurTime /////////////////////////////////////////////////////////////////////////////// \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ " #-foregroundcolor "Red" Write-Host $HeaderMessage -ForegroundColor Green Log $HeaderMessage #$UserContext = [System.Security.Principal.WindowsIdentity]::GetCurrent().Name #$ServerName = $(Get-Content env:computername) #======================================================================== #Scrub inputs #======================================================================== $DBServerName = $DBServerName.trim() # $DatabaseName = $DatabaseName.trim() #======================================================================== #Perform test connection #======================================================================== If (Test-Connection $DBServerName -count 1 -quiet) { $CurTime = get-date [console]::ForegroundColor = "Green" $LogMessage = "---> Servername $DBServerName appears to be valid. Continuing. . ." Write-Host $LogMessage [console]::ResetColor() # log [$CurTime]$LogMessage } Else { $CurTime = get-date [console]::ForegroundColor = "Red" $LogMessage = "---> Servername $DBServerName appears to be invalid or the server is unavailable. Please validate the specified SQL Server name. Exiting." Write-Host $LogMessage [console]::ResetColor() # log [$CurTime]$LogMessage EXIT } #======================================================================== #Validate database existence #======================================================================== $CurTime = get-date [console]::ForegroundColor = "Green" $LogMessage = "---> Checking for the existence of database [$DatabaseName]" Write-Host $LogMessage [console]::ResetColor() # log [$CurTime]$LogMessage $DBexistsQuery = "SELECT 1 AS DatabaseExists FROM sys.databases where [name] = '$DatabaseName' and [state] = 0 and is_read_only = 0" $SqlConnection = New-Object System.Data.SqlClient.SqlConnection $SqlConnection.ConnectionString = "Server=$DBServerName;Database=master;Integrated Security=True" $SqlCmd = New-Object System.Data.SqlClient.SqlCommand $SqlCmd.CommandText = $DBexistsQuery $SqlCmd.Connection = $SqlConnection $SqlAdapter = New-Object System.Data.SqlClient.SqlDataAdapter $SqlAdapter.SelectCommand = $SqlCmd $DataSet = New-Object System.Data.DataSet [void]$SqlAdapter.Fill($DataSet) $SqlConnection.Close() $DBexists = $DataSet.Tables[0] | Select-Object DatabaseExists -ExpandProperty DatabaseExists if ($DBexists -ne 1) { $CurTime = get-date [console]::ForegroundColor = "Yellow" $LogMessage = "---> Specified database [$DatabaseName] was not found. Creating database [$DatabaseName] now." Write-Host $LogMessage [console]::ResetColor() # log [$CurTime]$LogMessage try { $CreateDatabaseQuery = " DECLARE @DatabaseName varchar(256) SET @DatabaseName = '$DatabaseName' DECLARE @DefaultDataLoc varchar(256) DECLARE @DefaultLogLoc varchar(256) DECLARE @SQLCMD varchar(MAX) SELECT @DefaultDataLoc = CAST(SERVERPROPERTY('InstanceDefaultDataPath') AS varchar(256)), @DefaultLogLoc = CAST(SERVERPROPERTY('InstanceDefaultLogPath') AS varchar(256)) -- SET @SQLCMD = 'CREATE DATABASE ['+@DatabaseName+'] ON PRIMARY (NAME = '''+@DatabaseName+'_data'', FILENAME = '''+@DefaultDataLoc+''+@DatabaseName+'_data.mdf'' , SIZE = 128MB , MAXSIZE = UNLIMITED, FILEGROWTH = 128MB) LOG ON (NAME = '''+@DatabaseName+'_log'', FILENAME = '''+@DefaultLogLoc+''+@DatabaseName+'_log.ldf'' , SIZE = 128MB , MAXSIZE = 2048GB , FILEGROWTH =128MB)' --PRINT @SQLCMD EXEC(@SQLCMD) -- SET @SQLCMD = 'ALTER DATABASE ['+@DatabaseName+'] SET RECOVERY SIMPLE' --PRINT @SQLCMD EXEC(@SQLCMD) -- SET @SQLCMD = 'ALTER DATABASE ['+@DatabaseName+'] SET PAGE_VERIFY CHECKSUM' --PRINT @SQLCMD EXEC(@SQLCMD) " $SqlConnection = New-Object System.Data.SqlClient.SqlConnection $SqlConnection.ConnectionString = "Server=$DBServerName;Database=master;Integrated Security=True" $SqlCmd = New-Object System.Data.SqlClient.SqlCommand $SqlCmd.CommandText = $CreateDatabaseQuery $SqlCmd.Connection = $SqlConnection $SqlAdapter = New-Object System.Data.SqlClient.SqlDataAdapter $SqlAdapter.SelectCommand = $SqlCmd $DataSet = New-Object System.Data.DataSet [void]$SqlAdapter.Fill($DataSet) $SqlConnection.Close() $CurTime = get-date [console]::ForegroundColor = "Green" $LogMessage = "---> Database [$DatabaseName] created successfully." Write-Host $LogMessage [console]::ResetColor() # log [$CurTime]$LogMessage } catch { $CurTime = get-date [console]::ForegroundColor = "Red" $LogMessage = "---> An error was encountered while creating database [$DatabaseName]. Please investigate." Write-Host $LogMessage [console]::ResetColor() # log [$CurTime]$LogMessage } } else { $CurTime = get-date [console]::ForegroundColor = "Green" $LogMessage = "---> The specified database [$DatabaseName] already exists. PowerSTIGscan deployment continuing." Write-Host $LogMessage [console]::ResetColor() # log [$CurTime]$LogMessage } #======================================================================== #Execute deployment scripts #======================================================================== $DeployScripts = Get-ChildItem "$(Split-Path $PsCommandPath)\" | Where-Object {$_.Extension -eq ".sql"} | Sort-Object Name foreach ($Script in $DeployScripts) { try { Write-Host "Executing Script: " $Script.Name -BackgroundColor DarkGreen -ForegroundColor White $script = $Script.FullName #write-host $script $DatabaseScript = Get-Content $Script | Out-String $ScriptBatches = $DatabaseScript -split "GO\r\n" foreach ($Batch in $ScriptBatches) { $SqlConnection = New-Object System.Data.SqlClient.SqlConnection $SqlConnection.ConnectionString = "Server=$DBServerName;Database=$DatabaseName;Integrated Security=True" $SqlCmd = New-Object System.Data.SqlClient.SqlCommand $SqlCmd.CommandText = $Batch; $SqlCmd.Connection = $SqlConnection $SqlAdapter = New-Object System.Data.SqlClient.SqlDataAdapter $SqlAdapter.SelectCommand = $SqlCmd $DataSet = New-Object System.Data.DataSet [void]$SqlAdapter.Fill($DataSet) #$SqlAdapter.Fill($DataSet) | Out-Null $SqlConnection.Close() } $CurTime = get-date [console]::ForegroundColor = "Green" $LogMessage = "---> Script [$script] executed successfully." #Write-Host $LogMessage [console]::ResetColor() # log [$CurTime]$LogMessage # Write-Host "Execution successful for script: " $Script.Name -BackgroundColor DarkGreen -ForegroundColor White } catch { $UpdateApplied = $DataSet.Tables[0] | Select-Object UpdateApplied -ExpandProperty UpdateApplied if ($UpdateApplied -eq 8675309){ $CurTime = get-date $LogMessage = "---> Database update previously applied. This is an informational message only." log [$CurTime]$LogMessage Write-Host $LogMessage -BackgroundColor Yellow -ForegroundColor Black } else { $CurTime = get-date [console]::ForegroundColor = "Green" $LogMessage = "---> Error encountered executing script [$script]. Please investigate." #Write-Host $LogMessage [console]::ResetColor() # log [$CurTime]$LogMessage #log [$CurTime]$PSItem log [$CurTime]$_ # Write-Host "Error encountered executing script: " $Script.Name -BackgroundColor Red -ForegroundColor White } } } |