Skip to content

Commit b6b1daa

Browse files
authored
Enable-/Disable-SqlDscDatabaseSnapshotIsolation: Add new commands (#2351)
1 parent 6c4fbd1 commit b6b1daa

10 files changed

+1421
-0
lines changed

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ applyTo: "**/*.[Tt]ests.ps1"
3535
- Use nested `Context` blocks for complex scenarios
3636
- Mocking in `BeforeAll` (`BeforeEach` only when required)
3737
- Setup/teardown in `BeforeAll`,`BeforeEach`/`AfterAll`,`AfterEach` close to usage
38+
- Spacing between blocks, arrange, act, and assert for readability
3839

3940
## Syntax Rules
4041
- PascalCase: `Describe`, `Context`, `It`, `Should`, `BeforeAll`, `BeforeEach`, `AfterAll`, `AfterEach`

CHANGELOG.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,14 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
2828

2929
### Added
3030

31+
- Added public command `Enable-SqlDscDatabaseSnapshotIsolation` to enable snapshot
32+
isolation for a database in a SQL Server Database Engine instance. This command
33+
uses the SMO `SetSnapshotIsolation()` method to enable row-versioning and snapshot
34+
isolation settings to optimize concurrency and consistency ([issue #2329](https://github.com/dsccommunity/SqlServerDsc/issues/2329)).
35+
- Added public command `Disable-SqlDscDatabaseSnapshotIsolation` to disable snapshot
36+
isolation for a database in a SQL Server Database Engine instance. This command
37+
uses the SMO `SetSnapshotIsolation()` method to disable row-versioning and snapshot
38+
isolation settings ([issue #2329](https://github.com/dsccommunity/SqlServerDsc/issues/2329)).
3139
- Added public command `New-SqlDscDatabaseSnapshot` to create database snapshots
3240
in a SQL Server Database Engine instance using SMO. This command provides an
3341
automated and DSC-friendly approach to snapshot management by leveraging
Lines changed: 190 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,190 @@
1+
<#
2+
.SYNOPSIS
3+
Disables snapshot isolation for a database in a SQL Server Database Engine instance.
4+
5+
.DESCRIPTION
6+
This command disables snapshot isolation for a database in a SQL Server Database Engine
7+
instance. Disabling snapshot isolation removes row-versioning and snapshot isolation
8+
settings for the database.
9+
10+
The command uses the SetSnapshotIsolation() method on the SMO Database object to disable
11+
row-versioning and snapshot isolation settings.
12+
13+
.PARAMETER ServerObject
14+
Specifies current server connection object.
15+
16+
.PARAMETER Name
17+
Specifies the name of the database to modify.
18+
19+
.PARAMETER DatabaseObject
20+
Specifies the database object to modify (from Get-SqlDscDatabase).
21+
22+
.PARAMETER Refresh
23+
Specifies that the **ServerObject**'s databases should be refreshed before
24+
trying to get the database object. This is helpful when databases could have been
25+
modified outside of the **ServerObject**, for example through T-SQL. But
26+
on instances with a large amount of databases it might be better to make
27+
sure the **ServerObject** is recent enough.
28+
29+
This parameter is only used when setting snapshot isolation using **ServerObject** and
30+
**Name** parameters.
31+
32+
.PARAMETER Force
33+
Specifies that snapshot isolation should be disabled without any confirmation.
34+
35+
.PARAMETER PassThru
36+
Specifies that the database object should be returned after modification.
37+
38+
.EXAMPLE
39+
$serverObject = Connect-SqlDscDatabaseEngine -InstanceName 'MyInstance'
40+
Disable-SqlDscDatabaseSnapshotIsolation -ServerObject $serverObject -Name 'MyDatabase'
41+
42+
Disables snapshot isolation for the database named **MyDatabase**.
43+
44+
.EXAMPLE
45+
$serverObject = Connect-SqlDscDatabaseEngine -InstanceName 'MyInstance'
46+
$databaseObject = $serverObject | Get-SqlDscDatabase -Name 'MyDatabase'
47+
Disable-SqlDscDatabaseSnapshotIsolation -DatabaseObject $databaseObject -Force
48+
49+
Disables snapshot isolation for the database using a database object without prompting for confirmation.
50+
51+
.EXAMPLE
52+
$serverObject = Connect-SqlDscDatabaseEngine -InstanceName 'MyInstance'
53+
Disable-SqlDscDatabaseSnapshotIsolation -ServerObject $serverObject -Name 'MyDatabase' -PassThru
54+
55+
Disables snapshot isolation and returns the updated database object.
56+
57+
.INPUTS
58+
Microsoft.SqlServer.Management.Smo.Database
59+
60+
The database object to modify (from Get-SqlDscDatabase).
61+
62+
.OUTPUTS
63+
None.
64+
65+
By default, no output is returned.
66+
67+
.OUTPUTS
68+
Microsoft.SqlServer.Management.Smo.Database
69+
70+
When PassThru is specified, the updated database object is returned.
71+
#>
72+
function Disable-SqlDscDatabaseSnapshotIsolation
73+
{
74+
[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.')]
75+
[OutputType()]
76+
[OutputType([Microsoft.SqlServer.Management.Smo.Database])]
77+
[CmdletBinding(DefaultParameterSetName = 'ServerObjectSet', SupportsShouldProcess = $true, ConfirmImpact = 'Medium')]
78+
param
79+
(
80+
[Parameter(ParameterSetName = 'ServerObjectSet', Mandatory = $true)]
81+
[Microsoft.SqlServer.Management.Smo.Server]
82+
$ServerObject,
83+
84+
[Parameter(ParameterSetName = 'ServerObjectSet', Mandatory = $true)]
85+
[ValidateNotNullOrEmpty()]
86+
[System.String]
87+
$Name,
88+
89+
[Parameter(ParameterSetName = 'ServerObjectSet')]
90+
[System.Management.Automation.SwitchParameter]
91+
$Refresh,
92+
93+
[Parameter(ParameterSetName = 'DatabaseObjectSet', Mandatory = $true, ValueFromPipeline = $true)]
94+
[Microsoft.SqlServer.Management.Smo.Database]
95+
$DatabaseObject,
96+
97+
[Parameter()]
98+
[System.Management.Automation.SwitchParameter]
99+
$Force,
100+
101+
[Parameter()]
102+
[System.Management.Automation.SwitchParameter]
103+
$PassThru
104+
)
105+
106+
begin
107+
{
108+
if ($Force.IsPresent -and -not $Confirm)
109+
{
110+
$ConfirmPreference = 'None'
111+
}
112+
}
113+
114+
process
115+
{
116+
# Get the database object based on the parameter set
117+
switch ($PSCmdlet.ParameterSetName)
118+
{
119+
'ServerObjectSet'
120+
{
121+
$previousErrorActionPreference = $ErrorActionPreference
122+
$ErrorActionPreference = 'Stop'
123+
124+
$sqlDatabaseObject = $ServerObject |
125+
Get-SqlDscDatabase -Name $Name -Refresh:$Refresh -ErrorAction 'Stop'
126+
127+
$ErrorActionPreference = $previousErrorActionPreference
128+
}
129+
130+
'DatabaseObjectSet'
131+
{
132+
$sqlDatabaseObject = $DatabaseObject
133+
}
134+
}
135+
136+
$descriptionMessage = $script:localizedData.DatabaseSnapshotIsolation_Disable_ShouldProcessVerboseDescription -f $sqlDatabaseObject.Name, $sqlDatabaseObject.Parent.InstanceName
137+
$confirmationMessage = $script:localizedData.DatabaseSnapshotIsolation_Disable_ShouldProcessVerboseWarning -f $sqlDatabaseObject.Name
138+
$captionMessage = $script:localizedData.DatabaseSnapshotIsolation_Disable_ShouldProcessCaption
139+
140+
if ($PSCmdlet.ShouldProcess($descriptionMessage, $confirmationMessage, $captionMessage))
141+
{
142+
# Check if snapshot isolation is already disabled (idempotence)
143+
if ($sqlDatabaseObject.SnapshotIsolationState -eq 'Disabled')
144+
{
145+
Write-Debug -Message ($script:localizedData.DatabaseSnapshotIsolation_AlreadyDisabled -f $sqlDatabaseObject.Name)
146+
}
147+
else
148+
{
149+
Write-Debug -Message ($script:localizedData.DatabaseSnapshotIsolation_Disabling -f $sqlDatabaseObject.Name)
150+
151+
try
152+
{
153+
$sqlDatabaseObject.SetSnapshotIsolation($false)
154+
}
155+
catch
156+
{
157+
$errorMessage = $script:localizedData.DatabaseSnapshotIsolation_DisableFailed -f $sqlDatabaseObject.Name
158+
159+
$PSCmdlet.ThrowTerminatingError(
160+
[System.Management.Automation.ErrorRecord]::new(
161+
[System.InvalidOperationException]::new($errorMessage, $_.Exception),
162+
'DSDSI0001', # cspell: disable-line
163+
[System.Management.Automation.ErrorCategory]::InvalidOperation,
164+
$sqlDatabaseObject
165+
)
166+
)
167+
}
168+
169+
Write-Debug -Message ($script:localizedData.DatabaseSnapshotIsolation_Disabled -f $sqlDatabaseObject.Name)
170+
}
171+
172+
<#
173+
Refresh the database object to get the updated SnapshotIsolationState property if:
174+
- PassThru is specified (user wants the updated object back)
175+
- Using DatabaseObject parameter set (user's object reference should be updated)
176+
177+
Refresh even if no change was made to ensure the object is up to date.
178+
#>
179+
if ($PassThru.IsPresent -or $PSCmdlet.ParameterSetName -eq 'DatabaseObjectSet')
180+
{
181+
$sqlDatabaseObject.Refresh()
182+
}
183+
184+
if ($PassThru.IsPresent)
185+
{
186+
return $sqlDatabaseObject
187+
}
188+
}
189+
}
190+
}

0 commit comments

Comments
 (0)