Skip to content

Commit 8313dbe

Browse files
authored
Set-SqlDscDatabaseDefault: Command for managing database defaults (#2189)
1 parent 0150527 commit 8313dbe

12 files changed

+771
-44
lines changed

.github/copilot-instructions.md

Lines changed: 1 addition & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1,35 +1,2 @@
1-
# AI Instructions
2-
3-
This file provides AI agent guidance for the project. Each instruction file below
4-
targets specific file glob patterns and use cases.
5-
6-
## Build & Test Workflow
7-
- Run in PowerShell, from repository root
8-
- Build before running tests: `.\build.ps1 -Tasks build`
9-
- Always run tests in new PowerShell session: `Invoke-Pester -Path @({test paths}) -Output Detailed`
10-
11-
## Instructions Overview
12-
13-
The guidelines always take priority over existing code patterns in project.
14-
1+
# Requirements
152
- SqlServerDsc-specific guidelines override general project guidelines
16-
- Follow PowerShell style guidelines
17-
- Maintain localization requirements across all source files
18-
- Follow test patterns strictly for maintainability
19-
20-
## Core Project Guidelines
21-
22-
- Follow SqlServerDsc project specific guidelines: [./instructions/SqlServerDsc-guidelines.instructions.md](./instructions/SqlServerDsc-guidelines.instructions.md)
23-
- Always follow PowerShell code style guidelines: [./instructions/dsc-community-style-guidelines-powershell.instructions.md](./instructions/dsc-community-style-guidelines-powershell.instructions.md)
24-
- Follow Project-level guidelines: [./instructions/dsc-community-style-guidelines.instructions.md](./instructions/dsc-community-style-guidelines.instructions.md)
25-
- Follow localization requirements: [./instructions/dsc-community-style-guidelines-localization.instructions.md](./instructions/dsc-community-style-guidelines-localization.instructions.md)
26-
- Always add Unit testing according to: [./instructions/dsc-community-style-guidelines-unit-tests.instructions.md](./instructions/dsc-community-style-guidelines-unit-tests.instructions.md)
27-
- Always add Integration testing according to: [./instructions/dsc-community-style-guidelines-integration-tests.instructions.md](./instructions/dsc-community-style-guidelines-integration-tests.instructions.md)
28-
- Follow Markdown formatting requirements: [./instructions/dsc-community-style-guidelines-markdown.instructions.md](./instructions/dsc-community-style-guidelines-markdown.instructions.md)
29-
- Always update CHANGELOG.md: [./instructions/dsc-community-style-guidelines-changelog.instructions.md](./instructions/dsc-community-style-guidelines-changelog.instructions.md)
30-
31-
## Desired State Configuration (DSC) Resource Guidelines
32-
33-
New DSC resources should always be created as class-based resources.
34-
35-
- Follow class-based resources guidelines: [./instructions/dsc-community-style-guidelines-class-resource.instructions.md](./instructions/dsc-community-style-guidelines-class-resource.instructions.md)

.github/instructions/dsc-community-style-guidelines-class-resource.instructions.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -86,9 +86,9 @@ Add to .DESCRIPTION section:
8686
- `## Requirements`: List minimum requirements
8787
- `## Known issues`: Critical issues + pattern: `All issues are not listed here, see [all open issues](https://github.com/{owner}/{repo}/issues?q=is%3Aissue+is%3Aopen+in%3Atitle+{ResourceName}).`
8888

89-
## Error Handling
89+
## Error Handling for classes
9090
- Use `try/catch` blocks to handle exceptions
91-
- Do not use `throw` for terminating errors, use `New-*Exception` commands:
91+
- Do not use `throw` for terminating errors, use `New-*Exception` commands (never for functions):
9292
- [`New‑InvalidDataException`](https://github.com/dsccommunity/DscResource.Common/wiki/New%E2%80%91InvalidDataException)
9393
- [`New-ArgumentException`](https://github.com/dsccommunity/DscResource.Common/wiki/New%E2%80%91ArgumentException)
9494
- [`New-InvalidOperationException`](https://github.com/dsccommunity/DscResource.Common/wiki/New%E2%80%91InvalidOperationException)

.github/instructions/dsc-community-style-guidelines-mof-resources.instructions.md

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,10 +28,9 @@ applyTo: "source/DSCResources/**/*.psm1"
2828
- Use localized strings for all messages (Write-Verbose, Write-Error, etc.)
2929
- Import localized strings using `Get-LocalizedData` at module top
3030

31-
## Error Handling
32-
- Do not use `throw` for terminating errors
31+
## Error Handling for MOF-based resources
3332
- Use `try/catch` blocks to handle exceptions
34-
- Throw localized exceptions using the appropriate `New-*Exception` cmdlet:
33+
- Do not use `throw` for terminating errors, use `New-*Exception` commands (never for functions):
3534
- [`New‑InvalidDataException`](https://github.com/dsccommunity/DscResource.Common/wiki/New%E2%80%91InvalidDataException)
3635
- [`New-ArgumentException`](https://github.com/dsccommunity/DscResource.Common/wiki/New%E2%80%91ArgumentException)
3736
- [`New-InvalidOperationException`](https://github.com/dsccommunity/DscResource.Common/wiki/New%E2%80%91InvalidOperationException)

.github/instructions/dsc-community-style-guidelines-powershell.instructions.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,7 @@ applyTo: "**/*.ps?(m|d)1"
7979
- For state-changing functions, use `SupportsShouldProcess`
8080
- Place ShouldProcess check immediately before each state-change
8181
- `$PSCmdlet.ShouldProcess` must use required pattern
82+
- Inside `$PSCmdlet.ShouldProcess`-block, avoid using `Write-Verbose`
8283
- Never use backtick as line continuation in production code.
8384
- Set `$ErrorActionPreference = 'Stop'` before commands using `-ErrorAction 'Stop'`; restore after
8485

@@ -89,7 +90,7 @@ applyTo: "**/*.ps?(m|d)1"
8990
- Use `Write-Verbose` for: High-level execution flow only; User-actionable information
9091
- Use `Write-Information` for: User-facing status updates; Important operational messages; Non-error state changes
9192
- Use `Write-Warning` for: Non-fatal issues requiring attention; Deprecated functionality usage; Configuration problems that don't block execution
92-
- Use `$PSCmdlet.ThrowTerminatingError()` for terminating errors (except for classes), use relevant error category
93+
- Use `$PSCmdlet.ThrowTerminatingError()` for terminating errors (except for classes), use relevant error category, in try-catch include exception
9394
- Use `Write-Error` for non-terminating errors, use relevant error category
9495

9596
## ShouldProcess Required Pattern

.github/instructions/dsc-community-style-guidelines.instructions.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,10 +22,12 @@ applyTo: "**"
2222
- Integration tests: `tests/Integration/Commands/{CommandName}.Integration.Tests.ps1`
2323

2424
## Requirements
25-
- Follow guidelines over existing code patterns
25+
- Follow instructions over existing code patterns
26+
- Follow PowerShell style and test guideline instructions strictly
2627
- Always update CHANGELOG.md Unreleased section
2728
- Localize all strings using string keys; remove any orphaned string keys
2829
- Check DscResource.Common before creating private functions
2930
- Separate reusable logic into private functions
31+
- DSC resources should always be created as class-based resources
3032
- Add unit tests for all commands/functions/resources
3133
- Add integration tests for all public commands and resources

.vscode/settings.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,8 @@
9090
"SOURCEBRANCH",
9191
"SOURCEBRANCHNAME",
9292
"setvariable",
93-
"RAISERROR"
93+
"RAISERROR",
94+
"filegroup"
9495
],
9596
"cSpell.ignorePaths": [
9697
".git"

CHANGELOG.md

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
3535

3636
- Added setup workflow for GitHub Copilot.
3737
- Switch the workflow to use Linux.
38-
- Attempt to unshallow the Copilot branch
38+
- `Set-SqlDscDatabaseDefault`
39+
- Added new command to set default objects of a database in a SQL Server
40+
Database Engine instance (issue [#2178](https://github.com/dsccommunity/SqlServerDsc/issues/2178)).
41+
- The command can set the default filegroup, default FILESTREAM filegroup,
42+
and default Full-Text catalog using SMO methods SetDefaultFileGroup,
43+
SetDefaultFileStreamFileGroup, and SetDefaultFullTextCatalog.
3944
- `SqlAgentAlert`
4045
- Added new DSC resource to manage SQL Server Agent alerts.
4146
- Improved AI instructions.
@@ -82,7 +87,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
8287
- `Set-SqlDscDatabase` - Modify properties of an existing database
8388
- `Remove-SqlDscDatabase` - Remove a database from SQL Server instance
8489
- `Test-SqlDscDatabase` - Test if a database is in the desired state
85-
- All commands support pipeline input with ServerObject and follow established patterns
90+
- All commands support pipeline input with ServerObject and follow established
91+
patterns
8692
- Database objects can also be used as pipeline input for Set and Remove operations
8793
- Commands include comprehensive validation, localization, and ShouldProcess support
8894

Lines changed: 213 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,213 @@
1+
<#
2+
.SYNOPSIS
3+
Sets default objects of a database in a SQL Server Database Engine instance.
4+
5+
.DESCRIPTION
6+
This command sets default objects of a database in a SQL Server Database Engine instance.
7+
It can set the default filegroup, default FILESTREAM filegroup, and default Full-Text catalog
8+
using SMO methods.
9+
10+
.PARAMETER ServerObject
11+
Specifies current server connection object.
12+
13+
.PARAMETER DatabaseObject
14+
Specifies a database object to modify.
15+
16+
.PARAMETER Name
17+
Specifies the name of the database to be modified.
18+
19+
.PARAMETER DefaultFileGroup
20+
Sets the default filegroup for the database. The filegroup must exist in the database.
21+
22+
.PARAMETER DefaultFileStreamFileGroup
23+
Sets the default FILESTREAM filegroup for the database. The filegroup must exist in the database.
24+
25+
.PARAMETER DefaultFullTextCatalog
26+
Sets the default Full-Text catalog for the database. The catalog must exist in the database.
27+
28+
.PARAMETER Force
29+
Specifies that the database defaults should be modified without any confirmation.
30+
31+
.PARAMETER Refresh
32+
Specifies that the **ServerObject**'s databases should be refreshed before
33+
modifying the database object. This is helpful when databases could have been
34+
modified outside of the **ServerObject**, for example through T-SQL. But
35+
on instances with a large amount of databases it might be better to make
36+
sure the **ServerObject** is recent enough, or pass in **DatabaseObject**.
37+
38+
.PARAMETER PassThru
39+
Specifies that the database object should be returned after modification.
40+
41+
.EXAMPLE
42+
$serverObject = Connect-SqlDscDatabaseEngine -InstanceName 'MyInstance'
43+
$databaseObject = $serverObject | Get-SqlDscDatabase -Name 'MyDatabase'
44+
$databaseObject | Set-SqlDscDatabaseDefault -DefaultFileGroup 'MyFileGroup'
45+
46+
Sets the default filegroup of the database named **MyDatabase** to **MyFileGroup**.
47+
48+
.EXAMPLE
49+
$serverObject = Connect-SqlDscDatabaseEngine -InstanceName 'MyInstance'
50+
$serverObject | Set-SqlDscDatabaseDefault -Name 'MyDatabase' -DefaultFullTextCatalog 'MyCatalog' -Force
51+
52+
Sets the default Full-Text catalog of the database named **MyDatabase** to **MyCatalog** without prompting for confirmation.
53+
54+
.EXAMPLE
55+
$serverObject = Connect-SqlDscDatabaseEngine -InstanceName 'MyInstance'
56+
$databaseObject = $serverObject | Get-SqlDscDatabase -Name 'MyDatabase'
57+
$databaseObject | Set-SqlDscDatabaseDefault -DefaultFileGroup 'DataFileGroup' -DefaultFileStreamFileGroup 'FileStreamFileGroup' -DefaultFullTextCatalog 'FTCatalog'
58+
59+
Sets multiple default objects for the database named **MyDatabase**.
60+
61+
.INPUTS
62+
Microsoft.SqlServer.Management.Smo.Server
63+
Server object accepted from the pipeline (ServerObject parameter set).
64+
65+
Microsoft.SqlServer.Management.Smo.Database
66+
Database object accepted from the pipeline (DatabaseObject parameter set).
67+
68+
.OUTPUTS
69+
None. But when **PassThru** is specified the output is `[Microsoft.SqlServer.Management.Smo.Database]`.
70+
#>
71+
function Set-SqlDscDatabaseDefault
72+
{
73+
[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.')]
74+
[OutputType([Microsoft.SqlServer.Management.Smo.Database])]
75+
[CmdletBinding(SupportsShouldProcess = $true, ConfirmImpact = 'Medium')]
76+
param
77+
(
78+
[Parameter(ParameterSetName = 'ServerObject', Mandatory = $true, ValueFromPipeline = $true)]
79+
[Microsoft.SqlServer.Management.Smo.Server]
80+
$ServerObject,
81+
82+
[Parameter(ParameterSetName = 'DatabaseObject', Mandatory = $true, ValueFromPipeline = $true)]
83+
[Microsoft.SqlServer.Management.Smo.Database]
84+
$DatabaseObject,
85+
86+
[Parameter(ParameterSetName = 'ServerObject', Mandatory = $true)]
87+
[ValidateNotNullOrEmpty()]
88+
[System.String]
89+
$Name,
90+
91+
[Parameter()]
92+
[ValidateNotNullOrEmpty()]
93+
[System.String]
94+
$DefaultFileGroup,
95+
96+
[Parameter()]
97+
[ValidateNotNullOrEmpty()]
98+
[System.String]
99+
$DefaultFileStreamFileGroup,
100+
101+
[Parameter()]
102+
[ValidateNotNullOrEmpty()]
103+
[System.String]
104+
$DefaultFullTextCatalog,
105+
106+
[Parameter()]
107+
[System.Management.Automation.SwitchParameter]
108+
$Force,
109+
110+
[Parameter(ParameterSetName = 'ServerObject')]
111+
[System.Management.Automation.SwitchParameter]
112+
$Refresh,
113+
114+
[Parameter()]
115+
[System.Management.Automation.SwitchParameter]
116+
$PassThru
117+
)
118+
119+
process
120+
{
121+
if ($PSCmdlet.ParameterSetName -eq 'ServerObject')
122+
{
123+
# Get the database object
124+
$previousErrorActionPreference = $ErrorActionPreference
125+
$ErrorActionPreference = 'Stop'
126+
127+
$DatabaseObject = $ServerObject | Get-SqlDscDatabase -Name $Name -Refresh:$Refresh.IsPresent -ErrorAction 'Stop'
128+
129+
$ErrorActionPreference = $previousErrorActionPreference
130+
}
131+
else
132+
{
133+
$Name = $DatabaseObject.Name
134+
$ServerObject = $DatabaseObject.Parent
135+
}
136+
137+
Write-Verbose -Message ($script:localizedData.DatabaseDefault_Set -f $Name, $ServerObject.InstanceName)
138+
139+
if ($Force.IsPresent -and -not $Confirm)
140+
{
141+
$ConfirmPreference = 'None'
142+
}
143+
144+
try
145+
{
146+
$wasUpdate = $false
147+
148+
if ($PSBoundParameters.ContainsKey('DefaultFileGroup'))
149+
{
150+
$descriptionMessage = $script:localizedData.DatabaseDefault_SetFileGroup_ShouldProcessVerboseDescription -f $Name, $DefaultFileGroup, $ServerObject.InstanceName
151+
$confirmationMessage = $script:localizedData.DatabaseDefault_SetFileGroup_ShouldProcessVerboseWarning -f $Name, $DefaultFileGroup
152+
$captionMessage = $script:localizedData.DatabaseDefault_SetFileGroup_ShouldProcessCaption
153+
154+
if ($PSCmdlet.ShouldProcess($descriptionMessage, $confirmationMessage, $captionMessage))
155+
{
156+
$DatabaseObject.SetDefaultFileGroup($DefaultFileGroup)
157+
$wasUpdate = $true
158+
}
159+
}
160+
161+
if ($PSBoundParameters.ContainsKey('DefaultFileStreamFileGroup'))
162+
{
163+
$descriptionMessage = $script:localizedData.DatabaseDefault_SetFileStreamFileGroup_ShouldProcessVerboseDescription -f $Name, $DefaultFileStreamFileGroup, $ServerObject.InstanceName
164+
$confirmationMessage = $script:localizedData.DatabaseDefault_SetFileStreamFileGroup_ShouldProcessVerboseWarning -f $Name, $DefaultFileStreamFileGroup
165+
$captionMessage = $script:localizedData.DatabaseDefault_SetFileStreamFileGroup_ShouldProcessCaption
166+
167+
if ($PSCmdlet.ShouldProcess($descriptionMessage, $confirmationMessage, $captionMessage))
168+
{
169+
$DatabaseObject.SetDefaultFileStreamFileGroup($DefaultFileStreamFileGroup)
170+
$wasUpdate = $true
171+
}
172+
}
173+
174+
if ($PSBoundParameters.ContainsKey('DefaultFullTextCatalog'))
175+
{
176+
$descriptionMessage = $script:localizedData.DatabaseDefault_SetFullTextCatalog_ShouldProcessVerboseDescription -f $Name, $DefaultFullTextCatalog, $ServerObject.InstanceName
177+
$confirmationMessage = $script:localizedData.DatabaseDefault_SetFullTextCatalog_ShouldProcessVerboseWarning -f $Name, $DefaultFullTextCatalog
178+
$captionMessage = $script:localizedData.DatabaseDefault_SetFullTextCatalog_ShouldProcessCaption
179+
180+
if ($PSCmdlet.ShouldProcess($descriptionMessage, $confirmationMessage, $captionMessage))
181+
{
182+
$DatabaseObject.SetDefaultFullTextCatalog($DefaultFullTextCatalog)
183+
$wasUpdate = $true
184+
}
185+
}
186+
187+
if ($wasUpdate)
188+
{
189+
Write-Verbose -Message ($script:localizedData.DatabaseDefault_Updated -f $Name)
190+
}
191+
192+
if ($PassThru.IsPresent)
193+
{
194+
return $DatabaseObject
195+
}
196+
}
197+
catch
198+
{
199+
$errorMessage = $script:localizedData.DatabaseDefault_SetFailed -f $Name, $ServerObject.InstanceName
200+
201+
$exception = [System.InvalidOperationException]::new($errorMessage, $_.Exception)
202+
203+
$PSCmdlet.ThrowTerminatingError(
204+
[System.Management.Automation.ErrorRecord]::new(
205+
$exception,
206+
'SSDDD0003', # cSpell: disable-line
207+
[System.Management.Automation.ErrorCategory]::InvalidOperation,
208+
$Name
209+
)
210+
)
211+
}
212+
}
213+
}

source/en-US/SqlServerDsc.strings.psd1

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -371,6 +371,23 @@ ConvertFrom-StringData @'
371371
Database_RecoveryModelWrong = The database '{0}' exists and has the recovery model '{1}', but expected it to have the recovery model '{2}'.
372372
Database_OwnerNameWrong = The database '{0}' exists and has the owner '{1}', but expected it to have the owner '{2}'.
373373
374+
## Set-SqlDscDatabaseDefault
375+
DatabaseDefault_Set = Setting default objects of database '{0}' on instance '{1}'. (SSDDD0001)
376+
DatabaseDefault_Updated = Database '{0}' default objects were updated successfully. (SSDDD0002)
377+
DatabaseDefault_SetFailed = Failed to set default objects of database '{0}' on instance '{1}'. (SSDDD0003)
378+
DatabaseDefault_SetFileGroup_ShouldProcessVerboseDescription = Setting the default filegroup of database '{0}' to '{1}' on instance '{2}'.
379+
DatabaseDefault_SetFileGroup_ShouldProcessVerboseWarning = Are you sure you want to set the default filegroup of database '{0}' to '{1}'?
380+
# This string shall not end with full stop (.) since it is used as a title of ShouldProcess messages.
381+
DatabaseDefault_SetFileGroup_ShouldProcessCaption = Set database default filegroup
382+
DatabaseDefault_SetFileStreamFileGroup_ShouldProcessVerboseDescription = Setting the default FILESTREAM filegroup of database '{0}' to '{1}' on instance '{2}'.
383+
DatabaseDefault_SetFileStreamFileGroup_ShouldProcessVerboseWarning = Are you sure you want to set the default FILESTREAM filegroup of database '{0}' to '{1}'?
384+
# This string shall not end with full stop (.) since it is used as a title of ShouldProcess messages.
385+
DatabaseDefault_SetFileStreamFileGroup_ShouldProcessCaption = Set database default FILESTREAM filegroup
386+
DatabaseDefault_SetFullTextCatalog_ShouldProcessVerboseDescription = Setting the default Full-Text catalog of database '{0}' to '{1}' on instance '{2}'.
387+
DatabaseDefault_SetFullTextCatalog_ShouldProcessVerboseWarning = Are you sure you want to set the default Full-Text catalog of database '{0}' to '{1}'?
388+
# This string shall not end with full stop (.) since it is used as a title of ShouldProcess messages.
389+
DatabaseDefault_SetFullTextCatalog_ShouldProcessCaption = Set database default Full-Text catalog
390+
374391
## Get-AgentAlertObject
375392
Get_AgentAlertObject_GettingAlert = Getting SQL Agent Alert '{0}'. (GAAO0001)
376393

0 commit comments

Comments
 (0)