-
Notifications
You must be signed in to change notification settings - Fork 4
/
UnlinkDropRelinkDatabases.ps1
482 lines (414 loc) · 22.2 KB
/
UnlinkDropRelinkDatabases.ps1
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
#region FUNCTIONS
#this function creates the entry for the configuration xml file (RedGate config file)
function AddAndSaveXmlConfiguration (
[string]$serverName = $(Throw 'serverName is required'),
[string]$databaseName = $(Throw 'databaseName is required'),
[string]$workSpacePath = $(Throw 'workSpacePath is required'),
[string]$hooksPath = $(Throw 'hooksPath is required'),
[string]$workingBasePath = $(Throw 'workingBasePath is required'),
[string]$transientPath = $(Throw 'transientPath is required'),
[xml]$xmlLinkedDatabases = $(Throw 'xmlLinkedDatabases is required'),
[string]$xmlConfigurationsFilePath = $(Throw 'xmlConfigurationsFilePath is required'),
[string]$sourceControlName = $(Throw 'sourceControlName is required'))
{
#value node
$xmlValueNode = $xmlLinkedDatabases.LinkedDatabaseStore.LinkedDatabaseList.AppendChild($xmlLinkedDatabases.CreateElement("value"))
$xmlValueNode.SetAttribute("version", "7")
$xmlValueNode.SetAttribute("type", "LinkedDatabase")
#DatabaseId node
$xmlDatabaseIdNode = $xmlValueNode.AppendChild($xmlLinkedDatabases.CreateElement("DatabaseId"))
$xmlDatabaseIdNode.SetAttribute("version", "2")
$xmlDatabaseIdNode.SetAttribute("type", "DatabaseId")
#ServerAndInstanceName node
$xmlServerAndInstanceNameNode = $xmlDatabaseIdNode.AppendChild($xmlLinkedDatabases.CreateElement("ServerAndInstanceName"))
$xmlServerAndInstanceNameNode = $xmlServerAndInstanceNameNode.AppendChild($xmlLinkedDatabases.CreateTextNode($serverName))
#DatabaseName node
$xmlDatabaseNameNode = $xmlDatabaseIdNode.AppendChild($xmlLinkedDatabases.CreateElement("DatabaseName"))
$xmlDatabaseNameNode = $xmlDatabaseNameNode.AppendChild($xmlLinkedDatabases.CreateTextNode($databaseName))
#ISrcCLocation node
$xmlISrcCLocationNode = $xmlValueNode.AppendChild($xmlLinkedDatabases.CreateElement("ISrcCLocation"))
if ($sourceControlName -eq "WorkingFolder")
{
$xmlISrcCLocationNode.SetAttribute("version", "2")
$xmlISrcCLocationNode.SetAttribute("type", "WorkingFolderGenericLocation")
#LocalRepositoryFolder node
$xmlLocalRepositoryFolderNode = $xmlISrcCLocationNode.AppendChild($xmlLinkedDatabases.CreateElement("LocalRepositoryFolder"))
$xmlLocalRepositoryFolderNode = $xmlLocalRepositoryFolderNode.AppendChild($xmlLinkedDatabases.CreateTextNode($workSpacePath+'\'))
}
if ($sourceControlName -eq "git")
{
$xmlISrcCLocationNode.SetAttribute("version", "1")
$xmlISrcCLocationNode.SetAttribute("type", "GitLocalLocation")
#LocalRepositoryFolder node
$xmlLocalRepositoryFolderNode = $xmlISrcCLocationNode.AppendChild($xmlLinkedDatabases.CreateElement("LocalPath"))
$xmlLocalRepositoryFolderNode = $xmlLocalRepositoryFolderNode.AppendChild($xmlLinkedDatabases.CreateTextNode($workSpacePath+'\'))
}
#HooksConfigFile node
if ($sourceControlName -eq "WorkingFolder")
{
$xmlHooksConfigFileNode = $xmlISrcCLocationNode.AppendChild($xmlLinkedDatabases.CreateElement("HooksConfigFile"))
$xmlHooksConfigFileNode = $xmlHooksConfigFileNode.AppendChild($xmlLinkedDatabases.CreateTextNode($hooksPath))
#HooksFileInRepositoryFolder node
$xmlHooksFileInRepositoryFolderNode = $xmlISrcCLocationNode.AppendChild($xmlLinkedDatabases.CreateElement("HooksFileInRepositoryFolder"))
$xmlHooksFileInRepositoryFolderNode = $xmlHooksFileInRepositoryFolderNode.AppendChild($xmlLinkedDatabases.CreateTextNode("False"))
}
#IWorkspaceId node
$xmlIWorkspaceIdNode = $xmlValueNode.AppendChild($xmlLinkedDatabases.CreateElement("IWorkspaceId"))
$xmlIWorkspaceIdNode.SetAttribute("version", "1")
$xmlIWorkspaceIdNode.SetAttribute("type", "WorkspaceId")
#RootPath node
$xmlRootPathWFNode = $xmlIWorkspaceIdNode.AppendChild($xmlLinkedDatabases.CreateElement("RootPath"))
$xmlRootPathWFNode = $xmlRootPathWFNode.AppendChild($xmlLinkedDatabases.CreateTextNode($workingBasePath))
#SharedModel node
$xmlSharedModelNode = $xmlValueNode.AppendChild($xmlLinkedDatabases.CreateElement("SharedModel"))
$xmlSharedModelNode = $xmlSharedModelNode.AppendChild($xmlLinkedDatabases.CreateTextNode("False"))
#ScriptTransientId node
$xmlScriptTransientIdNode = $xmlValueNode.AppendChild($xmlLinkedDatabases.CreateElement("ScriptTransientId"))
$xmlScriptTransientIdNode.SetAttribute("version", "1")
$xmlScriptTransientIdNode.SetAttribute("type", "WorkspaceId")
#RootPath node
$xmlRootPathTRNode = $xmlScriptTransientIdNode.AppendChild($xmlLinkedDatabases.CreateElement("RootPath"))
$xmlRootPathTRNode = $xmlRootPathTRNode.AppendChild($xmlLinkedDatabases.CreateTextNode($transientPath))
$xmlLinkedDatabases.Save($xmlConfigurationsFilePath)
}
function RemoveAndSaveXmlConfiguration (
[string]$xmlConfigurationsFilePath = $(Throw 'xmlConfigurationsFilePath is required'),
[System.Xml.XmlElement]$nodeToRemove = $(Throw 'dbNode is required')
)
{
$xmlLinkedDatabases.LinkedDatabaseStore.LinkedDatabaseList.RemoveChild($nodeToRemove) | Out-Null
$xmlLinkedDatabases.Save($xmlConfigurationsFilePath)
}
function CreateDatabaseFromScript(
[string]$createDatabaseScript = $(Throw 'createDatabaseScript is required'),
[string]$serverName = $(Throw 'serverName is required'),
[string]$databasesPath = $(Throw 'databasesPath is required'),
[string]$databaseName = $(Throw 'databaseName is required')
)
{
if(!(Test-Path (Join-Path $databasesPath $databaseName)))
{
New-Item -ItemType Directory -Path (Join-Path $databasesPath $databaseName) | Out-Null
}
Invoke-Sqlcmd -inputfile $createDatabaseScript -serverinstance $serverName -Variable DatabaseFilesPath="$databasesPath", DatabaseName="$databaseName"
}
function DropDatabaseIfExists (
[string]$dropDatabaseScript = $(Throw 'dropDatabaseScript is required'),
[string]$databaseName = $(Throw 'databaseName is required'),
[string]$serverName = $(Throw 'serverName is required')
)
{
$databaseExists = Invoke-Sqlcmd -Query "DECLARE @v int; SELECT @v=DB_ID('$databaseName'); SELECT @v AS DBExists;" -serverinstance $serverName
if (![string]::IsNullOrEmpty($databaseExists.DBExists))
{
$dropScript = $dropDatabaseScript -replace "<DB>", $databaseName
Invoke-Sqlcmd -Query $dropScript -serverinstance $serverName
}
}
function RemoveWorkingBaseAndTransientFolders (
[string]$workingBase = $(Throw 'workingBase is required'),
[string]$transient = $(Throw 'transient is required')
)
{
if((Test-Path $workingBase))
{
Remove-Item $workingBase -Recurse
}
if((Test-Path $transient))
{
Remove-Item $transient -Recurse
}
}
function CreateWorkingBaseAndTransientFolders (
[string]$workingBase = $(Throw 'workingBase is required'),
[string]$transient = $(Throw 'transient is required'),
[string]$sourceControlName = $(Throw 'sourceControlName is required')
)
{
New-Item $workingBase -type Directory | Out-Null
New-Item $transient -type Directory | Out-Null
if ($sourceControlName -eq "git")
{
Set-Location $workingBase
git init | Out-Null
Set-Location $transient
git init | Out-Null
}
}
function GeneratingWorkingBaseAndTransient (
[string]$sourceFolder = $(Throw 'sourceFolder is required'),
[string]$targetWorkingBase = $(Throw 'targetWorkingBase is required'),
[string]$targetTransient = $(Throw 'targetTransient is required')
)
{
#working base is the copy of the database, at this time, an empty structure made by folders only
robocopy $sourceFolder $targetWorkingBase /e /xf *.* | Out-Null
Copy-Item $sourceFolder\RedGateDatabaseInfo.xml $targetWorkingBase | Out-Null #must be copied
Copy-Item $sourceFolder\RedGate.ssc $targetWorkingBase | Out-Null #must be copied
#transient folder is a copy of the latest version of the source control
Copy-Item $sourceFolder\* $targetTransient -Recurse | Out-Null
if (Test-Path $sourceFolder\Filter.scpf)
{
Copy-Item $sourceFolder\Filter.scpf $targetTransient -Force | Out-Null #must be refreshed
}
}
function GetLatestDatabaseStructure(
[string]$sourceFolder = $(Throw 'sourceFolder is required'),
[string]$serverName = $(Throw 'serverName is required'),
[string]$databaseName = $(Throw 'databaseName is required'),
[string]$SqlCompareFolder = $(Throw 'SqlCompareFolder is required'),
[string]$LicenseSerialNumber = $(Throw 'LicenseSerialNumber is required')
)
{
Set-Location $SqlCompareFolder
$command = "./sqlcompare"
$arguments = " /activateSerial: $LicenseSerialNumber"
$arguments = "/scripts1:$sourceFolder"
$arguments += " /server2:$serverName"
$arguments += " /database2:$databaseName"
$arguments += " /options:IgnoreCollations,IgnoreFillFactor,IgnoreWhiteSpace,IncludeDependencies,IgnoreUserProperties,IgnoreWithElementOrder,IgnoreDatabaseAndServerName,DecryptPost2kEncryptedObjects"
$arguments += " /Synchronize"
$arguments += " /include:Identical"
$arguments += " /Force"
$arguments += " /Quiet"
Invoke-Expression "$command $arguments" | Out-Null
}
function GetLatestDatabaseData(
[string]$sourceFolder = $(Throw 'sourceFolder is required'),
[string]$serverName = $(Throw 'serverName is required'),
[string]$databaseName = $(Throw 'databaseName is required'),
[string]$SqlDataCompareFolder = $(Throw 'SqlDataCompareFolder is required'),
[string]$LicenseSerialNumber = $(Throw 'LicenseSerialNumber is required')
)
{
Set-Location $SqlDataCompareFolder
$command = "./sqldatacompare"
$arguments = " /activateSerial: $LicenseSerialNumber"
$arguments = "/scripts1:$sourceFolder"
$arguments += " /server2:$serverName"
$arguments += " /database2:$databaseName"
$arguments += " /Synchronize"
$arguments += " /include:Identical"
$arguments += " /Force"
$arguments += " /Quiet"
Invoke-Expression "$command $arguments" | Out-Null
}
#endregion
Clear-Host
Write-Host "This script will create and link the development databases.." -ForegroundColor Cyan
Write-Host
#region GLOBAL SETTINGS
$CurrentFolder = Split-Path $MyInvocation.MyCommand.Definition -Parent
#source control in use
$sourceControlName = "git"
#set this to true if you want a step by step execution
$executeStepByStep = $false
#current barnch folder (you can change this if you move the file deeper in the path)
$BranchFolder = Split-Path $MyInvocation.MyCommand.Definition -Parent
#this is the point to get the Database branch folder (in order to create the workspace folder)
$databaseBranchFolder = $BranchFolder
$BranchSuffix = Split-Path $BranchFolder -Leaf
#product (brand) name, change it with your name (it cannot be blank)
$ProductName = "Foo"
#databases path, change it with your databases path
$databasesPath = "C:\Foo\Databases\"
#database scope settings (list of custom database "scope", scope is the "meaning" of the database and it needs the branch name for being a complete name)
$DB1Scope = 'DB1'
$DB2Scope = 'DB2'
$DB3Scope = 'DB3'
#database scripts (you can change the names of each script, and also the text within them)
$DB1CreationScript = '01 - Create database DB1.sql'
$DB2CreationScript = '02 - Create database DB2.sql'
$DB3CreationScript = '03 - Create database DB3.sql'
#endregion
#region WORKING VARIABLES
# list of needed database (specify the position = specify the sorting of scripts execution, if you need any)
$DB1Name = $DB1Scope+"_"+$BranchSuffix
$DB2Name = $DB2Scope+"_"+$BranchSuffix
$DB3Name = $DB3Scope+"_"+$BranchSuffix
$databases = (
($DB1Scope, $DB1Name, $DB1CreationScript, 1),
($DB2Scope, $DB2Name, $DB2CreationScript, 2),
($DB3Scope, $DB3Name, $DB3CreationScript, 3)
)
# RedGate - hard-coded to version 6, change it if you have another version.
$socPath = $env:LOCALAPPDATA + "\Red Gate\SQL Source Control 6\"
$SQLComparePath = Join-Path $CurrentFolder -ChildPath "Dependencies"
$SQLDataComparePath = Join-Path $CurrentFolder -ChildPath "Dependencies"
$SqlToolbeltLicenseSerialNumber = ""
$hooksPath = Join-Path $socPath "ReservedCommandLineHooks\$sourceControlName.xml"
$xmlConfigurationsFilePath = Join-Path $socPath LinkedDatabases.xml
# script sql template for DROP DATABASE (needed for dropping the database before recreating it)
$dropDatabaseScript = "EXEC msdb.dbo.sp_delete_database_backuphistory @database_name = N'<DB>'
GO
USE [master]
GO
ALTER DATABASE [<DB>] SET SINGLE_USER WITH ROLLBACK IMMEDIATE
GO
DROP DATABASE [<DB>]
GO"
[xml]$xmlLinkedDatabases = Get-Content ($xmlConfigurationsFilePath)
#endregion
#check whether the SSMS process is running (if you want to refresh the database status you need to restart SSMS)
if((get-process "Ssms" -ea SilentlyContinue) -ne $null){
Write-Host "Please close SQL Server Management Studio before executing this script." -ForegroundColor Red
exit
}
#region SERVER MANAGEMENT
$MachineName = $env:computername
$FullServerName = Read-Host "Server name\Instance name (empty to auto-discover)"
Write-Host
if ($FullServerName -eq "")
{
Write-Host "Gathering instance data.." -ForegroundColor Yellow
# default instance name (the first in the registry key)
$InstanceName = (get-itemproperty 'HKLM:\SOFTWARE\Microsoft\Microsoft SQL Server').InstalledInstances | Select-Object -first 1
$serverName = $MachineName + "\"+ $InstanceName
} else
{
$serverName = $FullServerName
}
Write-Host "Instance name set to '$serverName'" -ForegroundColor Gray
Write-Host
#endregion
#region MENU
Write-Host "Choose an option:" -ForegroundColor Yellow
Write-Host "0 - All databases" -ForegroundColor White
foreach ($database in $databases)
{
Write-Host $database[3] '-' $database[1] -ForegroundColor White
}
Do
{
$selectedOption = Read-host
}
while ($selectedOption -ne $null -and $selectedOption -notin 0..6)
#endregion
#region LINKING DATABASES AND SCRIPT EXECUTION
#check for base databases path
Write-Host "Creating base databases folders... " -ForegroundColor Yellow
if(!(Test-Path $databasesPath))
{
New-Item -ItemType Directory -Path $databasesPath | Out-Null
Write-Host "Folder '$databasesPath' created successfully." -ForegroundColor Gray
}
else
{
Write-Host "Folder '$databasesPath' already exists. No user action required." -ForegroundColor Gray
}
Write-Host "Base databases path set to '$databasesPath'." -ForegroundColor Gray
Write-Host
if ($selectedOption -eq 0)
{
Write-Host "Linking all databases" -ForegroundColor Yellow
}
else
{
Write-Host "Linking database"$databases[$selectedOption - 1][1] -ForegroundColor Yellow
}
#configuration file (RedGate) xml node to manage
#$linkedDatabasesXmlNode = $xmlLinkedDatabases.LinkedDatabaseStore.LinkedDatabaseList.value
#loop setting by database (list of databases on the top, hard coded)
foreach ($database in $databases)
{
$databaseScope = $database[0] #is the macro database area
$databaseName = $database[1] #name of the database
$databaseOption = $database[3] #option related to the database in the "start menu"
if ($databaseOption -eq $selectedOption -or $selectedOption -eq 0)
{
$createDatabaseScript = Join-Path $CurrentFolder $database[2] #path of the script to execute in order to create the database
#$databaseFilesPath = Join-Path $databasesPath $databaseName #path of the target database
$databaseWorkSpaceFolder = Join-Path $databaseBranchFolder $ProductName'.'$databaseScope #path of the workspace which contains the database
Write-Host "Managing database: '$databaseName'" -ForegroundColor White
#unlinking the databases from the source control working folder
#delete info from the RedGate Source Control xml configuration file (if exists)
$dbNode = $xmlLinkedDatabases.LinkedDatabaseStore.LinkedDatabaseList.value | Where-Object {$_.DatabaseId.DatabaseName -eq $databaseName}
if ($dbNode)
{
if ($executeStepByStep)
{
write-host "remove workingbase and transient from xml" -ForegroundColor Yellow -BackgroundColor Red
read-host
}
#removing node on xml config file
Write-Host " Removing nodes from RedGate XML config file for '$databaseName'... " -ForegroundColor DarkGray -NoNewline
RemoveAndSaveXmlConfiguration -xmlConfigurationsFilePath $xmlConfigurationsFilePath -nodeToRemove $dbNode
Write-Host "Done!" -ForegroundColor Gray
if ($executeStepByStep)
{
write-host "remove folders" -ForegroundColor Yellow -BackgroundColor Red
read-host
}
#remove working bases and transient folders from the filesystem
Write-Host " Removing the working base and the transient settings from the xml configuration file... " -ForegroundColor DarkGray -NoNewline
RemoveWorkingBaseAndTransientFolders -workingBase $dbNode.IWorkspaceId.RootPath -transient $dbNode.ScriptTransientId.RootPath
Write-Host "Done!" -ForegroundColor Gray
}
if ($executeStepByStep)
{
write-host "drop and create the db" -ForegroundColor Yellow -BackgroundColor Red
read-host
}
#drop and create the database
Write-Host " Dropping '$databaseName' database if exists, then re-create it with '$createDatabaseScript' setup script... " -ForegroundColor DarkGray -NoNewline
DropDatabaseIfExists -dropDatabaseScript $dropDatabaseScript -databaseName $databaseName -serverName $serverName
CreateDatabaseFromScript -serverName $serverName -databaseScope $databaseScope -databasesPath $databasesPath -databaseName $databaseName -createDatabaseScript $createDatabaseScript
Write-Host "Done!" -ForegroundColor Gray
if ($executeStepByStep)
{
write-host "create workingbase and transient on disk" -ForegroundColor Yellow -BackgroundColor Red
read-host
}
# create working bases and transient folders
$randomWorkingBaseFileName = [System.IO.Path]::GetRandomFileName()
$randomWorkingBaseDirectoryName = Join-Path (Join-Path $socPath WorkingBases) $randomWorkingBaseFileName
$randomTransientFileName = [System.IO.Path]::GetRandomFileName()
$randomTransientDirectoryName = Join-Path (Join-Path $socPath Transients) $randomTransientFileName
Write-Host " Creating the working base '$randomWorkingBaseFileName' and the transient '$randomTransientFileName'... " -ForegroundColor DarkGray -NoNewline
CreateWorkingBaseAndTransientFolders -workingBase $randomWorkingBaseDirectoryName -transient $randomTransientDirectoryName -sourceControlName $sourceControlName
Write-Host "Done!" -ForegroundColor Gray
if ($executeStepByStep)
{
write-host "create workingbases and transients on xml" -ForegroundColor Yellow -BackgroundColor Red
read-host
}
# create the info in the RedGate Source Control xml configuration file
Write-Host " Creating nodes for the RedGate XML config file for '$databaseName'... " -ForegroundColor DarkGray -NoNewline
AddAndSaveXmlConfiguration -serverName $serverName -databaseName $databaseName -workspacePath $databaseWorkSpaceFolder -hooksPath $hooksPath -workingBasePath $randomWorkingBaseDirectoryName -transientPath $randomTransientDirectoryName -xmlLinkedDatabases $xmlLinkedDatabases -xmlConfigurationsFilePath $xmlConfigurationsFilePath -sourceControlName $sourceControlName
Write-Host "Done!" -ForegroundColor Gray
if ($executeStepByStep)
{
write-host "copying working bases" -ForegroundColor Yellow -BackgroundColor Red
read-host
}
# copy the content of the working folder into the transient and working bases
GeneratingWorkingBaseAndTransient -sourceFolder $databaseWorkSpaceFolder -targetWorkingBase $randomWorkingBaseDirectoryName -targetTransient $randomTransientDirectoryName
#getting latest version of structures
Write-Host " Getting latest versions of '$databaseName'... " -ForegroundColor DarkGray
Write-Host " Comparing structures..." -ForegroundColor DarkGray -NoNewline
GetLatestDatabaseStructure -sourceFolder $databaseWorkSpaceFolder -serverName $serverName -databaseName $databaseName -SqlCompareFolder "$SQLComparePath" -LicenseSerialNumber $SqlToolbeltLicenseSerialNumber
Write-Host "Done!" -ForegroundColor Gray
if ($executeStepByStep)
{
write-host "getting latest versions of data" -ForegroundColor Yellow -BackgroundColor Red
read-host
}
#getting latest version of data
Write-Host " Comparing data..." -ForegroundColor DarkGray -NoNewline
GetLatestDatabaseData -sourceFolder $databaseWorkSpaceFolder -serverName $serverName -databaseName $databaseName -SqlDataCompareFolder "$SQLDataComparePath" -LicenseSerialNumber $SqlToolbeltLicenseSerialNumber
Write-Host "Done!" -ForegroundColor Gray
Write-Host "New environment for database '$databaseName' ready!" -ForegroundColor White
Write-Host
if ($executeStepByStep)
{
write-host "Next database" -ForegroundColor Yellow -BackgroundColor Green
read-host
}
#>
}
}
Write-Host "Environment for databases completed successfully!" -ForegroundColor Yellow
Write-Host
Write-Host "Starting SQL Server Management Studio..." -ForegroundColor Cyan
start-process ssms -verb runAs
#endregion