Skip to content

Commit 371314d

Browse files
authored
Test-SqlDscIsAgentAlert: Command rename proposal (#2204)
1 parent 1440fce commit 371314d

24 files changed

+603
-174
lines changed

.github/copilot-instructions.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
11
# Requirements
2-
- SqlServerDsc-specific guidelines override general project guidelines
2+
- SqlServerDsc-specific guidelines and requirements override general project guidelines and requirements

.github/instructions/SqlServerDsc-guidelines.instructions.md

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,15 @@ description: SqlServerDsc-specific guidelines for AI development.
33
applyTo: "**"
44
---
55

6-
# SqlServerDsc Guidelines
6+
# SqlServerDsc Requirements
7+
8+
## Build & Test Workflow Requirements
9+
- Run PowerShell script files from repository root
10+
- Setup build and test environment (once per `pwsh` session): `./build.ps1 -Tasks noop`
11+
- Build project before running tests: `./build.ps1 -Tasks build`
12+
- Run tests without coverage (wildcards allowed): `Invoke-PesterJob -Path '{tests filepath}' -SkipCodeCoverage`
13+
- Run QA tests: `Invoke-PesterJob -Path 'tests/QA' -SkipCodeCoverage`
14+
- Never run integration tests locally
715

816
## Naming
917
- Public commands: `{Verb}-SqlDsc{Noun}` format
@@ -25,7 +33,7 @@ applyTo: "**"
2533
- Reporting Services: instance `SSRS`
2634
- Power BI Report Server: instance `PBIRS`
2735

28-
## Test Requirements
36+
## Tests Requirements
2937
- Unit tests: Add `$env:SqlServerDscCI = $true` in `BeforeAll`, remove in `AfterAll`
3038
- Integration tests:
3139
- If requiring SQL Server DB, start the Windows service in `BeforeAll`, stop it in `AfterAll`.

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

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,4 +10,5 @@ applyTo: "CHANGELOG.md"
1010
- Describe notable changes briefly, ≤2 items per change type
1111
- Reference issues using format [issue #<issue_number>](https://github.com/<owner>/<repo>/issues/<issue_number>)
1212
- No empty lines between list items in same section
13-
- Do not add item if there are already an existing item for the same change
13+
- Skip adding entry if same change already exists in Unreleased section
14+
- No duplicate sections or items in Unreleased section

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

Lines changed: 22 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -64,8 +64,8 @@ applyTo: "**/*.ps?(m|d)1"
6464
- Comment-based help: SYNOPSIS, DESCRIPTION (40+ chars), PARAMETER, EXAMPLE sections before function/class
6565
- Comment-based help indentation: keywords 4 spaces, text 8 spaces
6666
- Include examples for all parameter sets and combinations
67-
- INPUTS: List each pipeline‑accepted type (one per line) with a 1‑line description.
68-
- OUTPUTS: List each return type (one per line) with a 1‑line description. Must match both [OutputType()] and actual returns.
67+
- INPUTS: List each pipeline‑accepted type (one per line) with a 1‑line description. Repeat keyword for each input type.
68+
- OUTPUTS: List each return type (one per line) with a 1‑line description. Repeat keyword for each output type. Must match both `[OutputType()]` and actual returns.
6969
- .NOTES: Include only if it conveys critical info (constraints, side effects, security, version compatibility, breaking behavior). Keep to ≤2 short sentences.
7070

7171
## Functions
@@ -83,6 +83,7 @@ applyTo: "**/*.ps?(m|d)1"
8383
- Inside `$PSCmdlet.ShouldProcess`-block, avoid using `Write-Verbose`
8484
- Never use backtick as line continuation in production code.
8585
- Set `$ErrorActionPreference = 'Stop'` before commands using `-ErrorAction 'Stop'`; restore previous value directly after invocation (do not use try-catch-finally)
86+
- Use `[Alias()]` attribute for function aliases, never `Set-Alias` or `New-Alias`
8687

8788
## Output streams
8889

@@ -92,7 +93,10 @@ applyTo: "**/*.ps?(m|d)1"
9293
- Use `Write-Information` for: User-facing status updates; Important operational messages; Non-error state changes
9394
- Use `Write-Warning` for: Non-fatal issues requiring attention; Deprecated functionality usage; Configuration problems that don't block execution
9495
- 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
96+
- Use `Write-Error` for non-terminating errors
97+
- Always include `-Message` (localized string), `-Category` (relevant error category), `-ErrorId` (unique ID matching localized string ID), `-TargetObject` (object causing error)
98+
- In catch blocks, pass original exception using `-Exception`
99+
- Always use `return` after `Write-Error` to avoid further processing
96100

97101
## ShouldProcess Required Pattern
98102

@@ -134,14 +138,25 @@ if ($Force.IsPresent -and -not $Confirm)
134138
Parameter description
135139
136140
.INPUTS
137-
TypeName
141+
TypeName1
138142
139-
Description
143+
Description1
144+
145+
.INPUTS
146+
TypeName2
147+
148+
Description2
140149
141150
.OUTPUTS
142-
TypeName
151+
TypeName1
152+
153+
Description1
154+
155+
.OUTPUTS
156+
TypeName2
157+
158+
Description2
143159
144-
Description
145160
#>
146161
function Get-Something
147162
{

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

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,11 @@ applyTo: "**"
1010
- **Function**: Private function
1111
- **Resource**: DSC class-based resource
1212

13-
## Build & Test Workflow
14-
- Run in PowerShell, from repository root
15-
- Build before running tests: `.\build.ps1 -Tasks build`
16-
- Always run tests in new PowerShell session: `Invoke-Pester -Path @({test paths}) -Output Detailed`
13+
## Build & Test Workflow Requirements
14+
- Run PowerShell script files from repository root
15+
- Setup build and test environment (once per `pwsh` session): `./build.ps1 -Tasks noop`
16+
- Build project before running tests: `./build.ps1 -Tasks build`
17+
- Always run tests in new `pwsh` session: `Invoke-Pester -Path @({test paths}) -Output Detailed`
1718

1819
## File Organization
1920
- Public commands: `source/Public/{CommandName}.ps1`

CHANGELOG.md

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
9292
`Remove-SqlDscRole`, and `Remove-SqlDscLogin` commands for retrieving and managing
9393
SQL Server logins and roles with support for refresh, pipeline input, and ShouldProcess.
9494
- Added `Get-SqlDscAgentAlert`, `New-SqlDscAgentAlert`,
95-
`Set-SqlDscAgentAlert`, `Remove-SqlDscAgentAlert`, and `Test-SqlDscAgentAlert`
95+
`Set-SqlDscAgentAlert`, `Remove-SqlDscAgentAlert`, and `Test-SqlDscIsAgentAlert`
9696
to manage SQL Agent alerts on a Database Engine instance.
9797
- Added new public commands for SQL Agent Operator management:
9898
- `Get-SqlDscAgentOperator` - Get SQL Agent Operators from a SQL Server
@@ -115,6 +115,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
115115
patterns
116116
- Database objects can also be used as pipeline input for Set and Remove operations
117117
- Commands include comprehensive validation, localization, and ShouldProcess support
118+
- `Test-SqlDscAgentAlertProperty`
119+
- New command to test specific properties of SQL Agent alerts.
120+
- Supports testing severity and message ID properties.
121+
- Requires at least one property parameter to be specified.
122+
- Supports pipeline input of
123+
`[Microsoft.SqlServer.Management.Smo.Agent.Alert]` objects.
118124
- Added private function `Get-CommandParameter` to filter command parameters
119125
by excluding specified parameter names and common parameters, providing a
120126
reusable way to determine settable properties on objects.
@@ -197,6 +203,17 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
197203
- `source/Examples/Resources/SqlSetup/5-InstallNamedInstanceInFailoverClusterSecondNode.ps1`
198204
- Removed redundant `$SqlAdministratorCredential` parameter from example
199205
configuration.
206+
- `New-SqlDscAgentAlert`
207+
- Updated the command to use `Test-SqlDscIsAgentAlert` instead of directly
208+
calling `Get-AgentAlertObject` when checking if an alert already exists
209+
(issue [#2202](https://github.com/dsccommunity/SqlServerDsc/issues/2202)).
210+
- `Test-SqlDscIsAgentAlert`
211+
- Removed optional `Severity` and `MessageId` parameters - use
212+
`Test-SqlDscAgentAlertProperty` instead for property testing.
213+
- Now only tests for alert existence.
214+
- Added support for pipeline input of
215+
`[Microsoft.SqlServer.Management.Smo.Agent.Alert]` objects.
216+
- Updated examples and documentation to reflect the simplified functionality.
200217

201218
## [17.1.0] - 2025-05-22
202219

RequiredModules.psd1

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,4 +66,7 @@
6666
}
6767
}
6868
PlatyPS = 'latest'
69+
70+
# For development
71+
'Viscalyx.Common' = 'latest' # Invoke-PesterJob to run tests
6972
}

azure-pipelines.yml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -316,7 +316,8 @@ stages:
316316
'tests/Integration/Commands/Get-SqlDscAgentAlert.Integration.Tests.ps1'
317317
'tests/Integration/Commands/New-SqlDscAgentAlert.Integration.Tests.ps1'
318318
'tests/Integration/Commands/Set-SqlDscAgentAlert.Integration.Tests.ps1'
319-
'tests/Integration/Commands/Test-SqlDscAgentAlert.Integration.Tests.ps1'
319+
'tests/Integration/Commands/Test-SqlDscAgentAlertProperty.Integration.Tests.ps1'
320+
'tests/Integration/Commands/Test-SqlDscIsAgentAlert.Integration.Tests.ps1'
320321
'tests/Integration/Commands/Get-SqlDscAgentOperator.Integration.Tests.ps1'
321322
'tests/Integration/Commands/New-SqlDscAgentOperator.Integration.Tests.ps1'
322323
'tests/Integration/Commands/Set-SqlDscAgentOperator.Integration.Tests.ps1'

source/Public/New-SqlDscAgentAlert.ps1

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -105,9 +105,9 @@ function New-SqlDscAgentAlert
105105
Assert-BoundParameter -BoundParameterList $PSBoundParameters -MutuallyExclusiveList1 @('Severity') -MutuallyExclusiveList2 @('MessageId')
106106

107107
# Check if alert already exists
108-
$existingAlert = Get-AgentAlertObject -ServerObject $ServerObject -Name $Name
108+
$alertExists = Test-SqlDscIsAgentAlert -ServerObject $ServerObject -Name $Name
109109

110-
if ($existingAlert)
110+
if ($alertExists)
111111
{
112112
$errorMessage = $script:localizedData.New_SqlDscAgentAlert_AlertAlreadyExists -f $Name
113113

Lines changed: 42 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,21 @@
11
<#
22
.SYNOPSIS
3-
Tests if a SQL Agent Alert exists and has the desired properties.
3+
Tests if a SQL Agent Alert has the specified properties.
44
55
.DESCRIPTION
6-
This command tests if a SQL Agent Alert exists on a SQL Server Database Engine
7-
instance and optionally validates its properties.
6+
This command tests if a SQL Agent Alert on a SQL Server Database Engine
7+
instance has the specified properties. At least one property parameter
8+
must be specified.
89
910
.PARAMETER ServerObject
1011
Specifies current server connection object.
1112
1213
.PARAMETER Name
1314
Specifies the name of the SQL Agent Alert to test.
1415
16+
.PARAMETER AlertObject
17+
Specifies the SQL Agent Alert object to test.
18+
1519
.PARAMETER Severity
1620
Specifies the expected severity level for the SQL Agent Alert. Valid range is 0 to 25.
1721
If specified, the command will return $true only if the alert exists and has this severity.
@@ -25,43 +29,52 @@
2529
2630
SQL Server Database Engine instance object.
2731
32+
.INPUTS
33+
Microsoft.SqlServer.Management.Smo.Agent.Alert
34+
35+
SQL Agent Alert object.
36+
2837
.OUTPUTS
2938
[System.Boolean]
3039
3140
.EXAMPLE
3241
$serverObject = Connect-SqlDscDatabaseEngine -InstanceName 'MyInstance'
33-
Test-SqlDscAgentAlert -ServerObject $serverObject -Name 'MyAlert'
42+
Test-SqlDscAgentAlertProperty -ServerObject $serverObject -Name 'MyAlert' -Severity 16
3443
35-
Tests if the SQL Agent Alert named 'MyAlert' exists.
44+
Tests if the SQL Agent Alert named 'MyAlert' exists and has severity level 16.
3645
3746
.EXAMPLE
3847
$serverObject = Connect-SqlDscDatabaseEngine -InstanceName 'MyInstance'
39-
$serverObject | Test-SqlDscAgentAlert -Name 'MyAlert' -Severity 16
48+
$serverObject | Test-SqlDscAgentAlertProperty -Name 'MyAlert' -MessageId 50001
4049
41-
Tests if the SQL Agent Alert named 'MyAlert' exists and has severity level 16.
50+
Tests if the SQL Agent Alert named 'MyAlert' exists and has message ID 50001.
4251
4352
.EXAMPLE
4453
$serverObject = Connect-SqlDscDatabaseEngine -InstanceName 'MyInstance'
45-
$serverObject | Test-SqlDscAgentAlert -Name 'MyAlert' -MessageId 50001
54+
$alertObject = $serverObject | Get-SqlDscAgentAlert -Name 'MyAlert'
55+
$alertObject | Test-SqlDscAgentAlertProperty -Severity 16
4656
47-
Tests if the SQL Agent Alert named 'MyAlert' exists and has message ID 50001.
57+
Tests if the SQL Agent Alert has severity level 16 using alert object pipeline input.
4858
#>
49-
function Test-SqlDscAgentAlert
59+
function Test-SqlDscAgentAlertProperty
5060
{
5161
[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.')]
52-
[CmdletBinding()]
62+
[CmdletBinding(DefaultParameterSetName = 'ByServerAndName')]
5363
[OutputType([System.Boolean])]
5464
param
5565
(
56-
[Parameter(Mandatory = $true, ValueFromPipeline = $true)]
66+
[Parameter(ParameterSetName = 'ByServerAndName', Mandatory = $true, ValueFromPipeline = $true)]
5767
[Microsoft.SqlServer.Management.Smo.Server]
5868
$ServerObject,
5969

60-
[Parameter(Mandatory = $true)]
61-
[ValidateNotNullOrEmpty()]
70+
[Parameter(ParameterSetName = 'ByServerAndName', Mandatory = $true)]
6271
[System.String]
6372
$Name,
6473

74+
[Parameter(ParameterSetName = 'ByAlertObject', Mandatory = $true, ValueFromPipeline = $true)]
75+
[Microsoft.SqlServer.Management.Smo.Agent.Alert]
76+
$AlertObject,
77+
6578
[Parameter()]
6679
[ValidateRange(0, 25)]
6780
[System.Int32]
@@ -73,65 +86,51 @@ function Test-SqlDscAgentAlert
7386
$MessageId
7487
)
7588

76-
# cSpell: ignore TSAA
89+
# cSpell: ignore TSAAP
7790
process
7891
{
92+
# Ensure at least one property parameter is specified
93+
Assert-BoundParameter -BoundParameterList $PSBoundParameters -AtLeastOneList @('Severity', 'MessageId')
94+
7995
# Validate that both Severity and MessageId are not specified
8096
Assert-BoundParameter -BoundParameterList $PSBoundParameters -MutuallyExclusiveList1 @('Severity') -MutuallyExclusiveList2 @('MessageId')
8197

82-
Write-Verbose -Message ($script:localizedData.Test_SqlDscAgentAlert_TestingAlert -f $Name)
83-
84-
$alertObject = Get-AgentAlertObject -ServerObject $ServerObject -Name $Name
85-
86-
if ($null -eq $alertObject)
98+
if ($PSCmdlet.ParameterSetName -eq 'ByAlertObject')
8799
{
88-
Write-Verbose -Message ($script:localizedData.Test_SqlDscAgentAlert_AlertNotFound -f $Name)
89-
90-
return $false
100+
$alertObject = $AlertObject
91101
}
102+
else
103+
{
104+
$alertObject = Get-AgentAlertObject -ServerObject $ServerObject -Name $Name
92105

93-
Write-Verbose -Message ($script:localizedData.Test_SqlDscAgentAlert_AlertFound -f $Name)
106+
if ($null -eq $alertObject)
107+
{
108+
$errorMessage = $script:localizedData.Test_SqlDscAgentAlertProperty_AlertNotFound -f $Name
94109

95-
# If no specific properties are specified, just return true (alert exists)
96-
if (-not $PSBoundParameters.ContainsKey('Severity') -and -not $PSBoundParameters.ContainsKey('MessageId'))
97-
{
98-
Write-Verbose -Message ($script:localizedData.Test_SqlDscAgentAlert_NoPropertyTest)
110+
Write-Error -Message $errorMessage -Category 'ObjectNotFound' -ErrorId 'TSDAAP0001' -TargetObject $Name
99111

100-
return $true
112+
return $false
113+
}
101114
}
102115

103116
# Test severity if specified
104117
if ($PSBoundParameters.ContainsKey('Severity'))
105118
{
106119
if ($alertObject.Severity -ne $Severity)
107120
{
108-
Write-Verbose -Message ($script:localizedData.Test_SqlDscAgentAlert_SeverityMismatch -f $alertObject.Severity, $Severity)
109-
110121
return $false
111122
}
112-
else
113-
{
114-
Write-Verbose -Message ($script:localizedData.Test_SqlDscAgentAlert_SeverityMatch -f $Severity)
115-
}
116123
}
117124

118125
# Test message ID if specified
119126
if ($PSBoundParameters.ContainsKey('MessageId'))
120127
{
121128
if ($alertObject.MessageId -ne $MessageId)
122129
{
123-
Write-Verbose -Message ($script:localizedData.Test_SqlDscAgentAlert_MessageIdMismatch -f $alertObject.MessageId, $MessageId)
124-
125130
return $false
126131
}
127-
else
128-
{
129-
Write-Verbose -Message ($script:localizedData.Test_SqlDscAgentAlert_MessageIdMatch -f $MessageId)
130-
}
131132
}
132133

133-
Write-Verbose -Message ($script:localizedData.Test_SqlDscAgentAlert_AllTestsPassed -f $Name)
134-
135134
return $true
136135
}
137136
}

0 commit comments

Comments
 (0)