Skip to content

Commit

Permalink
SqlServerDsc: Add public command Get-SqlDscConfigurationOption (#1935)
Browse files Browse the repository at this point in the history
- SqlServerDsc
  - Added new public command:
    - `Get-SqlDscConfigurationOption` - Returns the available configuration
      options that can be used with the DSC resource _SqlConfiguration_.
  • Loading branch information
johlju authored May 7, 2023
1 parent 7d58bf5 commit d296853
Show file tree
Hide file tree
Showing 8 changed files with 348 additions and 4 deletions.
3 changes: 2 additions & 1 deletion .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,8 @@
"GetxPDTVariable",
"Dbcc",
"creplace",
"dbatools"
"dbatools",
"fastbuild"
],
"cSpell.ignorePaths": [
".git"
Expand Down
9 changes: 9 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,15 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [Unreleased]

### Added

- SqlServerDsc
- Added a new build task `fastbuild` that can be used during development
process when there are no need to generate documentation.
- Added new public command:
- `Get-SqlDscConfigurationOption` - Returns the available configuration
options that can be used with the DSC resource _SqlConfiguration_.

### Changed

- SqlServerDsc
Expand Down
11 changes: 8 additions & 3 deletions build.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,16 @@ BuildWorkflow:
- Generate_Conceptual_Help
- Generate_Wiki_Content

fastbuild:
- Clean
- Build_Module_ModuleBuilder
- Build_NestedModules_ModuleBuilder

pack:
- build
- package_module_nupkg
- package_module_nupkg # cSpell: disable-line

hqrmtest:
hqrmtest: # cSpell: disable-line
- Invoke_HQRM_Tests_Stop_On_Fail

test:
Expand Down Expand Up @@ -146,7 +151,7 @@ Resolve-Dependency:
GitHubConfig:
GitHubFilesToAdd:
- 'CHANGELOG.md'
GitHubConfigUserName: dscbot
GitHubConfigUserName: dscbot # cSpell: disable-line
GitHubConfigUserEmail: dsccommunity@outlook.com
UpdateChangelogOnPrerelease: false

Expand Down
7 changes: 7 additions & 0 deletions source/DSCResources/DSC_SqlConfiguration/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,13 @@
The `SqlConfiguration` DSC resource manages the [SQL Server Configuration Options](https://msdn.microsoft.com/en-us/library/ms189631.aspx)
on a SQL Server instance.

To list the available configuration option names run:

```powershell
$serverObject = Connect-SqlDscDatabaseEngine -InstanceName 'SQL2022'
$serverObject | Get-SqlDscConfigurationOption | ft
```

## Requirements

* Target machine must be running Windows Server 2012 or later.
Expand Down
95 changes: 95 additions & 0 deletions source/Public/Get-SqlDscConfigurationOption.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
<#
.SYNOPSIS
Get server configuration option.
.DESCRIPTION
This command gets the available configuration options from a SQL Server Database Engine instance.
.PARAMETER ServerObject
Specifies current server connection object.
.PARAMETER Name
Specifies the name of the configuration option to get.
.PARAMETER Refresh
Specifies that the **ServerObject**'s configuration property should be
refreshed before trying get the available configuration options. This is
helpful when run values or configuration values have been modified outside
of the specified **ServerObject**.
.EXAMPLE
$serverObject = Connect-SqlDscDatabaseEngine -InstanceName 'MyInstance'
$sqlServerObject | Get-SqlDscConfigurationOption
Get all the available configuration options.
.EXAMPLE
$serverObject = Connect-SqlDscDatabaseEngine -InstanceName 'MyInstance'
$sqlServerObject | Get-SqlDscConfigurationOption -Name '*threshold*'
Get the configuration options that contains the word **threshold**.
.OUTPUTS
`[Microsoft.SqlServer.Management.Smo.ConfigProperty[]]`
#>
function Get-SqlDscConfigurationOption
{
[System.Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseOutputTypeCorrectly', '', Justification = 'Because the rule does not understands that the command returns [System.String[]] when using , (comma) in the return statement')]
[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([Microsoft.SqlServer.Management.Smo.ConfigProperty[]])]
[CmdletBinding()]
param
(
[Parameter(Mandatory = $true, ValueFromPipeline = $true)]
[Microsoft.SqlServer.Management.Smo.Server]
$ServerObject,

[Parameter()]
[System.String]
$Name,

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

process
{
if ($Refresh.IsPresent)
{
# Make sure the configuration option values are up-to-date.
$serverObject.Configuration.Refresh()
}

if ($PSBoundParameters.ContainsKey('Name'))
{
$configurationOption = $serverObject.Configuration.Properties |
Where-Object -FilterScript {
$_.DisplayName -like $Name
}

if (-not $configurationOption)
{
$missingConfigurationOptionMessage = $script:localizedData.ConfigurationOption_Get_Missing -f $Name

$writeErrorParameters = @{
Message = $missingConfigurationOptionMessage
Category = 'InvalidOperation'
ErrorId = 'GSDCO0001' # cspell: disable-line
TargetObject = $Name
}

Write-Error @writeErrorParameters
}
}
else
{
$configurationOption = $serverObject.Configuration.Properties.ForEach({ $_ })
}

return , [Microsoft.SqlServer.Management.Smo.ConfigProperty[]] (
$configurationOption |
Sort-Object -Property 'DisplayName'
)
}
}
3 changes: 3 additions & 0 deletions source/en-US/SqlServerDsc.strings.psd1
Original file line number Diff line number Diff line change
Expand Up @@ -178,4 +178,7 @@ ConvertFrom-StringData @'
## Get-FileVersionInformation
FileVersionInformation_Get_FilePathIsNotFile = The specified path is not a file.
## Get-SqlDscConfigurationOption
ConfigurationOption_Get_Missing = There is no configuration option with the name '{0}'.
'@
187 changes: 187 additions & 0 deletions tests/Unit/Public/Get-SqlDscConfigurationOption.Tests.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,187 @@
[System.Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseDeclaredVarsMoreThanAssignments', '')]
param ()

BeforeDiscovery {
try
{
if (-not (Get-Module -Name 'DscResource.Test'))
{
# Assumes dependencies has been resolved, so if this module is not available, run 'noop' task.
if (-not (Get-Module -Name 'DscResource.Test' -ListAvailable))
{
# Redirect all streams to $null, except the error stream (stream 2)
& "$PSScriptRoot/../../build.ps1" -Tasks 'noop' 2>&1 4>&1 5>&1 6>&1 > $null
}

# If the dependencies has not been resolved, this will throw an error.
Import-Module -Name 'DscResource.Test' -Force -ErrorAction 'Stop'
}
}
catch [System.IO.FileNotFoundException]
{
throw 'DscResource.Test module dependency not found. Please run ".\build.ps1 -ResolveDependency -Tasks build" first.'
}
}

BeforeAll {
$script:dscModuleName = 'SqlServerDsc'

$env:SqlServerDscCI = $true

Import-Module -Name $script:dscModuleName

# Loading mocked classes
Add-Type -Path (Join-Path -Path (Join-Path -Path $PSScriptRoot -ChildPath '../Stubs') -ChildPath 'SMO.cs')

$PSDefaultParameterValues['InModuleScope:ModuleName'] = $script:dscModuleName
$PSDefaultParameterValues['Mock:ModuleName'] = $script:dscModuleName
$PSDefaultParameterValues['Should:ModuleName'] = $script:dscModuleName
}

AfterAll {
$PSDefaultParameterValues.Remove('InModuleScope:ModuleName')
$PSDefaultParameterValues.Remove('Mock:ModuleName')
$PSDefaultParameterValues.Remove('Should:ModuleName')

# Unload the module being tested so that it doesn't impact any other tests.
Get-Module -Name $script:dscModuleName -All | Remove-Module -Force

Remove-Item -Path 'env:SqlServerDscCI'
}

Describe 'Get-SqlDscConfigurationOption' -Tag 'Public' {
It 'Should have the correct parameters in parameter set <MockParameterSetName>' -ForEach @(
@{
MockParameterSetName = '__AllParameterSets'
MockExpectedParameters = '[-ServerObject] <Server> [[-Name] <string>] [-Refresh] [<CommonParameters>]'
}
) {
$result = (Get-Command -Name 'Get-SqlDscConfigurationOption').ParameterSets |
Where-Object -FilterScript {
$_.Name -eq $mockParameterSetName
} |
Select-Object -Property @(
@{
Name = 'ParameterSetName'
Expression = { $_.Name }
},
@{
Name = 'ParameterListAsString'
Expression = { $_.ToString() }
}
)

$result.ParameterSetName | Should -Be $MockParameterSetName
$result.ParameterListAsString | Should -Be $MockExpectedParameters
}

Context 'When the specified configuration option exist' {
BeforeAll {
$mockServerObject = New-Object -TypeName 'Microsoft.SqlServer.Management.Smo.Server' |
Add-Member -MemberType 'ScriptProperty' -Name 'Configuration' -Value {
return @{
Properties = @()
}
} -PassThru -Force

$mockDefaultParameters = @{
ServerObject = $mockServerObject
Name = 'Unknown Option Name'
}
}

Context 'When specifying to throw on error' {
BeforeAll {
$mockErrorMessage = InModuleScope -ScriptBlock {
$script:localizedData.ConfigurationOption_Get_Missing
}
}

It 'Should throw the correct error' {
{ Get-SqlDscConfigurationOption @mockDefaultParameters -ErrorAction 'Stop' } |
Should -Throw -ExpectedMessage ($mockErrorMessage -f 'Unknown Option Name')
}
}

Context 'When ignoring the error' {
It 'Should not throw an exception and return $null' {
Get-SqlDscConfigurationOption @mockDefaultParameters -ErrorAction 'SilentlyContinue' |
Should -BeNullOrEmpty
}
}
}

Context 'When getting a specific configuration option' {
BeforeAll {
$mockServerObject = New-Object -TypeName 'Microsoft.SqlServer.Management.Smo.Server' |
Add-Member -MemberType 'ScriptProperty' -Name 'Configuration' -Value {
$configOption1 = [Microsoft.SqlServer.Management.Smo.ConfigProperty]::CreateTypeInstance()
$configOption1.DisplayName = 'blocked process threshold (s)'

return @{
Properties = @($configOption1)
}
} -PassThru -Force
}

It 'Should return the correct values' {
$mockDefaultParameters = @{
ServerObject = $mockServerObject
Name = 'blocked process threshold (s)'
}

$result = Get-SqlDscConfigurationOption @mockDefaultParameters

$result | Should -BeOfType 'Microsoft.SqlServer.Management.Smo.ConfigProperty'

$result.DisplayName | Should -Be 'blocked process threshold (s)'
}

Context 'When passing parameter ServerObject over the pipeline' {
It 'Should return the correct values' {
$result = $mockServerObject | Get-SqlDscConfigurationOption -Name 'blocked process threshold (s)'

$result | Should -BeOfType 'Microsoft.SqlServer.Management.Smo.ConfigProperty'

$result.DisplayName | Should -Be 'blocked process threshold (s)'
}
}
}

Context 'When getting all available configuration options' {
BeforeAll {
$mockServerObject = New-Object -TypeName 'Microsoft.SqlServer.Management.Smo.Server' |
Add-Member -MemberType 'ScriptProperty' -Name 'Configuration' -Value {
$configOption1 = [Microsoft.SqlServer.Management.Smo.ConfigProperty]::CreateTypeInstance()
$configOption1.DisplayName = 'blocked process threshold (s)'

$configOption2 = [Microsoft.SqlServer.Management.Smo.ConfigProperty]::CreateTypeInstance()
$configOption2.DisplayName = 'show advanced options'

return @{
Properties = @($configOption1, $configOption2)
}
} -PassThru -Force
}

It 'Should return the correct values' {
$result = Get-SqlDscConfigurationOption -ServerObject $mockServerObject

$result | Should -BeOfType 'Microsoft.SqlServer.Management.Smo.ConfigProperty'

$result.DisplayName | Should -Contain 'show advanced options'
$result.DisplayName | Should -Contain 'blocked process threshold (s)'
}

Context 'When passing parameter ServerObject over the pipeline' {
It 'Should return the correct values' {
$result = $mockServerObject | Get-SqlDscConfigurationOption

$result | Should -BeOfType 'Microsoft.SqlServer.Management.Smo.ConfigProperty'

$result.DisplayName | Should -Contain 'show advanced options'
$result.DisplayName | Should -Contain 'blocked process threshold (s)'
}
}
}
}
Loading

0 comments on commit d296853

Please sign in to comment.