Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
command with the `-DatabaseSnapshotBaseName` parameter.
- Removed parameter `DefaultSchema`. Default schema is a user-level property,
not a database-level property. See [issue #2177](https://github.com/dsccommunity/SqlServerDsc/issues/2177).
- Removed parameter `IsLedger`. Ledger status is read-only after database creation.
Use `New-SqlDscDatabase` with the `-IsLedger` parameter to create ledger databases
[issue #2351](https://github.com/dsccommunity/SqlServerDsc/issues/2351).

### Added

Expand Down Expand Up @@ -58,6 +61,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
database snapshots, enabling control over file placement for snapshots (sparse
files) and custom filegroup/datafile configuration for regular databases
([issue #2341](https://github.com/dsccommunity/SqlServerDsc/issues/2341)).
- Added `IsLedger` parameter to support creating ledger databases at creation time.
Ledger status is read-only after database creation and can only be set when
creating a new database ([issue #2351](https://github.com/dsccommunity/SqlServerDsc/issues/2351)).
- Added public command `Set-SqlDscDatabaseOwner` to change the owner of a SQL Server
database [issue #2177](https://github.com/dsccommunity/SqlServerDsc/issues/2177).
This command uses the SMO `SetOwner()` method and supports both `ServerObject`
Expand Down
34 changes: 34 additions & 0 deletions source/Public/New-SqlDscDatabase.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,13 @@
.PARAMETER OwnerName
Specifies the name of the login that should be the owner of the database.

.PARAMETER IsLedger
Specifies whether to create a ledger database. Ledger databases provide
tamper-evidence capabilities and are immutable once created. This parameter
can only be set during database creation - ledger status cannot be changed
after the database is created. This parameter requires SQL Server 2022
(version 16) or later, or Azure SQL Database.

.PARAMETER DatabaseSnapshotBaseName
Specifies the name of the source database from which to create a snapshot.
When this parameter is specified, a database snapshot will be created instead
Expand Down Expand Up @@ -138,6 +145,10 @@ function New-SqlDscDatabase
[System.String]
$OwnerName,

[Parameter(ParameterSetName = 'Database')]
[System.Boolean]
$IsLedger,

[Parameter(Mandatory = $true, ParameterSetName = 'Snapshot')]
[ValidateNotNullOrEmpty()]
[System.String]
Expand Down Expand Up @@ -255,6 +266,24 @@ function New-SqlDscDatabase
}
}

# Validate IsLedger if specified (requires SQL Server 2022+)
if ($PSBoundParameters.ContainsKey('IsLedger'))
{
if ($ServerObject.VersionMajor -lt 16)
{
$errorMessage = $script:localizedData.Database_IsLedgerNotSupported -f $ServerObject.InstanceName, $ServerObject.VersionMajor

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

# Validate source database exists when creating a snapshot
if ($PSCmdlet.ParameterSetName -eq 'Snapshot')
{
Expand Down Expand Up @@ -312,6 +341,11 @@ function New-SqlDscDatabase
{
$sqlDatabaseObjectToCreate.CompatibilityLevel = $CompatibilityLevel
}

if ($PSBoundParameters.ContainsKey('IsLedger'))
{
$sqlDatabaseObjectToCreate.IsLedger = $IsLedger
}
}

# Add FileGroups if provided (applies to both regular databases and snapshots)
Expand Down
12 changes: 5 additions & 7 deletions source/Public/Set-SqlDscDatabaseProperty.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -135,9 +135,6 @@
.PARAMETER IsFullTextEnabled
Specifies whether full-text search is enabled.

.PARAMETER IsLedger
Specifies whether the database is a ledger database.

.PARAMETER IsParameterizationForced
Specifies whether forced parameterization is enabled for the database.

Expand Down Expand Up @@ -312,6 +309,11 @@
class. To create database snapshots, use the `New-SqlDscDatabaseSnapshot` or
`New-SqlDscDatabase` command with the `-DatabaseSnapshotBaseName` parameter.

- **IsLedger**: Specifies whether the database is a ledger database. Ledger
status can only be set during database creation using the `New-SqlDscDatabase`
command with the `-IsLedger` parameter. Once a database is created, its ledger
status cannot be changed.

There are some database properties that require method calls instead of direct
property assignment and will be supported through separate commands, e.g.
`Set-SqlDscDatabaseDefaultFileGroup`.
Expand Down Expand Up @@ -439,10 +441,6 @@ function Set-SqlDscDatabaseProperty
[System.Boolean]
$IsFullTextEnabled,

[Parameter()]
[System.Boolean]
$IsLedger,

[Parameter()]
[System.Boolean]
$IsParameterizationForced,
Expand Down
1 change: 1 addition & 0 deletions source/en-US/SqlServerDsc.strings.psd1
Original file line number Diff line number Diff line change
Expand Up @@ -358,6 +358,7 @@ ConvertFrom-StringData @'
Database_InvalidCompatibilityLevel = The specified compatibility level '{0}' is not a valid compatibility level for the instance '{1}'.
Database_InvalidCollation = The specified collation '{0}' is not a valid collation for the instance '{1}'.
Database_CatalogCollationNotSupported = The parameter CatalogCollation is not supported on SQL Server instance '{0}' with version '{1}'. This parameter requires SQL Server 2019 (version 15) or later.
Database_IsLedgerNotSupported = The parameter IsLedger is not supported on SQL Server instance '{0}' with version '{1}'. This parameter requires SQL Server 2022 (version 16) or later.
Database_SnapshotSourceDatabaseNotFound = The source database '{0}' for the database snapshot does not exist on instance '{1}'.
Database_CreatingSnapshot = Creating database snapshot '{0}' from source database '{1}'.
Database_Create_ShouldProcessVerboseDescription = Creating the database '{0}' on the instance '{1}'.
Expand Down
37 changes: 36 additions & 1 deletion tests/Unit/Public/New-SqlDscDatabase.Tests.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ Describe 'New-SqlDscDatabase' -Tag 'Public' {
$mockDatabaseObject | Add-Member -MemberType 'NoteProperty' -Name 'RecoveryModel' -Value $null -Force
$mockDatabaseObject | Add-Member -MemberType 'NoteProperty' -Name 'Collation' -Value $null -Force
$mockDatabaseObject | Add-Member -MemberType 'NoteProperty' -Name 'CompatibilityLevel' -Value $null -Force
$mockDatabaseObject | Add-Member -MemberType 'NoteProperty' -Name 'IsLedger' -Value $false -Force
$mockDatabaseObject | Add-Member -MemberType 'ScriptMethod' -Name 'Create' -Value {
# Mock implementation
} -Force
Expand Down Expand Up @@ -102,6 +103,24 @@ Describe 'New-SqlDscDatabase' -Tag 'Public' {
$result.CompatibilityLevel | Should -Be 'Version150'
}

It 'Should create a ledger database with IsLedger set to true' {
# Create a mock server for SQL Server 2022 (version 16) which supports IsLedger
$mockServerObject2022 = New-Object -TypeName 'Microsoft.SqlServer.Management.Smo.Server'
$mockServerObject2022 | Add-Member -MemberType 'NoteProperty' -Name 'InstanceName' -Value 'TestInstance2022' -Force
$mockServerObject2022 | Add-Member -MemberType 'NoteProperty' -Name 'VersionMajor' -Value 16 -Force
$mockServerObject2022 | Add-Member -MemberType 'ScriptProperty' -Name 'Databases' -Value {
return @{} | Add-Member -MemberType 'ScriptMethod' -Name 'Refresh' -Value {
# Mock implementation
} -PassThru -Force
} -Force

$result = New-SqlDscDatabase -ServerObject $mockServerObject2022 -Name 'LedgerDatabase' -IsLedger $true -Force

$result | Should -Not -BeNullOrEmpty
$result.Name | Should -Be 'LedgerDatabase'
$result.IsLedger | Should -BeTrue
}

It 'Should throw error when database already exists' {
$mockServerObjectWithExistingDb = New-Object -TypeName 'Microsoft.SqlServer.Management.Smo.Server'
$mockServerObjectWithExistingDb | Add-Member -MemberType 'NoteProperty' -Name 'InstanceName' -Value 'TestInstance' -Force
Expand Down Expand Up @@ -151,13 +170,23 @@ Describe 'New-SqlDscDatabase' -Tag 'Public' {
$errorRecord.CategoryInfo.Category | Should -Be 'InvalidArgument'
$errorRecord.CategoryInfo.TargetName | Should -Be 'InvalidCollation'
}

It 'Should throw error when IsLedger is used on SQL Server version older than 2022' {
$errorRecord = { New-SqlDscDatabase -ServerObject $mockServerObject -Name 'TestDB' -IsLedger $true -Force } |
Should -Throw -ExpectedMessage '*IsLedger is not supported*' -PassThru

$errorRecord.Exception.Message | Should -BeLike '*IsLedger is not supported*'
$errorRecord.FullyQualifiedErrorId | Should -Be 'NSD0007,New-SqlDscDatabase'
$errorRecord.CategoryInfo.Category | Should -Be 'InvalidOperation'
$errorRecord.CategoryInfo.TargetName | Should -Be 'True'
}
}

Context 'Parameter validation' {
It 'Should have the correct parameters in parameter set Database' -ForEach @(
@{
ExpectedParameterSetName = 'Database'
ExpectedParameters = '-ServerObject <Server> -Name <string> [-Collation <string>] [-CatalogCollation <CatalogCollationType>] [-CompatibilityLevel <string>] [-RecoveryModel <string>] [-OwnerName <string>] [-FileGroup <DatabaseFileGroupSpec[]>] [-Force] [-Refresh] [-WhatIf] [-Confirm] [<CommonParameters>]'
ExpectedParameters = '-ServerObject <Server> -Name <string> [-Collation <string>] [-CatalogCollation <CatalogCollationType>] [-CompatibilityLevel <string>] [-RecoveryModel <string>] [-OwnerName <string>] [-IsLedger <bool>] [-FileGroup <DatabaseFileGroupSpec[]>] [-Force] [-Refresh] [-WhatIf] [-Confirm] [<CommonParameters>]'
}
) {
$result = (Get-Command -Name 'New-SqlDscDatabase').ParameterSets |
Expand Down Expand Up @@ -203,6 +232,12 @@ Describe 'New-SqlDscDatabase' -Tag 'Public' {
$snapshotSetAttribute = $parameterInfo.Attributes | Where-Object { $_.ParameterSetName -eq 'Snapshot' }
$snapshotSetAttribute.Mandatory | Should -BeTrue
}

It 'Should have IsLedger as a parameter in Database parameter set' {
$parameterInfo = (Get-Command -Name 'New-SqlDscDatabase').Parameters['IsLedger']
$databaseSetAttribute = $parameterInfo.Attributes | Where-Object { $_.ParameterSetName -eq 'Database' }
$databaseSetAttribute | Should -Not -BeNullOrEmpty
}
}

Context 'When creating a database snapshot' {
Expand Down
Loading