Skip to content
Merged
Show file tree
Hide file tree
Changes from 18 commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
6000673
Initial plan
Copilot Sep 6, 2025
98100f5
Implement Set-SqlDscDatabaseDefault command with tests and documentation
Copilot Sep 6, 2025
5b4faa9
Fix file endings and replace Should -Not -Throw with direct command c…
Copilot Sep 6, 2025
8dadb42
Merge branch 'main' into copilot/fix-2178
johlju Sep 6, 2025
116623e
Replace New-InvalidOperationException with PSCmdlet.ThrowTerminatingE…
Copilot Sep 6, 2025
7e61feb
Fix integ test
johlju Sep 6, 2025
430a830
Merge branch 'main' into copilot/fix-2178
johlju Sep 6, 2025
b6c41f6
fix instructions
johlju Sep 6, 2025
950d028
Fix PSCmdlet.ThrowTerminatingError() to include exception parameter
Copilot Sep 6, 2025
bb57a89
Refine AI and DSC community guidelines for clarity and consistency
johlju Sep 6, 2025
c25798a
Update error handling guidelines to include try-catch for terminating…
johlju Sep 6, 2025
3c125da
Refactor verbose message variables in Set-SqlDscDatabaseDefault funct…
johlju Sep 6, 2025
c4aa5ce
Add guideline to avoid Write-Verbose inside ShouldProcess block for s…
johlju Sep 6, 2025
2c9585d
Enhance Set-SqlDscDatabaseDefault function with detailed ShouldProces…
johlju Sep 6, 2025
fc59c28
Consolidate PowerShell style and test guideline instructions in commu…
johlju Sep 6, 2025
0d297cf
Refactor `Set-SqlDscDatabaseDefault` command documentation for clarit…
johlju Sep 6, 2025
20de1f5
Update CHANGELOG.md to clarify the purpose of Set-SqlDscDatabaseDefau…
johlju Sep 6, 2025
75fb8d8
Add INPUTS section to Set-SqlDscDatabaseDefault documentation for pip…
johlju Sep 6, 2025
b0dc201
Remove verbose messages for updating default file group, file stream …
johlju Sep 6, 2025
1c5571b
Update database default object strings to use new identifier format
johlju Sep 6, 2025
a9117e5
Remove redundant OutputType attribute from Set-SqlDscDatabaseDefault …
johlju Sep 6, 2025
dfd2468
Refactor Set-SqlDscDatabaseDefault to improve error handling and stre…
johlju Sep 6, 2025
4106fe0
Add "filegroup" to cSpell words in settings.json
johlju Sep 6, 2025
e7ba896
Update error code in Set-SqlDscDatabaseDefault and clean up test cases
johlju Sep 6, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 1 addition & 34 deletions .github/copilot-instructions.md
Original file line number Diff line number Diff line change
@@ -1,35 +1,2 @@
# AI Instructions

This file provides AI agent guidance for the project. Each instruction file below
targets specific file glob patterns and use cases.

## Build & Test Workflow
- Run in PowerShell, from repository root
- Build before running tests: `.\build.ps1 -Tasks build`
- Always run tests in new PowerShell session: `Invoke-Pester -Path @({test paths}) -Output Detailed`

## Instructions Overview

The guidelines always take priority over existing code patterns in project.

# Requirements
- SqlServerDsc-specific guidelines override general project guidelines
- Follow PowerShell style guidelines
- Maintain localization requirements across all source files
- Follow test patterns strictly for maintainability

## Core Project Guidelines

- Follow SqlServerDsc project specific guidelines: [./instructions/SqlServerDsc-guidelines.instructions.md](./instructions/SqlServerDsc-guidelines.instructions.md)
- Always follow PowerShell code style guidelines: [./instructions/dsc-community-style-guidelines-powershell.instructions.md](./instructions/dsc-community-style-guidelines-powershell.instructions.md)
- Follow Project-level guidelines: [./instructions/dsc-community-style-guidelines.instructions.md](./instructions/dsc-community-style-guidelines.instructions.md)
- Follow localization requirements: [./instructions/dsc-community-style-guidelines-localization.instructions.md](./instructions/dsc-community-style-guidelines-localization.instructions.md)
- Always add Unit testing according to: [./instructions/dsc-community-style-guidelines-unit-tests.instructions.md](./instructions/dsc-community-style-guidelines-unit-tests.instructions.md)
- Always add Integration testing according to: [./instructions/dsc-community-style-guidelines-integration-tests.instructions.md](./instructions/dsc-community-style-guidelines-integration-tests.instructions.md)
- Follow Markdown formatting requirements: [./instructions/dsc-community-style-guidelines-markdown.instructions.md](./instructions/dsc-community-style-guidelines-markdown.instructions.md)
- Always update CHANGELOG.md: [./instructions/dsc-community-style-guidelines-changelog.instructions.md](./instructions/dsc-community-style-guidelines-changelog.instructions.md)

