Skip to content

Commit 53a4a65

Browse files
authored
Add commands for SQL Server database management (#2148)
1 parent 2c7ba54 commit 53a4a65

18 files changed

+2564
-0
lines changed

CHANGELOG.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,15 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
4242
- Added `Get-SqlDscAgentAlert`, `New-SqlDscAgentAlert`,
4343
`Set-SqlDscAgentAlert`, `Remove-SqlDscAgentAlert`, and `Test-SqlDscAgentAlert`
4444
to manage SQL Agent alerts on a Database Engine instance.
45+
- Added new public commands for database management:
46+
- `Get-SqlDscDatabase` - Get databases from a SQL Server Database Engine instance
47+
- `New-SqlDscDatabase` - Create a new database with specified properties
48+
- `Set-SqlDscDatabase` - Modify properties of an existing database
49+
- `Remove-SqlDscDatabase` - Remove a database from SQL Server instance
50+
- `Test-SqlDscDatabase` - Test if a database is in the desired state
51+
- All commands support pipeline input with ServerObject and follow established patterns
52+
- Database objects can also be used as pipeline input for Set and Remove operations
53+
- Commands include comprehensive validation, localization, and ShouldProcess support
4554

4655
### Changed
4756

azure-pipelines.yml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -301,6 +301,11 @@ stages:
301301
'tests/Integration/Commands/Get-SqlDscRole.Integration.Tests.ps1'
302302
'tests/Integration/Commands/Remove-SqlDscRole.Integration.Tests.ps1'
303303
'tests/Integration/Commands/Remove-SqlDscLogin.Integration.Tests.ps1'
304+
'tests/Integration/Commands/Get-SqlDscDatabase.Integration.Tests.ps1'
305+
'tests/Integration/Commands/New-SqlDscDatabase.Integration.Tests.ps1'
306+
'tests/Integration/Commands/Set-SqlDscDatabase.Integration.Tests.ps1'
307+
'tests/Integration/Commands/Test-SqlDscDatabase.Integration.Tests.ps1'
308+
'tests/Integration/Commands/Remove-SqlDscDatabase.Integration.Tests.ps1'
304309
'tests/Integration/Commands/Get-SqlDscAgentAlert.Integration.Tests.ps1'
305310
'tests/Integration/Commands/New-SqlDscAgentAlert.Integration.Tests.ps1'
306311
'tests/Integration/Commands/Set-SqlDscAgentAlert.Integration.Tests.ps1'
Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
<#
2+
.SYNOPSIS
3+
Get databases from a SQL Server Database Engine instance.
4+
5+
.DESCRIPTION
6+
This command gets one or more databases from a SQL Server Database Engine instance.
7+
If no name is specified, all databases are returned.
8+
9+
.PARAMETER ServerObject
10+
Specifies current server connection object.
11+
12+
.PARAMETER Name
13+
Specifies the name of the database to get. If not specified, all
14+
databases are returned.
15+
16+
.PARAMETER Refresh
17+
Specifies that the **ServerObject**'s databases should be refreshed before
18+
trying to get the database object. This is helpful when databases could have been
19+
modified outside of the **ServerObject**, for example through T-SQL. But
20+
on instances with a large amount of databases it might be better to make
21+
sure the **ServerObject** is recent enough.
22+
23+
.EXAMPLE
24+
$serverObject = Connect-SqlDscDatabaseEngine -InstanceName 'MyInstance'
25+
$serverObject | Get-SqlDscDatabase
26+
27+
Get all databases from the instance.
28+
29+
.EXAMPLE
30+
$serverObject = Connect-SqlDscDatabaseEngine -InstanceName 'MyInstance'
31+
$serverObject | Get-SqlDscDatabase -Name 'MyDatabase'
32+
33+
Get the database named **MyDatabase**.
34+
35+
.OUTPUTS
36+
`[Microsoft.SqlServer.Management.Smo.Database[]]`
37+
#>
38+
function Get-SqlDscDatabase
39+
{
40+
[System.Diagnostics.CodeAnalysis.SuppressMessageAttribute('UseSyntacticallyCorrectExamples', '', Justification = 'Because the rule does not yet support parsing the code when a parameter type is not available. The ScriptAnalyzer rule UseSyntacticallyCorrectExamples will always error in the editor due to https://github.com/indented-automation/Indented.ScriptAnalyzerRules/issues/8.')]
41+
[OutputType([Microsoft.SqlServer.Management.Smo.Database[]])]
42+
[CmdletBinding()]
43+
param
44+
(
45+
[Parameter(Mandatory = $true, ValueFromPipeline = $true)]
46+
[Microsoft.SqlServer.Management.Smo.Server]
47+
$ServerObject,
48+
49+
[Parameter()]
50+
[System.String]
51+
$Name,
52+
53+
[Parameter()]
54+
[System.Management.Automation.SwitchParameter]
55+
$Refresh
56+
)
57+
58+
process
59+
{
60+
if ($Refresh.IsPresent)
61+
{
62+
# Refresh the server object's databases collection
63+
$ServerObject.Databases.Refresh()
64+
}
65+
66+
Write-Verbose -Message ($script:localizedData.Database_Get -f $ServerObject.InstanceName)
67+
68+
$databaseObject = @()
69+
70+
if ($PSBoundParameters.ContainsKey('Name'))
71+
{
72+
$databaseObject = $ServerObject.Databases[$Name]
73+
74+
if (-not $databaseObject)
75+
{
76+
Write-Verbose -Message ($script:localizedData.Database_NotFound -f $Name)
77+
78+
$missingDatabaseMessage = $script:localizedData.Database_NotFound -f $Name
79+
80+
$writeErrorParameters = @{
81+
Message = $missingDatabaseMessage
82+
Category = 'ObjectNotFound'
83+
ErrorId = 'GSDD0001' # cspell: disable-line
84+
TargetObject = $Name
85+
}
86+
87+
Write-Error @writeErrorParameters
88+
}
89+
else
90+
{
91+
Write-Verbose -Message ($script:localizedData.Database_Found -f $Name)
92+
}
93+
}
94+
else
95+
{
96+
Write-Verbose -Message ($script:localizedData.Database_GetAll)
97+
98+
$databaseObject = $ServerObject.Databases
99+
}
100+
101+
return [Microsoft.SqlServer.Management.Smo.Database[]] $databaseObject
102+
}
103+
}
Lines changed: 206 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,206 @@
1+
<#
2+
.SYNOPSIS
3+
Creates a new database in a SQL Server Database Engine instance.
4+
5+
.DESCRIPTION
6+
This command creates a new database in a SQL Server Database Engine instance.
7+
8+
.PARAMETER ServerObject
9+
Specifies current server connection object.
10+
11+
.PARAMETER Name
12+
Specifies the name of the database to be created.
13+
14+
.PARAMETER Collation
15+
The name of the SQL collation to use for the new database.
16+
Default value is server collation.
17+
18+
.PARAMETER CompatibilityLevel
19+
The version of the SQL compatibility level to use for the new database.
20+
Default value is server version.
21+
22+
.PARAMETER RecoveryModel
23+
The recovery model to be used for the new database.
24+
Default value is Full.
25+
26+
.PARAMETER OwnerName
27+
Specifies the name of the login that should be the owner of the database.
28+
29+
.PARAMETER Force
30+
Specifies that the database should be created without any confirmation.
31+
32+
.PARAMETER Refresh
33+
Specifies that the **ServerObject**'s databases should be refreshed before
34+
creating the database object. This is helpful when databases could have been
35+
modified outside of the **ServerObject**, for example through T-SQL. But
36+
on instances with a large amount of databases it might be better to make
37+
sure the **ServerObject** is recent enough.
38+
39+
.EXAMPLE
40+
$serverObject = Connect-SqlDscDatabaseEngine -InstanceName 'MyInstance'
41+
$serverObject | New-SqlDscDatabase -Name 'MyDatabase'
42+
43+
Creates a new database named **MyDatabase**.
44+
45+
.EXAMPLE
46+
$serverObject = Connect-SqlDscDatabaseEngine -InstanceName 'MyInstance'
47+
$serverObject | New-SqlDscDatabase -Name 'MyDatabase' -Collation 'SQL_Latin1_General_Pref_CP850_CI_AS' -RecoveryModel 'Simple' -Force
48+
49+
Creates a new database named **MyDatabase** with the specified collation and recovery model
50+
without prompting for confirmation.
51+
52+
.OUTPUTS
53+
`[Microsoft.SqlServer.Management.Smo.Database]`
54+
#>
55+
function New-SqlDscDatabase
56+
{
57+
[System.Diagnostics.CodeAnalysis.SuppressMessageAttribute('UseSyntacticallyCorrectExamples', '', Justification = 'Because the rule does not yet support parsing the code when a parameter type is not available. The ScriptAnalyzer rule UseSyntacticallyCorrectExamples will always error in the editor due to https://github.com/indented-automation/Indented.ScriptAnalyzerRules/issues/8.')]
58+
[OutputType([Microsoft.SqlServer.Management.Smo.Database])]
59+
[CmdletBinding(SupportsShouldProcess = $true, ConfirmImpact = 'Medium')]
60+
param
61+
(
62+
[Parameter(Mandatory = $true, ValueFromPipeline = $true)]
63+
[Microsoft.SqlServer.Management.Smo.Server]
64+
$ServerObject,
65+
66+
[Parameter(Mandatory = $true)]
67+
[ValidateNotNullOrEmpty()]
68+
[System.String]
69+
$Name,
70+
71+
[Parameter()]
72+
[ValidateNotNullOrEmpty()]
73+
[System.String]
74+
$Collation,
75+
76+
[Parameter()]
77+
[ValidateSet('Version80', 'Version90', 'Version100', 'Version110', 'Version120', 'Version130', 'Version140', 'Version150', 'Version160')]
78+
[System.String]
79+
$CompatibilityLevel,
80+
81+
[Parameter()]
82+
[ValidateSet('Simple', 'Full', 'BulkLogged')]
83+
[System.String]
84+
$RecoveryModel,
85+
86+
[Parameter()]
87+
[System.String]
88+
$OwnerName,
89+
90+
[Parameter()]
91+
[System.Management.Automation.SwitchParameter]
92+
$Force,
93+
94+
[Parameter()]
95+
[System.Management.Automation.SwitchParameter]
96+
$Refresh
97+
)
98+
99+
begin
100+
{
101+
if ($Force.IsPresent -and -not $Confirm)
102+
{
103+
$ConfirmPreference = 'None'
104+
}
105+
}
106+
107+
process
108+
{
109+
if ($Refresh.IsPresent)
110+
{
111+
# Refresh the server object's databases collection
112+
$ServerObject.Databases.Refresh()
113+
}
114+
115+
Write-Verbose -Message ($script:localizedData.Database_Create -f $Name, $ServerObject.InstanceName)
116+
117+
# Check if the database already exists
118+
if ($ServerObject.Databases[$Name])
119+
{
120+
$errorMessage = $script:localizedData.Database_AlreadyExists -f $Name, $ServerObject.InstanceName
121+
New-InvalidOperationException -Message $errorMessage
122+
}
123+
124+
# Validate compatibility level if specified
125+
if ($PSBoundParameters.ContainsKey('CompatibilityLevel'))
126+
{
127+
$supportedCompatibilityLevels = @{
128+
8 = @('Version80')
129+
9 = @('Version80', 'Version90')
130+
10 = @('Version80', 'Version90', 'Version100')
131+
11 = @('Version90', 'Version100', 'Version110')
132+
12 = @('Version100', 'Version110', 'Version120')
133+
13 = @('Version100', 'Version110', 'Version120', 'Version130')
134+
14 = @('Version100', 'Version110', 'Version120', 'Version130', 'Version140')
135+
15 = @('Version100', 'Version110', 'Version120', 'Version130', 'Version140', 'Version150')
136+
16 = @('Version100', 'Version110', 'Version120', 'Version130', 'Version140', 'Version150', 'Version160')
137+
}
138+
139+
if ($CompatibilityLevel -notin $supportedCompatibilityLevels.$($ServerObject.VersionMajor))
140+
{
141+
$errorMessage = $script:localizedData.Database_InvalidCompatibilityLevel -f $CompatibilityLevel, $ServerObject.InstanceName
142+
New-InvalidArgumentException -ArgumentName 'CompatibilityLevel' -Message $errorMessage
143+
}
144+
}
145+
146+
# Validate collation if specified
147+
if ($PSBoundParameters.ContainsKey('Collation'))
148+
{
149+
if ($Collation -notin $ServerObject.EnumCollations().Name)
150+
{
151+
$errorMessage = $script:localizedData.Database_InvalidCollation -f $Collation, $ServerObject.InstanceName
152+
New-InvalidArgumentException -ArgumentName 'Collation' -Message $errorMessage
153+
}
154+
}
155+
156+
$verboseDescriptionMessage = $script:localizedData.Database_Create_ShouldProcessVerboseDescription -f $Name, $ServerObject.InstanceName
157+
$verboseWarningMessage = $script:localizedData.Database_Create_ShouldProcessVerboseWarning -f $Name
158+
$captionMessage = $script:localizedData.Database_Create_ShouldProcessCaption
159+
160+
if ($PSCmdlet.ShouldProcess($verboseDescriptionMessage, $verboseWarningMessage, $captionMessage))
161+
{
162+
try
163+
{
164+
$sqlDatabaseObjectToCreate = New-Object -TypeName 'Microsoft.SqlServer.Management.Smo.Database' -ArgumentList $ServerObject, $Name
165+
166+
if ($PSBoundParameters.ContainsKey('RecoveryModel'))
167+
{
168+
$sqlDatabaseObjectToCreate.RecoveryModel = $RecoveryModel
169+
}
170+
171+
if ($PSBoundParameters.ContainsKey('Collation'))
172+
{
173+
$sqlDatabaseObjectToCreate.Collation = $Collation
174+
}
175+
176+
if ($PSBoundParameters.ContainsKey('CompatibilityLevel'))
177+
{
178+
$sqlDatabaseObjectToCreate.CompatibilityLevel = $CompatibilityLevel
179+
}
180+
181+
Write-Verbose -Message ($script:localizedData.Database_Creating -f $Name)
182+
183+
$sqlDatabaseObjectToCreate.Create()
184+
185+
<#
186+
This must be run after the object is created because
187+
the owner property is read-only and the method cannot
188+
be call until the object has been created.
189+
#>
190+
if ($PSBoundParameters.ContainsKey('OwnerName'))
191+
{
192+
$sqlDatabaseObjectToCreate.SetOwner($OwnerName)
193+
}
194+
195+
Write-Verbose -Message ($script:localizedData.Database_Created -f $Name)
196+
197+
return $sqlDatabaseObjectToCreate
198+
}
199+
catch
200+
{
201+
$errorMessage = $script:localizedData.Database_CreateFailed -f $Name, $ServerObject.InstanceName
202+
New-InvalidOperationException -Message $errorMessage -ErrorRecord $_
203+
}
204+
}
205+
}
206+
}

0 commit comments

Comments
 (0)