Skip to content
12 changes: 9 additions & 3 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Removed parameter `OwnerName` [issue #2177](https://github.com/dsccommunity/SqlServerDsc/issues/2177).
Use the new command `Set-SqlDscDatabaseOwner` to change database ownership instead.
- BREAKING CHANGE: `Set-SqlDscDatabaseProperty`
- Removed parameters `AzureEdition` and `AzureServiceObjective`. Azure SQL Database
service tier and SLO changes should be managed using `Set-AzSqlDatabase` from the
Azure PowerShell module instead. See [issue #2177](https://github.com/dsccommunity/SqlServerDsc/issues/2177).
- Removed parameters `AzureEdition` and `AzureServiceObjective`. Azure SQL
Database service tier and SLO changes should be managed using
`Set-AzSqlDatabase` from the Azure PowerShell module instead. See
[issue #2177](https://github.com/dsccommunity/SqlServerDsc/issues/2177).
- Removed parameter `DatabaseSnapshotBaseName`. Database snapshots should be
created using the `New-SqlDscDatabaseSnapshot`, or the `New-SqlDscDatabase`
command with the `-DatabaseSnapshotBaseName` parameter.
Expand Down Expand Up @@ -49,6 +50,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
added to a Database later using `Add-SqlDscFileGroup`.
- Added public command `New-SqlDscDataFile` to create DataFile objects for SQL
Server FileGroups. This command simplifies creating DataFile objects with
- Added public command `Set-SqlDscDatabaseDefaultFileGroup` to set the default
filegroup or default FILESTREAM filegroup for a database in a SQL Server Database
Engine instance. This command uses the SMO `SetDefaultFileGroup()` or
`SetDefaultFileStreamFileGroup()` methods to change the default filegroup settings
([issue #2328](https://github.com/dsccommunity/SqlServerDsc/issues/2328)).
specified physical file paths, supporting both regular database files (.mdf, .ndf)
and sparse files for database snapshots (.ss). The `FileGroup` parameter is
mandatory, requiring DataFile objects to be created with an associated FileGroup.
Expand Down
1 change: 1 addition & 0 deletions azure-pipelines.yml
Original file line number Diff line number Diff line change
Expand Up @@ -344,6 +344,7 @@ stages:
'tests/Integration/Commands/Get-SqlDscCompatibilityLevel.Integration.Tests.ps1'
'tests/Integration/Commands/Set-SqlDscDatabaseProperty.Integration.Tests.ps1'
'tests/Integration/Commands/Set-SqlDscDatabaseOwner.Integration.Tests.ps1'
'tests/Integration/Commands/Set-SqlDscDatabaseDefaultFileGroup.Integration.Tests.ps1'
'tests/Integration/Commands/Test-SqlDscIsDatabase.Integration.Tests.ps1'
'tests/Integration/Commands/Test-SqlDscDatabaseProperty.Integration.Tests.ps1'
'tests/Integration/Commands/Get-SqlDscDatabasePermission.Integration.Tests.ps1'
Expand Down
267 changes: 267 additions & 0 deletions source/Public/Set-SqlDscDatabaseDefaultFileGroup.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,267 @@
<#
.SYNOPSIS
Sets the default filegroup for a database in a SQL Server Database Engine instance.

.DESCRIPTION
This command sets the default filegroup or default FILESTREAM filegroup for a
database in a SQL Server Database Engine instance.

The filegroup must exist in the database. The command uses the SetDefaultFileGroup()
or SetDefaultFileStreamFileGroup() methods on the SMO Database object to change
the default filegroup.

.PARAMETER ServerObject
Specifies current server connection object.

.PARAMETER Name
Specifies the name of the database to modify.

.PARAMETER DatabaseObject
Specifies the database object to modify (from Get-SqlDscDatabase).

.PARAMETER Refresh
Specifies that the **ServerObject**'s databases should be refreshed before
trying to get 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.

This parameter is only used when setting the default filegroup using **ServerObject**
and **Name** parameters.

.PARAMETER DefaultFileGroup
Specifies the name of the filegroup that should be set as the default filegroup
for the database. This is mutually exclusive with **DefaultFileStreamFileGroup**.

.PARAMETER DefaultFileStreamFileGroup
Specifies the name of the filegroup that should be set as the default FILESTREAM
filegroup for the database. This is mutually exclusive with **DefaultFileGroup**.

.PARAMETER Force
Specifies that the default filegroup should be modified without any confirmation.

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

.EXAMPLE
$serverObject = Connect-SqlDscDatabaseEngine -InstanceName 'MyInstance'
Set-SqlDscDatabaseDefaultFileGroup -ServerObject $serverObject -Name 'MyDatabase' -DefaultFileGroup 'UserData'

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

.EXAMPLE
$serverObject = Connect-SqlDscDatabaseEngine -InstanceName 'MyInstance'
Set-SqlDscDatabaseDefaultFileGroup -ServerObject $serverObject -Name 'MyDatabase' -DefaultFileStreamFileGroup 'FileStreamData'

Sets the default FILESTREAM filegroup of the database named **MyDatabase** to **FileStreamData**.

.EXAMPLE
$serverObject = Connect-SqlDscDatabaseEngine -InstanceName 'MyInstance'
$databaseObject = $serverObject | Get-SqlDscDatabase -Name 'MyDatabase'
Set-SqlDscDatabaseDefaultFileGroup -DatabaseObject $databaseObject -DefaultFileGroup 'UserData' -Force

Sets the default filegroup of the database using a database object without prompting for confirmation.

.EXAMPLE
$serverObject = Connect-SqlDscDatabaseEngine -InstanceName 'MyInstance'
$databaseObject = $serverObject | Get-SqlDscDatabase -Name 'MyDatabase'
Set-SqlDscDatabaseDefaultFileGroup -DatabaseObject $databaseObject -DefaultFileStreamFileGroup 'FileStreamData'

Sets the default FILESTREAM filegroup of the database using a database object.

.EXAMPLE
$serverObject = Connect-SqlDscDatabaseEngine -InstanceName 'MyInstance'
Set-SqlDscDatabaseDefaultFileGroup -ServerObject $serverObject -Name 'MyDatabase' -DefaultFileGroup 'UserData' -PassThru

Sets the default filegroup and returns the updated database object.

.INPUTS
Microsoft.SqlServer.Management.Smo.Database

The database object to modify (from Get-SqlDscDatabase).

.OUTPUTS
None

No output is returned by default.

.OUTPUTS
Microsoft.SqlServer.Management.Smo.Database

Returns the database object when PassThru is specified.
#>
function Set-SqlDscDatabaseDefaultFileGroup
{
[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.')]
[OutputType()]
[OutputType([Microsoft.SqlServer.Management.Smo.Database])]
[CmdletBinding(DefaultParameterSetName = 'ServerObjectSet', SupportsShouldProcess = $true, ConfirmImpact = 'Medium')]
param
(
[Parameter(ParameterSetName = 'ServerObjectSet', Mandatory = $true)]
[Parameter(ParameterSetName = 'ServerObjectSetFileStream', Mandatory = $true)]
[Microsoft.SqlServer.Management.Smo.Server]
$ServerObject,

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

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

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

[Parameter(ParameterSetName = 'ServerObjectSet', Mandatory = $true)]
[Parameter(ParameterSetName = 'DatabaseObjectSet', Mandatory = $true)]
[ValidateNotNullOrEmpty()]
[System.String]
$DefaultFileGroup,

[Parameter(ParameterSetName = 'ServerObjectSetFileStream', Mandatory = $true)]
[Parameter(ParameterSetName = 'DatabaseObjectSetFileStream', Mandatory = $true)]
[ValidateNotNullOrEmpty()]
[System.String]
$DefaultFileStreamFileGroup,

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

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

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

process
{
# Get the database object based on the parameter set
switch -Wildcard ($PSCmdlet.ParameterSetName)
{
'ServerObjectSet*'
{
$previousErrorActionPreference = $ErrorActionPreference
$ErrorActionPreference = 'Stop'

$sqlDatabaseObject = $ServerObject |
Get-SqlDscDatabase -Name $Name -Refresh:$Refresh -ErrorAction 'Stop'

$ErrorActionPreference = $previousErrorActionPreference
}

'DatabaseObjectSet*'
{
$sqlDatabaseObject = $DatabaseObject
}
}

# Determine which filegroup type to set
if ($PSBoundParameters.ContainsKey('DefaultFileGroup'))
{
$fileGroupName = $DefaultFileGroup
$currentFileGroup = $sqlDatabaseObject.DefaultFileGroup
$verboseDescriptionMessage = $script:localizedData.DatabaseDefaultFileGroup_Set_ShouldProcessVerboseDescription_DefaultFileGroup -f $sqlDatabaseObject.Name, $fileGroupName, $sqlDatabaseObject.Parent.InstanceName
$verboseWarningMessage = $script:localizedData.DatabaseDefaultFileGroup_Set_ShouldProcessVerboseWarning_DefaultFileGroup -f $sqlDatabaseObject.Name, $fileGroupName
}
else
{
$fileGroupName = $DefaultFileStreamFileGroup
$currentFileGroup = $sqlDatabaseObject.DefaultFileStreamFileGroup
$verboseDescriptionMessage = $script:localizedData.DatabaseDefaultFileGroup_Set_ShouldProcessVerboseDescription_DefaultFileStreamFileGroup -f $sqlDatabaseObject.Name, $fileGroupName, $sqlDatabaseObject.Parent.InstanceName
$verboseWarningMessage = $script:localizedData.DatabaseDefaultFileGroup_Set_ShouldProcessVerboseWarning_DefaultFileStreamFileGroup -f $sqlDatabaseObject.Name, $fileGroupName
}

$captionMessage = $script:localizedData.DatabaseDefaultFileGroup_Set_ShouldProcessCaption

if ($PSCmdlet.ShouldProcess($verboseDescriptionMessage, $verboseWarningMessage, $captionMessage))
{
# Check if the default filegroup is already correct (idempotence)
if ($currentFileGroup -eq $fileGroupName)
{
if ($PSBoundParameters.ContainsKey('DefaultFileGroup'))
{
Write-Debug -Message ($script:localizedData.DatabaseDefaultFileGroup_AlreadyCorrect_DefaultFileGroup -f $sqlDatabaseObject.Name, $fileGroupName)
}
else
{
Write-Debug -Message ($script:localizedData.DatabaseDefaultFileGroup_AlreadyCorrect_DefaultFileStreamFileGroup -f $sqlDatabaseObject.Name, $fileGroupName)
}
}
else
{
if ($PSBoundParameters.ContainsKey('DefaultFileGroup'))
{
Write-Debug -Message ($script:localizedData.DatabaseDefaultFileGroup_Updating_DefaultFileGroup -f $sqlDatabaseObject.Name, $fileGroupName)
}
else
{
Write-Debug -Message ($script:localizedData.DatabaseDefaultFileGroup_Updating_DefaultFileStreamFileGroup -f $sqlDatabaseObject.Name, $fileGroupName)
}

try
{
if ($PSBoundParameters.ContainsKey('DefaultFileGroup'))
{
$sqlDatabaseObject.SetDefaultFileGroup($fileGroupName)
}
else
{
$sqlDatabaseObject.SetDefaultFileStreamFileGroup($fileGroupName)
}
}
catch
{
if ($PSBoundParameters.ContainsKey('DefaultFileGroup'))
{
$errorMessage = $script:localizedData.DatabaseDefaultFileGroup_SetFailed_DefaultFileGroup -f $sqlDatabaseObject.Name, $fileGroupName
}
else
{
$errorMessage = $script:localizedData.DatabaseDefaultFileGroup_SetFailed_DefaultFileStreamFileGroup -f $sqlDatabaseObject.Name, $fileGroupName
}

$PSCmdlet.ThrowTerminatingError(
[System.Management.Automation.ErrorRecord]::new(
[System.InvalidOperationException]::new($errorMessage, $_.Exception),
'SSDDFG0004', # cspell: disable-line
[System.Management.Automation.ErrorCategory]::InvalidOperation,
$sqlDatabaseObject
)
)
}

if ($PSBoundParameters.ContainsKey('DefaultFileGroup'))
{
Write-Debug -Message ($script:localizedData.DatabaseDefaultFileGroup_Updated_DefaultFileGroup -f $sqlDatabaseObject.Name, $fileGroupName)
}
else
{
Write-Debug -Message ($script:localizedData.DatabaseDefaultFileGroup_Updated_DefaultFileStreamFileGroup -f $sqlDatabaseObject.Name, $fileGroupName)
}
}

if ($PassThru.IsPresent)
{
# Refresh the database object to get the updated default filegroup property
$sqlDatabaseObject.Refresh()

$sqlDatabaseObject
}
}
}
}
16 changes: 16 additions & 0 deletions source/en-US/SqlServerDsc.strings.psd1
Original file line number Diff line number Diff line change
Expand Up @@ -422,6 +422,22 @@ ConvertFrom-StringData @'
# This string shall not end with full stop (.) since it is used as a title of ShouldProcess messages.
DatabaseOwner_Set_ShouldProcessCaption = Set database owner on instance

## Set-SqlDscDatabaseDefaultFileGroup
DatabaseDefaultFileGroup_Updating_DefaultFileGroup = Setting default filegroup of database '{0}' to '{1}'. (SSDDFG0001)
DatabaseDefaultFileGroup_Updated_DefaultFileGroup = Default filegroup of database '{0}' was set to '{1}'. (SSDDFG0002)
DatabaseDefaultFileGroup_AlreadyCorrect_DefaultFileGroup = Default filegroup of database '{0}' is already set to '{1}'. (SSDDFG0003)
DatabaseDefaultFileGroup_SetFailed_DefaultFileGroup = Failed to set default filegroup of database '{0}' to '{1}'. (SSDDFG0004)
DatabaseDefaultFileGroup_Set_ShouldProcessVerboseDescription_DefaultFileGroup = Setting the default filegroup of the database '{0}' to '{1}' on the instance '{2}'.
DatabaseDefaultFileGroup_Set_ShouldProcessVerboseWarning_DefaultFileGroup = Are you sure you want to change the default filegroup of the database '{0}' to '{1}'?
DatabaseDefaultFileGroup_Updating_DefaultFileStreamFileGroup = Setting default FILESTREAM filegroup of database '{0}' to '{1}'. (SSDDFG0005)
DatabaseDefaultFileGroup_Updated_DefaultFileStreamFileGroup = Default FILESTREAM filegroup of database '{0}' was set to '{1}'. (SSDDFG0006)
DatabaseDefaultFileGroup_AlreadyCorrect_DefaultFileStreamFileGroup = Default FILESTREAM filegroup of database '{0}' is already set to '{1}'. (SSDDFG0007)
DatabaseDefaultFileGroup_SetFailed_DefaultFileStreamFileGroup = Failed to set default FILESTREAM filegroup of database '{0}' to '{1}'. (SSDDFG0008)
DatabaseDefaultFileGroup_Set_ShouldProcessVerboseDescription_DefaultFileStreamFileGroup = Setting the default FILESTREAM filegroup of the database '{0}' to '{1}' on the instance '{2}'.
DatabaseDefaultFileGroup_Set_ShouldProcessVerboseWarning_DefaultFileStreamFileGroup = Are you sure you want to change the default FILESTREAM filegroup of the database '{0}' to '{1}'?
# This string shall not end with full stop (.) since it is used as a title of ShouldProcess messages.
DatabaseDefaultFileGroup_Set_ShouldProcessCaption = Set database default filegroup on instance

## Enable-SqlDscDatabaseSnapshotIsolation
DatabaseSnapshotIsolation_Enabling = Enabling snapshot isolation for database '{0}'. (ESDSI0002)
DatabaseSnapshotIsolation_Enabled = Snapshot isolation for database '{0}' was enabled. (ESDSI0003)
Expand Down
1 change: 1 addition & 0 deletions tests/Integration/Commands/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,7 @@ New-SqlDscDatabaseSnapshot | 5 | 4 (New-SqlDscDatabase), 1 (Install-SqlDscServer
Get-SqlDscCompatibilityLevel | 4 | 1 (Install-SqlDscServer), 0 (Prerequisites) | DSCSQLTEST | -
Set-SqlDscDatabaseProperty | 4 | 1 (Install-SqlDscServer), 0 (Prerequisites) | DSCSQLTEST | -
Set-SqlDscDatabaseOwner | 4 | 1 (Install-SqlDscServer), 0 (Prerequisites) | DSCSQLTEST | -
Set-SqlDscDatabaseDefaultFileGroup | 4 | 1 (Install-SqlDscServer), 0 (Prerequisites) | DSCSQLTEST | -
Test-SqlDscIsDatabase | 4 | 1 (Install-SqlDscServer), 0 (Prerequisites) | DSCSQLTEST | -
Test-SqlDscDatabaseProperty | 4 | 1 (Install-SqlDscServer), 0 (Prerequisites) | DSCSQLTEST | -
Get-SqlDscDatabasePermission | 4 | 1 (Install-SqlDscServer), 0 (Prerequisites) | DSCSQLTEST | Test database, Test user
Expand Down
Loading
Loading