Skip to content

Commit 48e61cb

Browse files
authored
Add SQL Agent Operator management commands (#2154)
1 parent 8313dbe commit 48e61cb

File tree

67 files changed

+7995
-195
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

67 files changed

+7995
-195
lines changed

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ applyTo: "**/*.[Tt]ests.ps1"
3838

3939
## Syntax Rules
4040
- PascalCase: `Describe`, `Context`, `It`, `Should`, `BeforeAll`, `BeforeEach`, `AfterAll`, `AfterEach`
41-
- Prefer `-BeTrue`/`-BeFalse` over `-Be $true`/`-Be $false`
41+
- Use `-BeTrue`/`-BeFalse` never `-Be $true`/`-Be $false`
4242
- Never use `Assert-MockCalled`, use `Should -Invoke` instead
4343
- No `Should -Not -Throw` - invoke commands directly
4444
- Never add an empty `-MockWith` block

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

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -78,10 +78,11 @@ applyTo: "**/*.ps?(m|d)1"
7878
- Include a `Force` parameter for functions that uses `$PSCmdlet.ShouldContinue` or `$PSCmdlet.ShouldProcess`
7979
- For state-changing functions, use `SupportsShouldProcess`
8080
- Place ShouldProcess check immediately before each state-change
81+
- Set `ConfirmImpact` to 'Low', 'Medium', or 'High' depending on risk
8182
- `$PSCmdlet.ShouldProcess` must use required pattern
8283
- Inside `$PSCmdlet.ShouldProcess`-block, avoid using `Write-Verbose`
8384
- Never use backtick as line continuation in production code.
84-
- Set `$ErrorActionPreference = 'Stop'` before commands using `-ErrorAction 'Stop'`; restore after
85+
- Set `$ErrorActionPreference = 'Stop'` before commands using `-ErrorAction 'Stop'`; restore previous value after
8586

8687
## Output streams
8788

@@ -90,8 +91,8 @@ applyTo: "**/*.ps?(m|d)1"
9091
- Use `Write-Verbose` for: High-level execution flow only; User-actionable information
9192
- Use `Write-Information` for: User-facing status updates; Important operational messages; Non-error state changes
9293
- Use `Write-Warning` for: Non-fatal issues requiring attention; Deprecated functionality usage; Configuration problems that don't block execution
93-
- Use `$PSCmdlet.ThrowTerminatingError()` for terminating errors (except for classes), use relevant error category, in try-catch include exception
94-
- Use `Write-Error` for non-terminating errors, use relevant error category
94+
- Use `$PSCmdlet.ThrowTerminatingError()` for terminating errors (except for classes), use relevant error category, in try-catch include exception with localized message
95+
- Use `Write-Error` for non-terminating errors, use relevant error category; always use `return` after `Write-Error` to avoid further processing
9596

9697
## ShouldProcess Required Pattern
9798

@@ -184,6 +185,7 @@ function Get-Something
184185
- Assign function results to variables rather than inline calls
185186
- Return a single, consistent object type per function
186187
- return `$null` for no objects/non-terminating errors
188+
- Use `::new()` static method instead of `New-Object` for .NET types, e.g `[System.Management.Automation.ErrorRecord]::new()`
187189

188190
### Security & Safety
189191

@@ -207,6 +209,7 @@ function Get-Something
207209
- End files with only one blank line
208210
- Use CR+LF line endings
209211
- Maximum two consecutive newlines
212+
- No line shall have trailing whitespace
210213

211214
## File Encoding
212215

.github/instructions/dsc-community-style-guidelines-unit-tests.instructions.md

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@ applyTo: "tests/[u]Unit/**/*.[Tt]ests.ps1"
1515
Use this exact setup block before `Describe`:
1616

1717
```powershell
18-
[System.Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseDeclaredVarsMoreThanAssignments', '')]
1918
[System.Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseDeclaredVarsMoreThanAssignments', '', Justification = 'Suppressing this rule because Script Analyzer does not understand Pester syntax.')]
2019
param ()
2120

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,3 +2,4 @@
22
.vs
33
output/
44
coverage.xml
5+
testResults.xml

CHANGELOG.md

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,19 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
3838
- `Set-SqlDscDatabaseDefault`
3939
- Added new command to set default objects of a database in a SQL Server
4040
Database Engine instance (issue [#2178](https://github.com/dsccommunity/SqlServerDsc/issues/2178)).
41+
- `Set-SqlDscConfigurationOption`
42+
- Added new command to set SQL Server Database Engine configuration options
43+
using SMO with validation, ShouldProcess support, and dynamic tab completion.
44+
- `Test-SqlDscConfigurationOption`
45+
- Added new command to test if SQL Server Database Engine configuration options
46+
have the specified value using SMO with dynamic tab completion for both
47+
option names and values.
48+
- `Get-SqlDscConfigurationOption`
49+
- Enhanced existing command to return user-friendly metadata objects by default
50+
with properties Name, RunValue, ConfigValue, Minimum, Maximum, and IsDynamic.
51+
- Added `-Raw` switch to return original SMO ConfigProperty objects for
52+
backward compatibility.
53+
- Added dynamic tab completion for the `-Name` parameter.
4154
- The command can set the default filegroup, default FILESTREAM filegroup,
4255
and default Full-Text catalog using SMO methods SetDefaultFileGroup,
4356
SetDefaultFileStreamFileGroup, and SetDefaultFullTextCatalog.
@@ -81,6 +94,17 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
8194
- Added `Get-SqlDscAgentAlert`, `New-SqlDscAgentAlert`,
8295
`Set-SqlDscAgentAlert`, `Remove-SqlDscAgentAlert`, and `Test-SqlDscAgentAlert`
8396
to manage SQL Agent alerts on a Database Engine instance.
97+
- Added new public commands for SQL Agent Operator management:
98+
- `Get-SqlDscAgentOperator` - Get SQL Agent Operators from a SQL Server
99+
Database Engine instance
100+
- `New-SqlDscAgentOperator` - Create a new SQL Agent Operator with specified properties
101+
- `Set-SqlDscAgentOperator` - Update existing SQL Agent Operator properties
102+
- `Remove-SqlDscAgentOperator` - Remove a SQL Agent Operator from the instance
103+
- `Enable-SqlDscAgentOperator` - Enable a SQL Agent Operator
104+
- `Disable-SqlDscAgentOperator` - Disable a SQL Agent Operator
105+
- `Test-SqlDscIsAgentOperator` - Test if a SQL Agent Operator exists
106+
- Supports pipeline input for both ServerObject and OperatorObject where applicable
107+
- Includes comprehensive unit tests and follows ShouldProcess patterns
84108
- Added new public commands for database management:
85109
- `Get-SqlDscDatabase` - Get databases from a SQL Server Database Engine instance
86110
- `New-SqlDscDatabase` - Create a new database with specified properties
@@ -91,9 +115,14 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
91115
patterns
92116
- Database objects can also be used as pipeline input for Set and Remove operations
93117
- Commands include comprehensive validation, localization, and ShouldProcess support
118+
- Added private function `Get-CommandParameter` to filter command parameters
119+
by excluding specified parameter names and common parameters, providing a
120+
reusable way to determine settable properties on objects.
94121

95122
### Changed
96123

124+
- Improved code quality by ensuring all function invocations in the private
125+
and public functions use named parameters instead of positional parameters.
97126
- SqlServerDsc
98127
- Updated GitVersion.yml feature branch regex pattern to use anchor `^f(eature(s)?)?[\/-]`
99128
for more precise branch name matching.

azure-pipelines.yml

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -293,6 +293,9 @@ stages:
293293
'tests/Integration/Commands/Assert-SqlDscLogin.Integration.Tests.ps1'
294294
'tests/Integration/Commands/New-SqlDscLogin.Integration.Tests.ps1'
295295
'tests/Integration/Commands/Get-SqlDscLogin.Integration.Tests.ps1'
296+
'tests/Integration/Commands/Get-SqlDscConfigurationOption.Integration.Tests.ps1'
297+
'tests/Integration/Commands/Set-SqlDscConfigurationOption.Integration.Tests.ps1'
298+
'tests/Integration/Commands/Test-SqlDscConfigurationOption.Integration.Tests.ps1'
296299
'tests/Integration/Commands/Disable-SqlDscLogin.Integration.Tests.ps1'
297300
'tests/Integration/Commands/Enable-SqlDscLogin.Integration.Tests.ps1'
298301
'tests/Integration/Commands/Test-SqlDscIsLoginEnabled.Integration.Tests.ps1'
@@ -311,8 +314,16 @@ stages:
311314
'tests/Integration/Commands/New-SqlDscAgentAlert.Integration.Tests.ps1'
312315
'tests/Integration/Commands/Set-SqlDscAgentAlert.Integration.Tests.ps1'
313316
'tests/Integration/Commands/Test-SqlDscAgentAlert.Integration.Tests.ps1'
317+
'tests/Integration/Commands/Get-SqlDscAgentOperator.Integration.Tests.ps1'
318+
'tests/Integration/Commands/New-SqlDscAgentOperator.Integration.Tests.ps1'
319+
'tests/Integration/Commands/Set-SqlDscAgentOperator.Integration.Tests.ps1'
320+
'tests/Integration/Commands/Test-SqlDscIsAgentOperator.Integration.Tests.ps1'
321+
'tests/Integration/Commands/Assert-SqlDscAgentOperator.Integration.Tests.ps1'
322+
'tests/Integration/Commands/Enable-SqlDscAgentOperator.Integration.Tests.ps1'
323+
'tests/Integration/Commands/Disable-SqlDscAgentOperator.Integration.Tests.ps1'
314324
# Group 8
315325
'tests/Integration/Commands/Remove-SqlDscAgentAlert.Integration.Tests.ps1'
326+
'tests/Integration/Commands/Remove-SqlDscAgentOperator.Integration.Tests.ps1'
316327
'tests/Integration/Commands/Remove-SqlDscDatabase.Integration.Tests.ps1'
317328
'tests/Integration/Commands/Remove-SqlDscRole.Integration.Tests.ps1'
318329
'tests/Integration/Commands/Remove-SqlDscLogin.Integration.Tests.ps1'

source/Classes/020.SqlRSSetup.ps1

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -608,7 +608,7 @@ class SqlRSSetup : ResourceBase
608608
'InstallFolder'
609609
'LogPath'
610610
) |
611-
Where-Object {
611+
Where-Object -FilterScript {
612612
$properties.ContainsKey($_)
613613
}
614614

source/Examples/Resources/SqlDatabaseMail/1-EnableDatabaseMail.ps1

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,4 +47,3 @@ Configuration Example
4747
}
4848
}
4949
}
50-
Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
<#
2+
.SYNOPSIS
3+
Converts a hashtable of bound parameters into a formatted string for ShouldProcess descriptions.
4+
5+
.DESCRIPTION
6+
This function takes a hashtable of bound parameters and formats them into a readable string
7+
for use in ShouldProcess verbose descriptions. It excludes non-settable parameters and
8+
formats each parameter as 'ParameterName: Value'.
9+
10+
.PARAMETER BoundParameters
11+
Hashtable of bound parameters (typically $PSBoundParameters).
12+
13+
.PARAMETER Exclude
14+
Array of parameter names to exclude from the formatted output.
15+
16+
.OUTPUTS
17+
System.String
18+
19+
Returns a formatted string with parameters and their values.
20+
21+
.EXAMPLE
22+
$formattedText = ConvertTo-FormattedParameterDescription -BoundParameters $PSBoundParameters -Exclude @('ServerObject', 'Name', 'Force')
23+
24+
Returns a formatted string like:
25+
"
26+
EmailAddress: 'admin@company.com'
27+
CategoryName: 'Notifications'
28+
"
29+
#>
30+
function ConvertTo-FormattedParameterDescription
31+
{
32+
[CmdletBinding()]
33+
[OutputType([System.String])]
34+
param
35+
(
36+
[Parameter(Mandatory = $true)]
37+
[System.Collections.Hashtable]
38+
$BoundParameters,
39+
40+
[Parameter()]
41+
[System.String[]]
42+
$Exclude = @()
43+
)
44+
45+
$parameterDescriptions = @()
46+
47+
foreach ($parameter in ($BoundParameters.Keys | Sort-Object))
48+
{
49+
if ($parameter -notin $Exclude)
50+
{
51+
$raw = $BoundParameters[$parameter]
52+
53+
$value = if ($raw -is [System.Security.SecureString])
54+
{
55+
'***'
56+
}
57+
elseif ($raw -is [System.Management.Automation.PSCredential])
58+
{
59+
$raw.UserName
60+
}
61+
elseif ($raw -is [System.Array])
62+
{
63+
($raw -join ', ')
64+
}
65+
else
66+
{
67+
$raw
68+
}
69+
70+
$parameterDescriptions += "$parameter`: '$value'"
71+
}
72+
}
73+
74+
if ($parameterDescriptions.Count -gt 0)
75+
{
76+
return "`r`n " + ($parameterDescriptions -join "`r`n ")
77+
}
78+
else
79+
{
80+
return " $($script:localizedData.ConvertTo_FormattedParameterDescription_NoParametersToUpdate)"
81+
}
82+
}
Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
<#
2+
.SYNOPSIS
3+
Retrieves a SQL Server Agent Operator object.
4+
5+
.DESCRIPTION
6+
This private function retrieves a SQL Server Agent Operator object using the provided
7+
parameters. If the operator is not found, it throws a non-terminating error. Callers
8+
can use -ErrorAction to control error behavior.
9+
10+
.PARAMETER ServerObject
11+
Specifies the server object on which to retrieve the operator.
12+
13+
.PARAMETER Name
14+
Specifies the name of the operator to retrieve.
15+
16+
.PARAMETER Refresh
17+
Specifies whether to refresh the operators collection before retrieving the operator.
18+
When specified, the function calls Refresh() on the JobServer.Operators collection.
19+
20+
.INPUTS
21+
None.
22+
23+
.OUTPUTS
24+
Microsoft.SqlServer.Management.Smo.Agent.Operator
25+
26+
Returns the operator object if found.
27+
28+
.EXAMPLE
29+
$operatorObject = Get-AgentOperatorObject -ServerObject $serverObject -Name 'TestOperator'
30+
31+
Returns the SQL Agent Operator object for 'TestOperator', throws error if not found.
32+
33+
.EXAMPLE
34+
$operatorObject = Get-AgentOperatorObject -ServerObject $serverObject -Name 'TestOperator' -Refresh
35+
36+
Returns the SQL Agent Operator object for 'TestOperator' after refreshing the operators collection.
37+
#>
38+
function Get-AgentOperatorObject
39+
{
40+
[CmdletBinding()]
41+
[OutputType([Microsoft.SqlServer.Management.Smo.Agent.Operator])]
42+
param
43+
(
44+
[Parameter(Mandatory = $true)]
45+
[Microsoft.SqlServer.Management.Smo.Server]
46+
$ServerObject,
47+
48+
[Parameter(Mandatory = $true)]
49+
[System.String]
50+
$Name,
51+
52+
[Parameter()]
53+
[System.Management.Automation.SwitchParameter]
54+
$Refresh
55+
)
56+
57+
Write-Verbose -Message ($script:localizedData.Get_AgentOperatorObject_GettingOperator -f $Name)
58+
59+
if ($Refresh)
60+
{
61+
Write-Verbose -Message $script:localizedData.Get_AgentOperatorObject_RefreshingOperators
62+
$ServerObject.JobServer.Operators.Refresh()
63+
}
64+
65+
$operatorObject = $ServerObject.JobServer.Operators[$Name]
66+
67+
if ($null -eq $operatorObject)
68+
{
69+
$errorMessage = $script:localizedData.AgentOperator_NotFound -f $Name
70+
71+
Write-Error -Message $errorMessage -Category 'ObjectNotFound' -ErrorId 'GAOO0001' -TargetObject $Name
72+
73+
return $null
74+
}
75+
76+
return $operatorObject
77+
}

0 commit comments

Comments
 (0)