## Desired State Configuration (DSC) Resource Guidelines

New DSC resources should always be created as class-based resources.

- Follow class-based resources guidelines: [./instructions/dsc-community-style-guidelines-class-resource.instructions.md](./instructions/dsc-community-style-guidelines-class-resource.instructions.md)
Original file line number Diff line number Diff line change
Expand Up @@ -86,9 +86,9 @@ Add to .DESCRIPTION section:
- `## Requirements`: List minimum requirements
- `## 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}).`

## Error Handling
## Error Handling for classes
- Use `try/catch` blocks to handle exceptions
- Do not use `throw` for terminating errors, use `New-*Exception` commands:
- Do not use `throw` for terminating errors, use `New-*Exception` commands (never for functions):
- [`New‑InvalidDataException`](https://github.com/dsccommunity/DscResource.Common/wiki/New%E2%80%91InvalidDataException)
- [`New-ArgumentException`](https://github.com/dsccommunity/DscResource.Common/wiki/New%E2%80%91ArgumentException)
- [`New-InvalidOperationException`](https://github.com/dsccommunity/DscResource.Common/wiki/New%E2%80%91InvalidOperationException)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,9 @@ applyTo: "source/DSCResources/**/*.psm1"
- Use localized strings for all messages (Write-Verbose, Write-Error, etc.)
- Import localized strings using `Get-LocalizedData` at module top

## Error Handling
- Do not use `throw` for terminating errors
## Error Handling for MOF-based resources
- Use `try/catch` blocks to handle exceptions
- Throw localized exceptions using the appropriate `New-*Exception` cmdlet:
- Do not use `throw` for terminating errors, use `New-*Exception` commands (never for functions):
- [`New‑InvalidDataException`](https://github.com/dsccommunity/DscResource.Common/wiki/New%E2%80%91InvalidDataException)
- [`New-ArgumentException`](https://github.com/dsccommunity/DscResource.Common/wiki/New%E2%80%91ArgumentException)
- [`New-InvalidOperationException`](https://github.com/dsccommunity/DscResource.Common/wiki/New%E2%80%91InvalidOperationException)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ applyTo: "**/*.ps?(m|d)1"
- For state-changing functions, use `SupportsShouldProcess`
- Place ShouldProcess check immediately before each state-change
- `$PSCmdlet.ShouldProcess` must use required pattern
- Inside `$PSCmdlet.ShouldProcess`-block, avoid using `Write-Verbose`
- Never use backtick as line continuation in production code.
- Set `$ErrorActionPreference = 'Stop'` before commands using `-ErrorAction 'Stop'`; restore after

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

## ShouldProcess Required Pattern
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,12 @@ applyTo: "**"
- Integration tests: `tests/Integration/Commands/{CommandName}.Integration.Tests.ps1`

## Requirements
- Follow guidelines over existing code patterns
- Follow instructions over existing code patterns
- Follow PowerShell style and test guideline instructions strictly
- Always update CHANGELOG.md Unreleased section
- Localize all strings using string keys; remove any orphaned string keys
- Check DscResource.Common before creating private functions
- Separate reusable logic into private functions
- DSC resources should always be created as class-based resources
- Add unit tests for all commands/functions/resources
- Add integration tests for all public commands and resources
10 changes: 8 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

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

Expand Down
225 changes: 225 additions & 0 deletions source/Public/Set-SqlDscDatabaseDefault.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,225 @@
<#
.SYNOPSIS
Sets default objects of a database in a SQL Server Database Engine instance.

.DESCRIPTION
This command sets default objects of a database in a SQL Server Database Engine instance.
It can set the default filegroup, default FILESTREAM filegroup, and default Full-Text catalog
using SMO methods.

.PARAMETER ServerObject
Specifies current server connection object.

.PARAMETER DatabaseObject
Specifies a database object to modify.

.PARAMETER Name
Specifies the name of the database to be modified.

.PARAMETER DefaultFileGroup
Sets the default filegroup for the database. The filegroup must exist in the database.

.PARAMETER DefaultFileStreamFileGroup
Sets the default FILESTREAM filegroup for the database. The filegroup must exist in the database.

.PARAMETER DefaultFullTextCatalog
Sets the default Full-Text catalog for the database. The catalog must exist in the database.

.PARAMETER Force
Specifies that the database defaults should be modified without any confirmation.

.PARAMETER Refresh
Specifies that the **ServerObject**'s databases should be refreshed before
modifying the database object. This is helpful when databases could have been
modified outside of the **ServerObject**, for example through T-SQL. But
on instances with a large amount of databases it might be better to make
sure the **ServerObject** is recent enough, or pass in **DatabaseObject**.

.PARAMETER PassThru
Specifies that the database object should be returned after modification.

.EXAMPLE
$serverObject = Connect-SqlDscDatabaseEngine -InstanceName 'MyInstance'
$databaseObject = $serverObject | Get-SqlDscDatabase -Name 'MyDatabase'
$databaseObject | Set-SqlDscDatabaseDefault -DefaultFileGroup 'MyFileGroup'

Sets the default filegroup of the database named **MyDatabase** to **MyFileGroup**.

.EXAMPLE
$serverObject = Connect-SqlDscDatabaseEngine -InstanceName 'MyInstance'
$serverObject | Set-SqlDscDatabaseDefault -Name 'MyDatabase' -DefaultFullTextCatalog 'MyCatalog' -Force

Sets the default Full-Text catalog of the database named **MyDatabase** to **MyCatalog** without prompting for confirmation.

.EXAMPLE
$serverObject = Connect-SqlDscDatabaseEngine -InstanceName 'MyInstance'
$databaseObject = $serverObject | Get-SqlDscDatabase -Name 'MyDatabase'
$databaseObject | Set-SqlDscDatabaseDefault -DefaultFileGroup 'DataFileGroup' -DefaultFileStreamFileGroup 'FileStreamFileGroup' -DefaultFullTextCatalog 'FTCatalog'

Sets multiple default objects for the database named **MyDatabase**.

.INPUTS
Microsoft.SqlServer.Management.Smo.Server
Server object accepted from the pipeline (ServerObject parameter set).

Microsoft.SqlServer.Management.Smo.Database
Database object accepted from the pipeline (DatabaseObject parameter set).

.OUTPUTS
None. But when **PassThru** is specified the output is `[Microsoft.SqlServer.Management.Smo.Database]`.
#>
function Set-SqlDscDatabaseDefault
{
[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.')]
[OutputType()]
[OutputType([Microsoft.SqlServer.Management.Smo.Database])]
[CmdletBinding(SupportsShouldProcess = $true, ConfirmImpact = 'Medium')]
param
(
[Parameter(ParameterSetName = 'ServerObject', Mandatory = $true, ValueFromPipeline = $true)]
[Microsoft.SqlServer.Management.Smo.Server]
$ServerObject,

[Parameter(ParameterSetName = 'DatabaseObject', Mandatory = $true, ValueFromPipeline = $true)]
[Microsoft.SqlServer.Management.Smo.Database]
$DatabaseObject,

[Parameter(ParameterSetName = 'ServerObject', Mandatory = $true)]
[ValidateNotNullOrEmpty()]
[System.String]
$Name,

[Parameter()]
[ValidateNotNullOrEmpty()]
[System.String]
$DefaultFileGroup,

[Parameter()]
[ValidateNotNullOrEmpty()]
[System.String]
$DefaultFileStreamFileGroup,

[Parameter()]
[ValidateNotNullOrEmpty()]
[System.String]
$DefaultFullTextCatalog,

[Parameter()]
[System.Management.Automation.SwitchParameter]
$Force,

[Parameter(ParameterSetName = 'ServerObject')]
[System.Management.Automation.SwitchParameter]
$Refresh,

[Parameter()]
[System.Management.Automation.SwitchParameter]
$PassThru
)

process
{
if ($PSCmdlet.ParameterSetName -eq 'ServerObject')
{
if ($Refresh.IsPresent)
{
# Refresh the server object's databases collection
$ServerObject.Databases.Refresh()
}

Write-Verbose -Message ($script:localizedData.DatabaseDefault_Set -f $Name, $ServerObject.InstanceName)

# Get the database object
$DatabaseObject = $ServerObject.Databases[$Name]

if (-not $DatabaseObject)
{
$errorMessage = $script:localizedData.Database_NotFound -f $Name
New-InvalidOperationException -Message $errorMessage
}
}
else
{
$Name = $DatabaseObject.Name
$ServerObject = $DatabaseObject.Parent
Write-Verbose -Message ($script:localizedData.DatabaseDefault_Set -f $Name, $ServerObject.InstanceName)
}

if ($Force.IsPresent -and -not $Confirm)
{
$ConfirmPreference = 'None'
}

try
{
$wasUpdate = $false

if ($PSBoundParameters.ContainsKey('DefaultFileGroup'))
{
$descriptionMessage = $script:localizedData.DatabaseDefault_SetFileGroup_ShouldProcessVerboseDescription -f $Name, $DefaultFileGroup, $ServerObject.InstanceName
$confirmationMessage = $script:localizedData.DatabaseDefault_SetFileGroup_ShouldProcessVerboseWarning -f $Name, $DefaultFileGroup
$captionMessage = $script:localizedData.DatabaseDefault_SetFileGroup_ShouldProcessCaption

if ($PSCmdlet.ShouldProcess($descriptionMessage, $confirmationMessage, $captionMessage))
{
Write-Verbose -Message ($script:localizedData.DatabaseDefault_UpdatingDefaultFileGroup -f $DefaultFileGroup)
$DatabaseObject.SetDefaultFileGroup($DefaultFileGroup)
$wasUpdate = $true
}
}

if ($PSBoundParameters.ContainsKey('DefaultFileStreamFileGroup'))
{
$descriptionMessage = $script:localizedData.DatabaseDefault_SetFileStreamFileGroup_ShouldProcessVerboseDescription -f $Name, $DefaultFileStreamFileGroup, $ServerObject.InstanceName
$confirmationMessage = $script:localizedData.DatabaseDefault_SetFileStreamFileGroup_ShouldProcessVerboseWarning -f $Name, $DefaultFileStreamFileGroup
$captionMessage = $script:localizedData.DatabaseDefault_SetFileStreamFileGroup_ShouldProcessCaption

if ($PSCmdlet.ShouldProcess($descriptionMessage, $confirmationMessage, $captionMessage))
{
Write-Verbose -Message ($script:localizedData.DatabaseDefault_UpdatingDefaultFileStreamFileGroup -f $DefaultFileStreamFileGroup)
$DatabaseObject.SetDefaultFileStreamFileGroup($DefaultFileStreamFileGroup)
$wasUpdate = $true
}
}

if ($PSBoundParameters.ContainsKey('DefaultFullTextCatalog'))
{
$descriptionMessage = $script:localizedData.DatabaseDefault_SetFullTextCatalog_ShouldProcessVerboseDescription -f $Name, $DefaultFullTextCatalog, $ServerObject.InstanceName
$confirmationMessage = $script:localizedData.DatabaseDefault_SetFullTextCatalog_ShouldProcessVerboseWarning -f $Name, $DefaultFullTextCatalog
$captionMessage = $script:localizedData.DatabaseDefault_SetFullTextCatalog_ShouldProcessCaption

if ($PSCmdlet.ShouldProcess($descriptionMessage, $confirmationMessage, $captionMessage))
{
Write-Verbose -Message ($script:localizedData.DatabaseDefault_UpdatingDefaultFullTextCatalog -f $DefaultFullTextCatalog)
$DatabaseObject.SetDefaultFullTextCatalog($DefaultFullTextCatalog)
$wasUpdate = $true
}
}

if ($wasUpdate)
{
Write-Verbose -Message ($script:localizedData.DatabaseDefault_Updated -f $Name)
}

if ($PassThru.IsPresent)
{
return $DatabaseObject
}
}
catch
{
$errorMessage = $script:localizedData.DatabaseDefault_SetFailed -f $Name, $ServerObject.InstanceName

$exception = [System.InvalidOperationException]::new($errorMessage, $_.Exception)

$PSCmdlet.ThrowTerminatingError(
[System.Management.Automation.ErrorRecord]::new(
$exception,
'SSDDD0001', # cSpell: disable-line
[System.Management.Automation.ErrorCategory]::InvalidOperation,
$Name
)
)
}
}
}
Loading
Loading