Skip to content

SqlAgentAlert: Refactor to class-bases resource#2150

Merged
johlju merged 37 commits intodsccommunity:mainfrom
johlju:f/refactor-sqlagentalert-resource
Aug 29, 2025
Merged

SqlAgentAlert: Refactor to class-bases resource#2150
johlju merged 37 commits intodsccommunity:mainfrom
johlju:f/refactor-sqlagentalert-resource

Conversation

@johlju
Copy link
Member

@johlju johlju commented Aug 24, 2025

Pull Request (PR) description

  • SqlAgentAlert
    • Refactored DSC resource to manage SQL Server Agent alerts.

This Pull Request (PR) fixes the following issues

None.

Task list

  • Added an entry to the change log under the Unreleased section of the
    file CHANGELOG.md. Entry should say what was changed and how that
    affects users (if applicable), and reference the issue being resolved
    (if applicable).
  • Resource documentation updated in the resource's README.md.
  • Resource parameter descriptions updated in schema.mof.
  • Comment-based help updated, including parameter descriptions.
  • Localization strings updated.
  • Examples updated.
  • Unit tests updated. See DSC Community Testing Guidelines.
  • Integration tests updated (where possible). See DSC Community Testing Guidelines.
  • Code changes adheres to DSC Community Style Guidelines.

This change is Reviewable

@johlju johlju requested a review from a team as a code owner August 24, 2025 13:05
@coderabbitai
Copy link

coderabbitai bot commented Aug 24, 2025

Walkthrough

Adds a new class-based SqlAgentAlert DSC resource and en‑US resource strings, removes the legacy MOF/psm1-based DSC_SqlAgentAlert implementation and its README/localization and tests, introduces SMO test stubs and new class-based unit/integration tests (including MessageId flow), and updates multiple contributor/style guideline and project instruction files and the changelog.

Changes

Cohort / File(s) Summary
Class-based SqlAgentAlert resource
source/Classes/020.SqlAgentAlert.ps1, source/en-US/SqlAgentAlert.strings.psd1, CHANGELOG.md
Adds SqlAgentAlert : SqlResourceBase class (properties: Name, Ensure, Severity, MessageId; ctor; Get(), Test(), Set()), en‑US resource strings for the class, and documents the resource in CHANGELOG.
Removal of legacy MOF/psm1 resource
source/DSCResources/DSC_SqlAgentAlert/DSC_SqlAgentAlert.psm1, source/DSCResources/DSC_SqlAgentAlert/DSC_SqlAgentAlert.schema.mof, source/DSCResources/DSC_SqlAgentAlert/README.md, source/DSCResources/DSC_SqlAgentAlert/en-US/DSC_SqlAgentAlert.strings.psd1
Deletes the legacy MOF/psm1-based DSC_SqlAgentAlert implementation, its schema MOF, README, and en‑US localization PSD1 (removing previous Get/Set/Test functions and schema).
Unit tests and SMO stubs (new)
tests/Unit/Classes/SqlAgentAlert.Tests.ps1, tests/Unit/Stubs/SMO.cs
Adds Pester unit tests for the new class (constructor, properties, Get/Test/Set, AssertProperties) and introduces C# SMO stub types under Microsoft.SqlServer.Management.Smo.Agent (Alert, AlertCollection, JobServer, enums) used by tests.
Removal of legacy unit tests
tests/Unit/DSC_SqlAgentAlert.Tests.ps1
Removes legacy Pester tests for the MOF/psm1-based DSC_SqlAgentAlert resource.
Integration tests / config (MessageId flow)
tests/Integration/Resources/DSC_SqlAgentAlert.Integration.Tests.ps1, tests/Integration/Resources/DSC_SqlAgentAlert.config.ps1
Adds ChangeToMessageId_Config path and config to create custom sys.messages, updates assertions to conditionally validate MessageId vs Severity, and adds cleanup for custom messages.
Guidelines & project docs
.github/instructions/SqlServerDsc-guidelines.instructions.md, .github/instructions/dsc-community-style-guidelines-class-resource.instructions.md, .github/instructions/dsc-community-style-guidelines-pester.instructions.md, .github/instructions/dsc-community-style-guidelines-powershell.instructions.md, .github/instructions/dsc-community-style-guidelines-integration-tests.instructions.md, .github/instructions/dsc-community-style-guidelines-localization.instructions.md, .github/instructions/dsc-community-style-guidelines-unit-tests.instructions.md, .github/copilot-instructions.md, .github/instructions/dsc-community-style-guidelines-changelog.instructions.md
Edits and additions to contributor/style/testing instructions: SMO test guidance, nullable-type/constructor/comment-help patterns, error/output-stream guidance, Pester naming/structure rules, module-name/localization placeholders, build/test workflow, and changelog formatting.
Localization and test strings (new)
source/en-US/SqlAgentAlert.strings.psd1
Adds en‑US resource string mappings used by the new class-based resource.
Misc / editor settings
.vscode/settings.json
Adds RAISERROR to cSpell word list.

Sequence Diagram(s)

sequenceDiagram
  autonumber
  actor LCM as DSC Engine (LCM)
  participant Res as SqlAgentAlert (class)
  participant Cmd as Helper Cmdlets
  participant SQL as SQL Server (SMO)

  rect rgba(230,240,255,0.35)
    note right of Res: Get()
    LCM->>Res: Get()
    Res->>Cmd: Get-SqlDscAgentAlert(Name, Instance)
    Cmd->>SQL: Query Alerts
    SQL-->>Cmd: Alert or null
    Cmd-->>Res: Alert or null
    Res-->>LCM: Current state (Ensure, Severity/MessageId)
  end

  rect rgba(240,255,230,0.35)
    note right of Res: Test()
    LCM->>Res: Test()
    Res->>Cmd: Get-SqlDscAgentAlert(...)
    Cmd-->>Res: Alert or null
    Res-->>LCM: InDesiredState (bool)
  end

  rect rgba(255,245,230,0.35)
    note right of Res: Set()
    LCM->>Res: Set()
    Res->>Res: AssertProperties()
    alt Ensure = Present and not exists
      Res->>Cmd: New-SqlDscAgentAlert(...)
      Cmd->>SQL: Create Alert
      SQL-->>Cmd: Created
    else Ensure = Present and exists with diff
      Res->>Cmd: Set-SqlDscAgentAlert(...)
      Cmd->>SQL: Update Alert
      SQL-->>Cmd: Updated
    else Ensure = Absent and exists
      Res->>Cmd: Remove-SqlDscAgentAlert(...)
      Cmd->>SQL: Drop Alert
      SQL-->>Cmd: Removed
    else No changes
      Res-->>LCM: No-op
    end
    Res-->>LCM: Completed
  end
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

Tip

🔌 Remote MCP (Model Context Protocol) integration is now available!

Pro plan users can now connect to remote MCP servers from the Integrations page. Connect with popular remote MCPs such as Notion and Linear to add more context to your reviews and chats.


📜 Recent review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

💡 Knowledge Base configuration:

  • Jira integration is disabled
  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 87fec7e and 2f86af9.

📒 Files selected for processing (1)
  • tests/Unit/Classes/SqlAgentAlert.Tests.ps1 (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • tests/Unit/Classes/SqlAgentAlert.Tests.ps1
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
  • GitHub Check: dsccommunity.SqlServerDsc (Build Package Module)
  • GitHub Check: PSScriptAnalyzer
  • GitHub Check: PSScriptAnalyzer
✨ Finishing Touches
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbit in a new review comment at the desired location with your query.
  • PR comments: Tag @coderabbit in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbit gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbit read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

CodeRabbit Commands (Invoked using PR/Issue comments)

Type @coderabbit help to get the list of available commands.

Other keywords and placeholders

  • Add @coderabbit ignore or @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbit summary or @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbit or @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Status, Documentation and Community

  • Visit our Status Page to check the current availability of CodeRabbit.
  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

@codecov
Copy link

codecov bot commented Aug 24, 2025

Codecov Report

❌ Patch coverage is 97.29730% with 2 lines in your changes missing coverage. Please review.
✅ Project coverage is 94%. Comparing base (6488425) to head (2f86af9).
⚠️ Report is 2 commits behind head on main.

Files with missing lines Patch % Lines
source/Classes/020.SqlAgentAlert.ps1 97% 2 Missing ⚠️
Additional details and impacted files

Impacted file tree graph

@@         Coverage Diff          @@
##           main   #2150   +/-   ##
====================================
- Coverage    94%     94%   -1%     
====================================
  Files       122     122           
  Lines      8382    8355   -27     
====================================
- Hits       7939    7910   -29     
- Misses      443     445    +2     
Flag Coverage Δ
unit 94% <97%> (-1%) ⬇️
Files with missing lines Coverage Δ
source/Classes/020.SqlAgentAlert.ps1 97% <97%> (ø)
🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@johlju
Copy link
Member Author

johlju commented Aug 25, 2025

@coderabbitai review

@coderabbitai
Copy link

coderabbitai bot commented Aug 25, 2025

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
.github/instructions/dsc-community-style-guidelines-class-resource.instructions.md (1)

80-95: *Error-handling directive is incorrect for classes; you must throw the New-Exception.

The text says “Do not use throw… use New-*Exception,” but New-*Exception
returns an Exception you still need to throw in class methods (no $PSCmdlet
context). Provide the correct pattern and a short example. Also add blank lines around headings/lists to satisfy MD022/MD032, and wrap long lines (MD013).

Apply:

-## Error Handling
-- Use `try/catch` blocks to handle exceptions
-- Do not use `throw` for terminating errors, use `New-*Exception` commands:
+## Error Handling
+
+- Use `try/catch` blocks to handle exceptions.
+- In class methods, throw the exception created by the helper:
+  `throw (New-InvalidOperationException -Message $msg)`
+- In functions (non-class), prefer `$PSCmdlet.ThrowTerminatingError()`
+  when available.
+- Use the following helpers to create exceptions:
   - [`New‑InvalidDataException`](https://github.com/dsccommunity/DscResource.Common/wiki/New%E2%80%91InvalidDataException)
   - [`New-ArgumentException`](https://github.com/dsccommunity/DscResource.Common/wiki/New%E2%80%91ArgumentException)
   - [`New-InvalidOperationException`](https://github.com/dsccommunity/DscResource.Common/wiki/New%E2%80%91InvalidOperationException)
   - [`New-ObjectNotFoundException`](https://github.com/dsccommunity/DscResource.Common/wiki/New%E2%80%91ObjectNotFoundException)
   - [`New-InvalidResultException`](https://github.com/dsccommunity/DscResource.Common/wiki/New%E2%80%91InvalidResultException)
   - [`New-NotImplementedException`](https://github.com/dsccommunity/DscResource.Common/wiki/New%E2%80%91NotImplementedException)
+
+Example:
+
+```powershell
+try
+{
+    # state change
+}
+catch
+{
+    $msg = $this.localizedData.Modify_Failed -f $_.Exception.Message
+    throw (New-InvalidOperationException -Message $msg -ErrorRecord $_)
+}
+```
🧹 Nitpick comments (6)
CHANGELOG.md (1)

21-22: Optional: call out the refactor/removal of the legacy MOF-based resource for clarity.

Past entries (e.g., SqlRSSetup) explicitly note when a MOF-based resource was refactored to a class-based resource. Consider adding a short bullet under “Changed” to set user expectations about the replacement and removal.

Proposed wording:

 ### Changed
+ - `SqlAgentAlert`
+   - Refactored to a class-based DSC resource, replacing the legacy MOF-based resource `DSC_SqlAgentAlert`.
.github/instructions/dsc-community-style-guidelines-powershell.instructions.md (1)

76-79: Clarify the “required pattern” for ShouldProcess and fix long-line lint (MD013).

The bullet “$PSCmdlet.ShouldProcess must use required pattern” is ambiguous; also line length was flagged at 80+ chars by markdownlint. Recommend spelling out the exact pattern with a brief example and wrapping to ≤80 chars.

Apply:

-  - `$PSCmdlet.ShouldProcess` must use required pattern
+  - Use the standard pattern:
+    `if ($PSCmdlet.ShouldProcess($Target, $Action)) { <state-change> }`
+    Example:
+    ```powershell
+    $target = "$ServerName\$InstanceName"
+    $action = 'Create SQL Agent alert'
+    if ($PSCmdlet.ShouldProcess($target, $action))
+    {
+        $null = $server.JobServer.Alerts.Add($alert)
+        $alert.Alter()
+    }
+    ```
- - Use `$PSCmdlet.ThrowTerminatingError()` for terminating errors (except for classes), use relevant error category
+ - Use `$PSCmdlet.ThrowTerminatingError()` for terminating errors
+   (except for classes). Choose the most relevant error category.
.github/instructions/dsc-community-style-guidelines-pester.instructions.md (1)

32-38: Tighten guidance around ModuleName handling and minor grammar nits.

“Omit -ModuleName parameter on Pester commands” is only safe once default
ModuleName values are set. Make that conditional to prevent tests from binding to the wrong module. Also, adjust wording slightly for clarity.

Apply:

- - Omit `-ModuleName` parameter on Pester commands
+ - Omit the `-ModuleName` parameter on Pester commands only when
+   `$PSDefaultParameterValues` sets defaults for
+   `Mock:ModuleName`, `Should:ModuleName`, and `InModuleScope:ModuleName`.
+   Otherwise, specify `-ModuleName` explicitly.
- - Never use `Mock` inside `InModuleScope`-block
+ - Never use `Mock` inside an `InModuleScope` block
.github/instructions/dsc-community-style-guidelines-class-resource.instructions.md (2)

15-15: Clarify nullable usage (value types only).

PowerShell class properties need [Nullable[T]] only for value types (e.g., [int]).
Reference types (e.g., [string]) are already nullable. Spell this out to avoid overusing Nullable.

Apply:

- - Properties must have nullable types (`[Nullable[{Type}]]` where needed)
+ - Properties for value types that can be omitted must use nullable types
+   (`[Nullable[T]]`, e.g., `[Nullable[int]]`). Do not wrap reference types
+   like `[string]` in `Nullable` as they are already nullable.

80-85: Markdown spacing: add blank lines around lists and wrap long lines.

Lint flagged MD022/MD032/MD013 in this section. The previous diff adds blank lines and wraps long links; ensure the rest of the section remains within 80 characters per line.

.github/instructions/SqlServerDsc-guidelines.instructions.md (1)

32-38: Fix heading spacing, grammar, and line length (MD022/MD032/MD013).

Add a blank line before the “Unit tests” heading and around the list, rephrase the lead-in, and keep lines ≤80 chars. Also clarify the session note.

Apply:

- - Choose the appropriate group number based on the required dependencies
-
-## Unit tests
-- When unit test tests classes or commands that contain SMO types, e.g. `[Microsoft.SqlServer.Management.Smo.*]`
-  - Ensure they are properly stubbed in SMO.cs
-  - Load SMO stub types from SMO.cs in unit test files, e.g. `Add-Type -Path "$PSScriptRoot/../Stubs/SMO.cs"`
-  - After changing SMO stub types, run tests in a new PowerShell session for changes to take effect.
+ - Choose the appropriate group number based on the required dependencies
+
+## Unit tests
+
+- When unit tests target classes or commands that reference SMO types
+  (e.g., `[Microsoft.SqlServer.Management.Smo.*]`):
+  - Ensure the types are stubbed in `tests/Unit/Stubs/SMO.cs`.
+  - Load the stubs in the test file:
+    `Add-Type -Path "$PSScriptRoot/../Stubs/SMO.cs"`.
+  - After modifying `SMO.cs`, run tests in a new PowerShell session so the
+    updated types are loaded.
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

💡 Knowledge Base configuration:

  • Jira integration is disabled
  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 8eaf645 and 6a50a57.

📒 Files selected for processing (13)
  • .github/instructions/SqlServerDsc-guidelines.instructions.md (1 hunks)
  • .github/instructions/dsc-community-style-guidelines-class-resource.instructions.md (2 hunks)
  • .github/instructions/dsc-community-style-guidelines-pester.instructions.md (1 hunks)
  • .github/instructions/dsc-community-style-guidelines-powershell.instructions.md (1 hunks)
  • CHANGELOG.md (1 hunks)
  • source/Classes/020.SqlAgentAlert.ps1 (1 hunks)
  • source/DSCResources/DSC_SqlAgentAlert/DSC_SqlAgentAlert.psm1 (0 hunks)
  • source/DSCResources/DSC_SqlAgentAlert/DSC_SqlAgentAlert.schema.mof (0 hunks)
  • source/DSCResources/DSC_SqlAgentAlert/README.md (0 hunks)
  • source/DSCResources/DSC_SqlAgentAlert/en-US/DSC_SqlAgentAlert.strings.psd1 (0 hunks)
  • source/en-US/SqlAgentAlert.strings.psd1 (1 hunks)
  • tests/Unit/Classes/SqlAgentAlert.Tests.ps1 (1 hunks)
  • tests/Unit/Stubs/SMO.cs (1 hunks)
💤 Files with no reviewable changes (4)
  • source/DSCResources/DSC_SqlAgentAlert/README.md
  • source/DSCResources/DSC_SqlAgentAlert/DSC_SqlAgentAlert.schema.mof
  • source/DSCResources/DSC_SqlAgentAlert/en-US/DSC_SqlAgentAlert.strings.psd1
  • source/DSCResources/DSC_SqlAgentAlert/DSC_SqlAgentAlert.psm1
🧰 Additional context used
📓 Path-based instructions (7)
**

⚙️ CodeRabbit configuration file

**: # DSC Community Guidelines

Terminology

  • Command: Public command
  • Function: Private function
  • Resource: DSC class-based resource

Build & Test Workflow

  • Run project scripts in PowerShell from repository root
  • Build after source changes: .\build.ps1 -Tasks build
  • Test workflow: Build → Invoke-Pester -Path @('<test paths>') -Output Detailed
  • New session required after class changes

File Organization

  • Public commands: source/Public/{CommandName}.ps1
  • Private functions: source/Private/{FunctionName}.ps1
  • Unit tests: tests/Unit/{Classes|Public|Private}/{Name}.Tests.ps1
  • Integration tests: tests/Integration/Commands/{CommandName}.Integration.Tests.ps1

Requirements

  • Always update CHANGELOG.md Unreleased section
  • Localize all strings using string keys
  • Check DscResource.Common before creating private functions
  • Separate reusable logic into private functions
  • Add unit tests for all commands/functions/resources
  • Add integration tests for all public commands and resources

Files:

  • source/en-US/SqlAgentAlert.strings.psd1
  • tests/Unit/Classes/SqlAgentAlert.Tests.ps1
  • CHANGELOG.md
  • tests/Unit/Stubs/SMO.cs
  • source/Classes/020.SqlAgentAlert.ps1
**/*.ps?(m|d)1

⚙️ CodeRabbit configuration file

**/*.ps?(m|d)1: # PowerShell Guidelines

Naming

  • Use descriptive names (3+ characters, no abbreviations)
  • Functions: PascalCase with Verb-Noun format using approved verbs
  • Parameters: PascalCase
  • Variables: camelCase
  • Keywords: lower-case
  • Classes: PascalCase
  • Include scope for script/global/environment variables: $script:, $global:, $env:

Formatting

Indentation & Spacing

  • Use 4 spaces (no tabs)
  • One space around operators: $a = 1 + 2
  • One space between type and variable: [String] $name
  • One space between keyword and parenthesis: if ($condition)
  • No spaces on empty lines
  • Try to limit lines to 120 characters

Braces

  • Newline before opening brace (except variable assignments)
  • One newline after opening brace
  • Two newlines after closing brace (one if followed by another brace or continuation)

Quotes

  • Use single quotes unless variable expansion is needed: 'text' vs "text $variable"

Arrays

  • Single line: @('one', 'two', 'three')
  • Multi-line: each element on separate line with proper indentation
  • Do not use the unary comma operator (,) in return statements to force
    an array

Hashtables

  • Empty: @{}
  • Multi-line: each property on separate line with proper indentation
  • Properties: Use PascalCase

Comments

  • Single line: # Comment (capitalized, on own line)
  • Multi-line: <# Comment #> format (opening and closing brackets on own line), and indent text
  • No commented-out code

Comment-based help

  • Always add comment-based help to all functions and scripts
  • Comment-based help: SYNOPSIS, DESCRIPTION (40+ chars), PARAMETER, EXAMPLE sections before function/class
  • Comment-based help indentation: keywords 4 spaces, text 8 spaces
  • Include examples for all parameter sets and combinations
  • INPUTS: List each pipeline‑accepted type (one per line) with a 1‑line description.
  • OUTPUTS: List each return type (one per line) with a 1‑line description. Must match both [OutputType()] and actual ...

Files:

  • source/en-US/SqlAgentAlert.strings.psd1
  • tests/Unit/Classes/SqlAgentAlert.Tests.ps1
  • source/Classes/020.SqlAgentAlert.ps1
**/*.[Tt]ests.ps1

⚙️ CodeRabbit configuration file

**/*.[Tt]ests.ps1: # Tests Guidelines

Core Requirements

  • All public commands, private functions and classes must have unit tests
  • All public commands and class-based resources must have integration tests
  • Use Pester v5 syntax only
  • One Describe block per file matching the tested entity name
  • Test code only inside Describe blocks
  • Assertions only in It blocks
  • Never test Write-Verbose, Write-Debug, or parameter binding behavior
  • Pass all mandatory parameters to avoid prompts

Structure & Scope

  • Public commands: Never use InModuleScope (unless retrieving localized strings)
  • Private functions/class resources: Always use InModuleScope
  • Each scenario = separate Context block
  • Use nested Context blocks for complex scenarios
  • Mocking in BeforeAll (BeforeEach only when required)
  • Setup/teardown in BeforeAll,BeforeEach/AfterAll,AfterEach close to usage

Syntax Rules

  • PascalCase: Describe, Context, It, Should, BeforeAll, BeforeEach, AfterAll, AfterEach
  • It descriptions start with 'Should'
  • Context descriptions start with 'When'
  • Mock variables prefix: 'mock'
  • Prefer -BeTrue/-BeFalse over -Be $true/-Be $false
  • No Should -Not -Throw - invoke commands directly

File Organization

  • Class resources: tests/Unit/Classes/{Name}.Tests.ps1
  • Public commands: tests/Unit/Public/{Name}.Tests.ps1
  • Private functions: tests/Unit/Private/{Name}.Tests.ps1

Data-Driven Tests

  • Define variables in separate BeforeDiscovery for -ForEach (close to usage)
  • -ForEach allowed on Context and It blocks
  • Keep scope close to usage context

Best Practices

  • Assign unused return objects to $null
  • Tested entity must be called from within the It blocks
  • Keep results and assertions in same It block
  • Cover all scenarios and code paths
  • Use BeforeEach and AfterEach sparingly
  • Avoid try-catch-finally for cleanup, use AfterAll or AfterEach
  • Avoid unnecessary remove/recreate cyc...

Files:

  • tests/Unit/Classes/SqlAgentAlert.Tests.ps1
**/*.md

⚙️ CodeRabbit configuration file

**/*.md: # Markdown Style Guidelines

  • Wrap lines at word boundaries when over 80 characters (except tables/code blocks)
  • Use 2 spaces for indentation
  • Use '1.' for all items in ordered lists (1/1/1 numbering style)
  • Disable MD013 rule by adding a comment for tables/code blocks exceeding 80 characters
  • Empty lines required before/after code blocks and headings (except before line 1)
  • Code blocks must specify language identifiers

Text Formatting

  • Parameters: bold
  • Values/literals: inline code
  • Resource/module/product names: italic
  • Commands/files/paths: inline code

Files:

  • CHANGELOG.md
CHANGELOG.md

⚙️ CodeRabbit configuration file

CHANGELOG.md: # Changelog Guidelines

  • Always update the Unreleased section in CHANGELOG.md
  • Use Keep a Changelog format
  • Describe notable changes briefly, ≤2 items per change type
  • Reference issues using format #<issue_number>
  • No empty lines between list items in same section
  • Do not add item if there are already an existing item for the same change

Files:

  • CHANGELOG.md
source/**/*.ps1

⚙️ CodeRabbit configuration file

source/**/*.ps1: # Localization Guidelines

Requirements

  • Localize all Write-Debug, Write-Verbose, Write-Error, Write-Warning and $PSCmdlet.ThrowTerminatingError() messages
  • Use localized string keys, not hardcoded strings
  • Assume $script:localizedData is available

String Files

  • Commands/functions: source/en-US/SqlServerDsc.strings.psd1
  • Class resources: source/en-US/{ResourceClassName}.strings.psd1

Key Naming

  • Format: FunctionName_Description (underscore separators)
  • Example: Get_SqlDscDatabase_ConnectingToDatabase

String Format

ConvertFrom-StringData @'
    KeyName = Message with {0} placeholder. (PREFIX0001)
'@

String IDs

  • Format: (PREFIX####)
  • PREFIX: First letter of each word in class or function name (SqlSetup → SS, Get-SqlDscDatabase → GSDD)
  • Number: Sequential from 0001

Usage

Write-Verbose -Message ($script:localizedData.KeyName -f $value1)

Files:

  • source/Classes/020.SqlAgentAlert.ps1
source/[cC]lasses/**/*.ps1

⚙️ CodeRabbit configuration file

source/[cC]lasses/**/*.ps1: # DSC Class-Based Resource Guidelines

Applies to: Classes with [DscResource(...)] decoration only.

Requirements

  • File: source/Classes/{ResourceName}.ps1
  • Decoration: [DscResource(RunAsCredential = 'Optional')] (replace with 'Mandatory' if required)
  • Inheritance: Must inherit ResourceBase (part of module DscResource.Base)
  • $this.localizedData hashtable auto-populated by ResourceBase from localization file

Required Method Pattern

[MyResourceName] Get()
{
    $currentState = ([ResourceBase] $this).Get()

    # If needed, post-processing based on returned current state before returning to user

    return $currentState
}

[System.Boolean] Test()
{
    $inDesiredState = ([ResourceBase] $this).Test()

    # If needed, post-processing based on returned test result before returning to user

    return $inDesiredState
}

[void] Set()
{
    ([ResourceBase] $this).Set()

    # If needed, additional state changes that could not be handled by Modify()
}

hidden [System.Collections.Hashtable] GetCurrentState([System.Collections.Hashtable] $properties)
{
    # Return current state as hashtable
    # Variable $properties contains the key properties (key-value pairs).
}

hidden [void] Modify([System.Collections.Hashtable] $properties)
{
    # Set desired state for non-compliant properties only
    # Variable $properties contains the properties (key-value pairs) that are not in desired state.
}

hidden [void] AssertProperties([System.Collections.Hashtable] $properties)
{
    # Validate user-provided properties
    # Variable $properties contains properties user assigned values.
}

hidden [void] NormalizeProperties([System.Collections.Hashtable] $properties)
{
    # Normalize user-provided properties
    # Variable $properties contains properties user assigned values.
}

Files:

  • source/Classes/020.SqlAgentAlert.ps1
🧠 Learnings (36)
📓 Common learnings
Learnt from: CR
PR: dsccommunity/SqlServerDsc#0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-08-17T09:48:55.756Z
Learning: Applies to source/Classes/*.ps1 : A DSC resource should inherit SqlResourceBase if it needs to connect to a SQL Server Database Engine
📚 Learning: 2025-08-17T09:48:55.756Z
Learnt from: CR
PR: dsccommunity/SqlServerDsc#0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-08-17T09:48:55.756Z
Learning: Applies to tests/**/*.ps1 : All tests must use Pester and Pester v5.0 syntax

Applied to files:

  • .github/instructions/dsc-community-style-guidelines-pester.instructions.md
  • .github/instructions/SqlServerDsc-guidelines.instructions.md
📚 Learning: 2025-08-17T09:48:55.756Z
Learnt from: CR
PR: dsccommunity/SqlServerDsc#0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-08-17T09:48:55.756Z
Learning: Applies to tests/Unit/**/*.Tests.ps1 : Never test, mock, or use Should -Invoke for Write-Verbose or Write-Debug in unit tests

Applied to files:

  • .github/instructions/dsc-community-style-guidelines-pester.instructions.md
  • .github/instructions/dsc-community-style-guidelines-powershell.instructions.md
📚 Learning: 2025-08-17T09:48:55.756Z
Learnt from: CR
PR: dsccommunity/SqlServerDsc#0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-08-17T09:48:55.756Z
Learning: Applies to tests/**/*.ps1 : Each scenario/path should be in Context blocks starting with 'When'; It block descriptions should start with 'Should' and must call the subject; results and assertions stay within the same It; BeforeAll/BeforeEach must not call the subject

Applied to files:

  • .github/instructions/dsc-community-style-guidelines-pester.instructions.md
  • .github/instructions/SqlServerDsc-guidelines.instructions.md
📚 Learning: 2025-08-17T09:48:55.756Z
Learnt from: CR
PR: dsccommunity/SqlServerDsc#0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-08-17T09:48:55.756Z
Learning: Applies to tests/**/*.ps1 : Use BeforeAll/BeforeEach/AfterAll/AfterEach inside Context, placed near the It blocks using them; duplication across contexts is acceptable; AfterAll can clean up; use BeforeEach/AfterEach sparingly

Applied to files:

  • .github/instructions/dsc-community-style-guidelines-pester.instructions.md
📚 Learning: 2025-08-17T09:48:55.756Z
Learnt from: CR
PR: dsccommunity/SqlServerDsc#0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-08-17T09:48:55.756Z
Learning: Applies to tests/Unit/Classes/*.Tests.ps1 : Unit tests for class-based resources must be placed in tests/Unit/Classes and named <Resource>.Tests.ps1

Applied to files:

  • .github/instructions/dsc-community-style-guidelines-pester.instructions.md
  • .github/instructions/SqlServerDsc-guidelines.instructions.md
  • tests/Unit/Classes/SqlAgentAlert.Tests.ps1
📚 Learning: 2025-08-17T09:48:55.756Z
Learnt from: CR
PR: dsccommunity/SqlServerDsc#0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-08-17T09:48:55.756Z
Learning: Applies to tests/**/*.ps1 : Files that need to be mocked in tests must be created in Pester's $TestDrive

Applied to files:

  • .github/instructions/dsc-community-style-guidelines-pester.instructions.md
  • .github/instructions/SqlServerDsc-guidelines.instructions.md
📚 Learning: 2025-08-17T09:48:55.756Z
Learnt from: CR
PR: dsccommunity/SqlServerDsc#0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-08-17T09:48:55.756Z
Learning: Applies to tests/Integration/Commands/*.Integration.Tests.ps1 : Integration tests must exist for all public commands, not mock any commands, be placed at tests/Integration/Commands, and be named <Command>.Integration.Tests.ps1

Applied to files:

  • .github/instructions/dsc-community-style-guidelines-pester.instructions.md
  • .github/instructions/SqlServerDsc-guidelines.instructions.md
📚 Learning: 2025-08-17T10:15:48.194Z
Learnt from: johlju
PR: dsccommunity/SqlServerDsc#2136
File: tests/Unit/Public/Remove-SqlDscLogin.Tests.ps1:36-39
Timestamp: 2025-08-17T10:15:48.194Z
Learning: Public command unit tests guideline: Never use InModuleScope unless accessing localized strings from $script:localizedData. PSDefaultParameterValues for InModuleScope should be kept in public command tests to support localized string retrieval when necessary.

Applied to files:

  • .github/instructions/dsc-community-style-guidelines-pester.instructions.md
📚 Learning: 2025-08-17T09:48:55.756Z
Learnt from: CR
PR: dsccommunity/SqlServerDsc#0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-08-17T09:48:55.756Z
Learning: Applies to tests/Unit/**/*.Tests.ps1 : Do not use Should -Not -Throw; invoke the command directly

Applied to files:

  • .github/instructions/dsc-community-style-guidelines-pester.instructions.md
📚 Learning: 2025-08-17T09:48:55.756Z
Learnt from: CR
PR: dsccommunity/SqlServerDsc#0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-08-17T09:48:55.756Z
Learning: Applies to tests/**/*.ps1 : Each test file must contain exactly one Describe block named after the subject (public command, private function, or resource)

Applied to files:

  • .github/instructions/dsc-community-style-guidelines-pester.instructions.md
📚 Learning: 2025-08-17T09:48:55.756Z
Learnt from: CR
PR: dsccommunity/SqlServerDsc#0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-08-17T09:48:55.756Z
Learning: Applies to source/{Public,Private}/*.ps1 : Use Write-Verbose for action messages; Write-Debug for internal decision messages; Write-Error for errors; Write-Warning for warnings; Write-Information for informational messages

Applied to files:

  • .github/instructions/dsc-community-style-guidelines-powershell.instructions.md
📚 Learning: 2025-08-18T10:44:38.990Z
Learnt from: johlju
PR: dsccommunity/SqlServerDsc#2132
File: source/Public/New-SqlDscLogin.ps1:254-257
Timestamp: 2025-08-18T10:44:38.990Z
Learning: When implementing Force and Confirm parameter interaction in PowerShell functions with SupportsShouldProcess, use the pattern `if ($Force.IsPresent -and -not $Confirm)` to suppress confirmations. This ensures that explicit `-Confirm:$true` is respected even when `-Force` is present, preserving user intent when they explicitly request confirmation alongside Force.

Applied to files:

  • .github/instructions/dsc-community-style-guidelines-powershell.instructions.md
📚 Learning: 2025-08-17T09:48:55.756Z
Learnt from: CR
PR: dsccommunity/SqlServerDsc#0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-08-17T09:48:55.756Z
Learning: Applies to source/{Public,Private}/*.ps1 : Public command and private function names must follow Verb-Noun format and use PowerShell approved verbs

Applied to files:

  • .github/instructions/dsc-community-style-guidelines-powershell.instructions.md
📚 Learning: 2025-08-17T09:48:55.756Z
Learnt from: CR
PR: dsccommunity/SqlServerDsc#0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-08-17T09:48:55.756Z
Learning: Applies to source/Private/*.ps1 : Private functions must localize Write-Debug/Verbose/Error/Warning and other messages using keys from source/en-US/SqlServerDsc.strings.psd1; keys prefixed with function name using underscores; data available as $script:localizedData

Applied to files:

  • .github/instructions/dsc-community-style-guidelines-powershell.instructions.md
📚 Learning: 2025-08-17T09:48:55.756Z
Learnt from: CR
PR: dsccommunity/SqlServerDsc#0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-08-17T09:48:55.756Z
Learning: Applies to source/Public/*.ps1 : Public commands must localize Write-Debug/Verbose/Error/Warning and other messages using keys from source/en-US/SqlServerDsc.strings.psd1; keys prefixed with function name using underscores; data available as $script:localizedData

Applied to files:

  • .github/instructions/dsc-community-style-guidelines-powershell.instructions.md
  • source/en-US/SqlAgentAlert.strings.psd1
📚 Learning: 2025-08-17T09:48:55.756Z
Learnt from: CR
PR: dsccommunity/SqlServerDsc#0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-08-17T09:48:55.756Z
Learning: Applies to source/{Public,Private,Classes}/*.ps1 : Use PascalCase for function names and parameters in public commands, private functions, and class-based resources

Applied to files:

  • .github/instructions/dsc-community-style-guidelines-powershell.instructions.md
📚 Learning: 2025-08-17T09:48:55.756Z
Learnt from: CR
PR: dsccommunity/SqlServerDsc#0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-08-17T09:48:55.756Z
Learning: Applies to **/*.ps1 : Use descriptive, clear, full names for variables, parameters, and function names; names must be more than 2 characters; no abbreviations

Applied to files:

  • .github/instructions/dsc-community-style-guidelines-powershell.instructions.md
📚 Learning: 2025-08-17T09:48:55.756Z
Learnt from: CR
PR: dsccommunity/SqlServerDsc#0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-08-17T09:48:55.756Z
Learning: Applies to source/en-US/SqlServerDsc.strings.psd1 : All localized strings for public commands and private functions must be added to source/en-US/SqlServerDsc.strings.psd1 following existing key patterns

Applied to files:

  • source/en-US/SqlAgentAlert.strings.psd1
📚 Learning: 2025-08-17T09:48:55.756Z
Learnt from: CR
PR: dsccommunity/SqlServerDsc#0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-08-17T09:48:55.756Z
Learning: Applies to source/en-US/*.strings.psd1 : Each class-based resource must have a strings file in source/en-US named exactly <ResourceClassName>.strings.psd1; keys use underscores as word separator

Applied to files:

  • source/en-US/SqlAgentAlert.strings.psd1
📚 Learning: 2025-08-17T10:13:30.079Z
Learnt from: johlju
PR: dsccommunity/SqlServerDsc#2136
File: source/Public/Remove-SqlDscLogin.ps1:104-108
Timestamp: 2025-08-17T10:13:30.079Z
Learning: In SqlServerDsc unit tests, SMO object stubs (like Login objects) should have properly mocked Parent properties with correct Server stub types and valid InstanceName values, rather than handling null Parent scenarios in production code.

Applied to files:

  • .github/instructions/SqlServerDsc-guidelines.instructions.md
  • tests/Unit/Stubs/SMO.cs
📚 Learning: 2025-08-17T09:48:55.756Z
Learnt from: CR
PR: dsccommunity/SqlServerDsc#0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-08-17T09:48:55.756Z
Learning: Applies to azure-pipelines.yml : Add each public command integration test script to a group within the Integration_Test_Commands_SqlServer stage in ./azure-pipelines.yml, choosing the appropriate group

Applied to files:

  • .github/instructions/SqlServerDsc-guidelines.instructions.md
📚 Learning: 2025-08-17T09:48:55.756Z
Learnt from: CR
PR: dsccommunity/SqlServerDsc#0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-08-17T09:48:55.756Z
Learning: Applies to tests/Unit/Public/*.Tests.ps1 : Unit tests for public commands must be placed in tests/Unit/Public and named <Command>.Tests.ps1

Applied to files:

  • .github/instructions/SqlServerDsc-guidelines.instructions.md
📚 Learning: 2025-08-17T09:48:55.756Z
Learnt from: CR
PR: dsccommunity/SqlServerDsc#0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-08-17T09:48:55.756Z
Learning: Applies to tests/Unit/Private/*.Tests.ps1 : Unit tests for private functions must be placed in tests/Unit/Private and named <Function>.Tests.ps1

Applied to files:

  • .github/instructions/SqlServerDsc-guidelines.instructions.md
📚 Learning: 2025-08-17T09:48:55.756Z
Learnt from: CR
PR: dsccommunity/SqlServerDsc#0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-08-17T09:48:55.756Z
Learning: Applies to tests/Unit/Public/*.Tests.ps1 : Public command unit tests must include tests to validate parameter properties (e.g., Mandatory, ValueFromPipeline)

Applied to files:

  • .github/instructions/SqlServerDsc-guidelines.instructions.md
📚 Learning: 2025-08-17T09:48:55.756Z
Learnt from: CR
PR: dsccommunity/SqlServerDsc#0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-08-17T09:48:55.756Z
Learning: Applies to tests/Integration/Commands/*.Integration.Tests.ps1 : Include the standard integration test setup block (BeforeDiscovery/BeforeAll with module loading) before the first Describe block

Applied to files:

  • .github/instructions/SqlServerDsc-guidelines.instructions.md
📚 Learning: 2025-08-18T13:50:53.789Z
Learnt from: johlju
PR: dsccommunity/SqlServerDsc#2132
File: tests/Unit/Public/New-SqlDscLogin.Tests.ps1:0-0
Timestamp: 2025-08-18T13:50:53.789Z
Learning: In SqlServerDsc unit tests, SMO stub objects can be used to verify method calls like Create() on Login objects by adding mock verifications with Should -Invoke, providing more robust testing than just checking for no exceptions.

Applied to files:

  • tests/Unit/Classes/SqlAgentAlert.Tests.ps1
📚 Learning: 2025-08-17T09:48:55.756Z
Learnt from: CR
PR: dsccommunity/SqlServerDsc#0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-08-17T09:48:55.756Z
Learning: Applies to source/Classes/*.ps1 : Derived DSC resource classes must override Get, Test, Set, GetCurrentState, Modify, AssertProperties, NormalizeProperties following the provided pattern

Applied to files:

  • tests/Unit/Classes/SqlAgentAlert.Tests.ps1
  • .github/instructions/dsc-community-style-guidelines-class-resource.instructions.md
📚 Learning: 2025-08-17T09:48:55.756Z
Learnt from: CR
PR: dsccommunity/SqlServerDsc#0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-08-17T09:48:55.756Z
Learning: Applies to source/Classes/*.ps1 : A DSC resource should inherit SqlResourceBase if it needs to connect to a SQL Server Database Engine

Applied to files:

  • source/Classes/020.SqlAgentAlert.ps1
  • .github/instructions/dsc-community-style-guidelines-class-resource.instructions.md
📚 Learning: 2025-08-17T09:48:55.756Z
Learnt from: CR
PR: dsccommunity/SqlServerDsc#0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-08-17T09:48:55.756Z
Learning: Applies to source/Classes/*.ps1 : A DSC resource should inherit ResourceBase only when it cannot inherit SqlResourceBase or when not related to SQL Server Database Engine

Applied to files:

  • source/Classes/020.SqlAgentAlert.ps1
  • .github/instructions/dsc-community-style-guidelines-class-resource.instructions.md
📚 Learning: 2025-08-17T09:48:55.756Z
Learnt from: CR
PR: dsccommunity/SqlServerDsc#0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-08-17T09:48:55.756Z
Learning: Applies to source/Classes/*.ps1 : Derived DSC resource classes must use [DscResource(RunAsCredential = 'Optional')]

Applied to files:

  • .github/instructions/dsc-community-style-guidelines-class-resource.instructions.md
📚 Learning: 2025-08-17T09:48:55.756Z
Learnt from: CR
PR: dsccommunity/SqlServerDsc#0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-08-17T09:48:55.756Z
Learning: Applies to source/Classes/*.ps1 : Derived DSC resource classes must inherit from a parent class

Applied to files:

  • .github/instructions/dsc-community-style-guidelines-class-resource.instructions.md
📚 Learning: 2025-08-17T09:48:55.756Z
Learnt from: CR
PR: dsccommunity/SqlServerDsc#0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-08-17T09:48:55.756Z
Learning: Applies to source/Classes/*.ps1 : Class-based resources must use localized strings available via $this.localizedData

Applied to files:

  • .github/instructions/dsc-community-style-guidelines-class-resource.instructions.md
📚 Learning: 2025-08-17T09:48:55.756Z
Learnt from: CR
PR: dsccommunity/SqlServerDsc#0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-08-17T09:48:55.756Z
Learning: Applies to source/Classes/*.ps1 : Each DSC class-based resource must be in its own script file named exactly as the resource class and located in source/Classes

Applied to files:

  • .github/instructions/dsc-community-style-guidelines-class-resource.instructions.md
📚 Learning: 2025-08-17T09:48:55.756Z
Learnt from: CR
PR: dsccommunity/SqlServerDsc#0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-08-17T09:48:55.756Z
Learning: Applies to source/{Public,Private,Classes}/*.ps1 : Comment-based help .DESCRIPTION text must be descriptive and > 40 characters; .SYNOPSIS should be short; include at least one example

Applied to files:

  • .github/instructions/dsc-community-style-guidelines-class-resource.instructions.md
📚 Learning: 2025-08-17T09:48:55.756Z
Learnt from: CR
PR: dsccommunity/SqlServerDsc#0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-08-17T09:48:55.756Z
Learning: Applies to source/{Public,Private,Classes}/*.ps1 : Comment-based help must precede each function/class with a comment block using at least .SYNOPSIS, .DESCRIPTION, .PARAMETER, .EXAMPLE, .NOTES

Applied to files:

  • .github/instructions/dsc-community-style-guidelines-class-resource.instructions.md
🪛 LanguageTool
.github/instructions/dsc-community-style-guidelines-pester.instructions.md

[grammar] ~36-~36: There might be a mistake here.
Context: ...Mock:ModuleName, Should:ModuleName, InModuleScope:ModuleName - Omit -ModuleName parameter on Pester c...

(QB_NEW_EN)

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

[grammar] ~33-~33: There might be a mistake here.
Context: ...the required dependencies ## Unit tests - When unit test tests classes or commands...

(QB_NEW_EN)


[grammar] ~37-~37: There might be a mistake here.
Context: ...hell session for changes to take effect.

(QB_NEW_EN)

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

[grammar] ~82-~82: There might be a mistake here.
Context: ...based help Add to .DESCRIPTION section: - ## Requirements: List minimum requirements - `## Known ...

(QB_NEW_EN)


[grammar] ~83-~83: There might be a mistake here.
Context: ...Requirements: List minimum requirements - ## Known issues: Critical issues + pattern: All issues...

(QB_NEW_EN)


[grammar] ~86-~86: There might be a mistake here.
Context: ...tle+{ResourceName}). ## Error Handling - Usetry/catch` blocks to handle excepti...

(QB_NEW_EN)

🪛 markdownlint-cli2 (0.17.2)
.github/instructions/dsc-community-style-guidelines-powershell.instructions.md

78-78: Line length
Expected: 80; Actual: 114

(MD013, line-length)

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

33-33: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below

(MD022, blanks-around-headings)


34-34: Lists should be surrounded by blank lines

(MD032, blanks-around-lists)


37-37: Line length
Expected: 80; Actual: 100

(MD013, line-length)

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

83-83: Lists should be surrounded by blank lines

(MD032, blanks-around-lists)


84-84: Line length
Expected: 80; Actual: 195

(MD013, line-length)


86-86: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below

(MD022, blanks-around-headings)


87-87: Lists should be surrounded by blank lines

(MD032, blanks-around-lists)

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (5)
  • GitHub Check: dsccommunity.SqlServerDsc (Quality Test and Unit Test Publish Code Coverage)
  • GitHub Check: dsccommunity.SqlServerDsc (Quality Test and Unit Test Unit)
  • GitHub Check: dsccommunity.SqlServerDsc (Quality Test and Unit Test Determine DSC Resource Test Requirements)
  • GitHub Check: dsccommunity.SqlServerDsc (Quality Test and Unit Test HQRM)
  • GitHub Check: dsccommunity.SqlServerDsc (Build Package Module)
🔇 Additional comments (20)
CHANGELOG.md (1)

21-22: SqlAgentAlert entry reads well and follows the repo’s changelog conventions.

The new item is concise, under “Added,” and uses backticks for the resource name consistently with prior entries. LGTM.

source/en-US/SqlAgentAlert.strings.psd1 (1)

1-16: LGTM! The localization strings are well-structured and follow proper conventions.

The string key naming follows the correct pattern (ResourceName_Description) and each string includes appropriate formatting placeholders and unique identifiers (SAAA0002-SAAA0009). The strings provide clear, actionable messages for all SQL Agent Alert operations.

source/Classes/020.SqlAgentAlert.ps1 (7)

115-116: LGTM! Proper DSC resource decoration and inheritance.

The class correctly inherits from SqlResourceBase (appropriate for SQL Server Database Engine resources) and uses the proper DSC decoration with optional RunAsCredential support.


118-135: LGTM! Property declarations are correct and well-documented.

The properties follow the proper DSC patterns with appropriate validation ranges and nullable types for optional parameters. The parameter documentation in the comment-based help is comprehensive and accurate.


137-141: LGTM! Constructor follows the required pattern.

The constructor properly calls the base constructor and initializes ExcludeDscProperties as required by the guidelines.


143-163: LGTM! DSC methods follow the required pattern.

All three DSC methods (Get, Test, Set) correctly delegate to the base implementation as required by the DSC class-based resource guidelines.


165-169: LGTM! Property validation is correctly implemented.

The AssertProperties method properly enforces mutual exclusivity between Severity and MessageId parameters using the standard Assert-BoundParameter function.


171-209: LGTM! Current state retrieval is well-implemented.

The GetCurrentState method correctly:

  • Retrieves the server object
  • Uses localized verbose messages
  • Builds the appropriate state hashtable
  • Handles both existing and non-existing alerts
  • Properly handles optional severity and message ID properties

211-281: LGTM! State modification logic is robust and well-structured.

The Modify method correctly handles all scenarios:

  • Creates new alerts with proper parameter handling
  • Updates existing alerts only when necessary
  • Removes alerts when Ensure is Absent
  • Uses appropriate error handling with -ErrorAction 'Stop'
  • Provides clear verbose logging throughout

The logic for determining whether an update is needed (lines 250-271) is particularly well-done, avoiding unnecessary operations.

tests/Unit/Classes/SqlAgentAlert.Tests.ps1 (7)

5-25: LGTM! Proper dependency resolution and error handling.

The BeforeDiscovery block correctly handles the DscResource.Test dependency with appropriate error handling and clear error messages.


27-53: LGTM! Test setup and teardown follow best practices.

The setup properly loads SMO stubs, imports the module, configures default parameters, and sets the CI environment variable. The teardown correctly cleans up all configurations.


55-126: LGTM! Comprehensive constructor and property testing.

The tests thoroughly validate:

  • Constructor behavior (no exceptions, proper instantiation)
  • All property setters and getters
  • Proper type checking

128-183: LGTM! Get() method testing covers key scenarios.

The tests properly validate both scenarios (alert exists/doesn't exist) with appropriate mocking and assertions. The use of Add-Member to mock the GetServerObject method is a good testing pattern.


185-240: LGTM! Test() method testing validates core functionality.

The tests cover the essential scenarios for the Test method with proper state setup and assertions.


242-310: LGTM! Set() method testing with proper mock verification.

The tests correctly validate that the appropriate commands are called using Should -Invoke, which provides robust verification as noted in the learning context. The test structure properly separates different scenarios with nested contexts.


312-382: LGTM! Comprehensive AssertProperties validation testing.

The tests thoroughly cover all validation scenarios:

  • Error when both Severity and MessageId are specified
  • No error for valid combinations
  • Proper error message validation using wildcard matching
tests/Unit/Stubs/SMO.cs (4)

1474-1505: LGTM! Proper enum definitions for SQL Agent Alert types.

The enums AlertType and CompletionAction are correctly defined with appropriate values and comprehensive documentation indicating their usage in various test files.


1510-1534: LGTM! JobServer class stub is properly implemented.

The JobServer class includes all necessary properties and follows the established pattern with factory method and proper parent relationship to the Server class.


1536-1574: LGTM! AlertCollection implements proper collection behavior.

The AlertCollection class correctly:

  • Implements ICollection interface
  • Provides proper indexer access by name and index
  • Includes necessary collection methods (Add, Remove, etc.)
  • Uses a dictionary internally for efficient lookups
  • Follows the established factory pattern

1576-1625: LGTM! Alert class provides comprehensive property coverage.

The Alert class includes all necessary properties for SQL Agent alerts:

  • Proper constructors with JobServer parameter
  • Comprehensive property set covering all alert attributes
  • Standard SMO methods (Create, Drop, Alter)
  • Follows the established stub pattern with factory method

@johlju johlju force-pushed the f/refactor-sqlagentalert-resource branch from 6a50a57 to 4d5b237 Compare August 25, 2025 10:07
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

♻️ Duplicate comments (2)
.github/instructions/dsc-community-style-guidelines-class-resource.instructions.md (2)

22-23: Typos and example realism

“IsSingelInstance” → “IsSingleInstance”; also add the missing period after “e.g.”

-    # Property names where state cannot be enforced, e.g. IsSingelInstance
+    # Property names where state cannot be enforced, e.g. IsSingleInstance.

17-25: Duplicate and conflicting “Required constructor” sections — consolidate and align with current base() pattern

There are two “Required constructor” sections: one uses : base (), the other : base ($PSScriptRoot). Pick one canonical pattern and remove the duplicate. This doc should match current resources (e.g., SqlAgentAlert uses base ()).

-## Required constructor
-
-```powershell
-MyResourceName () : base ()
-{
-    # Property names where state cannot be enforced, e.g. IsSingelInstance
-    $this.ExcludeDscProperties = @()
-}
-```
-
-## Required constructor
+## Required constructor
 
 ```powershell
-MyResourceName () : base ($PSScriptRoot)
+MyResourceName () : base ()
 {
-    # Property names where state cannot be enforced, e.g Ensure
+    # Property names where state cannot be enforced, e.g. IsSingleInstance
     $this.ExcludeDscProperties = @()
 }


Also applies to: 27-35

</blockquote></details>

</blockquote></details>

<details>
<summary>🧹 Nitpick comments (17)</summary><blockquote>

<details>
<summary>.github/instructions/dsc-community-style-guidelines-pester.instructions.md (1)</summary><blockquote>

`38-38`: **Clarify “Never use Mock inside InModuleScope” and show the intended pattern**

As written, this can be interpreted as “don’t mock when testing classes,” which is not the intent. The intent (per our learnings) is to define mocks outside InModuleScope and let them flow in via PSDefaultParameterValues, not to avoid mocking entirely.


Apply something like:

```diff
- Never use `Mock` inside `InModuleScope`-block
+ Never define `Mock` inside an `InModuleScope` block.
+ 
+ Define all `Mock` in `BeforeAll` (or `BeforeEach` only when required) outside `InModuleScope`.
+ Let mocks flow into `InModuleScope` via `$PSDefaultParameterValues` (see rule below).
+
+ Example:
+ ```powershell
+ BeforeAll {
+     $PSDefaultParameterValues['Mock:ModuleName'] = 'SqlServerDsc'
+     Mock -CommandName Get-Something -ModuleName SqlServerDsc -MockWith { 'stub' }
+ }
+ 
+ InModuleScope SqlServerDsc {
+     It 'Should invoke Get-Something' {
+         # call SUT
+         Invoke-Thing
+         Should -Invoke Get-Something -Times 1
+     }
+ }
+ ```
.github/instructions/SqlServerDsc-guidelines.instructions.md (1)

37-40: Tighten grammar, wrap for md rules, and make the guidance unambiguous

Minor editorial polish and formatting to satisfy MD013/MD032 and improve clarity.

-## Unit tests
-- When unit test tests classes or commands that contain SMO types, e.g. `[Microsoft.SqlServer.Management.Smo.*]`
-  - Ensure they are properly stubbed in SMO.cs
-  - Load SMO stub types from SMO.cs in unit test files, e.g. `Add-Type -Path "$PSScriptRoot/../Stubs/SMO.cs"`
-  - After changing SMO stub types, run tests in a new PowerShell session for changes to take effect.
+## Unit tests
+
+- When a unit test exercises classes or commands that use SMO types
+  (for example `[Microsoft.SqlServer.Management.Smo.*]`):
+  - Ensure the types are stubbed in `SMO.cs`.
+  - Load the SMO stub types in the unit test files:
+    ```powershell
+    Add-Type -Path "$PSScriptRoot/../Stubs/SMO.cs"
+    ```
+  - After changing SMO stubs, run tests in a new PowerShell session
+    for changes to take effect.
.github/instructions/dsc-community-style-guidelines-powershell.instructions.md (1)

82-82: LGTM; consider wrapping to satisfy MD013

Substance is correct (functions use ThrowTerminatingError; classes follow class-resource guidance). Optionally wrap at ~80 chars to quiet markdownlint.

- Use `$PSCmdlet.ThrowTerminatingError()` for terminating errors (except for classes), use relevant error category
+ Use `$PSCmdlet.ThrowTerminatingError()` for terminating errors
+ (except for classes); use a relevant error category.
.github/instructions/dsc-community-style-guidelines-class-resource.instructions.md (2)

15-16: Fix nullable-type syntax and clarify scope (“where needed”)

PowerShell type notation should be [Nullable[System.Int32]] (or [System.Nullable[System.Int32]]). Also, “must” is too strong; some properties aren’t nullable.

-- Properties must have nullable types (`[Nullable[{Type}]]` where needed)
+- Use nullable types where appropriate
+  (for example `[Nullable[System.Int32]]`).

93-99: Improve wording and formatting of required comment-based help section

Make the wording imperative, add blank lines around lists, and ensure the link text is clear.

-## Required comment-based help
-
-Add to .DESCRIPTION section:
-- `## Requirements`: List minimum requirements
-- `## Known issues`: Critical issues + pattern: `All issues are not listed here, see [all open issues](https://github.com/{owner}/{repo}/issues?q=is%3Aissue+is%3Aopen+in%3Atitle+{ResourceName}).`
+## Required comment-based help
+
+Add the following subsections to `.DESCRIPTION`:
+
+- `## Requirements`: List minimum requirements.
+- `## Known issues`: Summarize critical issues and add:
+  “All issues are not listed here. See all open issues for {ResourceName}.”
+  Link to:
+  `https://github.com/{owner}/{repo}/issues?q=is%3Aissue+is%3Aopen+in%3Atitle+{ResourceName}`.
source/Classes/020.SqlAgentAlert.ps1 (4)

10-14: Polish description grammar (“It also possible…”)

Minor doc grammar fix for clarity.

-        The built-in parameter **PSDscRunAsCredential** can be used to run the resource
-        as another user. The resource will then authenticate to the _SQL Server_
-        instance as that user. It also possible to instead use impersonation by the
-        parameter **Credential**.
+        The built-in parameter **PSDscRunAsCredential** can be used to run the
+        resource as another user. The resource will then authenticate to the
+        _SQL Server_ instance as that user. It is also possible to use
+        impersonation via the **Credential** parameter.

26-33: Fix wording in “Reasons does not work with PSDscRunAsCredential”

Tighten grammar and remove ambiguity.

-        When using the built-in parameter **PSDscRunAsCredential** the read-only
-        property **Reasons** will return empty values for the properties **Code**
-        and **Phrase**. The built-in property **PSDscRunAsCredential** does not work
-        together with class-based resources that using advanced type like the parameter
-        **Reasons** have.
+        When using **PSDscRunAsCredential**, the read-only property **Reasons**
+        will return empty values for **Code** and **Phrase**. This is a known
+        limitation when class-based resources expose advanced types like
+        **Reasons**.

36-46: Tighten wording in “Using Credential property” section

Minor agreement and phrasing fixes.

-        SQL Authentication and Group Managed Service Accounts is not supported as
-        impersonation credentials. Currently only Windows Integrated Security is
-        supported to use as credentials.
+        SQL authentication and Group Managed Service Accounts are not supported
+        as impersonation credentials. Currently only Windows Integrated Security
+        is supported.
@@
-        (for example a local Windows Server account) account the username must be
-        provided without the NetBIOS name, e.g. `username`. Using the NetBIOS name, e.g
-        using the format `DOMAIN\username` will not work.
+        (for example, a local Windows Server account) the username must be
+        provided without the NetBIOS name, e.g. `username`. Using the NetBIOS
+        format `DOMAIN\username` will not work.

192-201: Consistency: reflect zero-disallowed decision in state projection

If you adopt the proposed ValidateRange(1, …), keep -gt 0 as-is (it becomes consistent). If you allow 0, change to -ge 0.

-            if ($alertObject.Severity -gt 0)
+            if ($alertObject.Severity -gt 0)
             {
                 $currentState.Severity = $alertObject.Severity
             }
@@
-            if ($alertObject.MessageId -gt 0)
+            if ($alertObject.MessageId -gt 0)
             {
                 $currentState.MessageId = $alertObject.MessageId
             }

Note: No code change needed if you adopt the non-zero ranges above; this comment documents the coupling.

tests/Unit/Classes/SqlAgentAlert.Tests.ps1 (8)

57-62: Remove “Should -Not -Throw” constructor test (violates tests guideline, redundant)

Per the tests guidelines, do not use “Should -Not -Throw”; just invoke the code (any exception will fail the test). This specific test is also redundant with the next two constructor tests.

Apply this diff to remove it:

-        It 'Should not throw an exception' {
-            InModuleScope -ScriptBlock {
-                { [SqlAgentAlert]::new() } | Should -Not -Throw
-            }
-        }

70-75: Prefer BeOfType over stringly-typed type assertion

Use Pester’s BeOfType for a stricter type check.

-                $instance.GetType().Name | Should -Be 'SqlAgentAlert'
+                $instance | Should -BeOfType ([SqlAgentAlert])

139-160: Assert the Get() flow invokes Get-SqlDscAgentAlert exactly once

Strengthen the Get() tests by verifying the mock invocation count.

                 $result = $instance.Get()
 
                 $result | Should -Not -BeNullOrEmpty
                 $result.Name | Should -Be 'TestAlert'
                 $result.Ensure | Should -Be 'Present'
                 $result.Severity | Should -Be 16
+                Should -Invoke -CommandName 'Get-SqlDscAgentAlert' -Exactly -Times 1 -Scope It
                 $result = $instance.Get()
 
                 $result | Should -Not -BeNullOrEmpty
                 $result.Name | Should -Be 'TestAlert'
                 $result.Ensure | Should -Be 'Absent'
+                Should -Invoke -CommandName 'Get-SqlDscAgentAlert' -Exactly -Times 1 -Scope It

Also applies to: 162-183


185-240: Add missing Test() scenario for Ensure=Absent when alert exists

This complements existing cases and ensures negative-path coverage.

         It 'Should return false when alert does not exist but should be present' {
             InModuleScope -ScriptBlock {
                 Mock -CommandName 'Get-SqlDscAgentAlert' -MockWith {
                     return $null
                 }
 
                 $instance = [SqlAgentAlert] @{
                     Name         = 'TestAlert'
                     InstanceName = 'MSSQLSERVER'
                     Ensure       = 'Present'
                     Severity     = 16
                 } |
                     Add-Member -Force -MemberType 'ScriptMethod' -Name 'GetServerObject' -Value {
                         return $script:mockServerObject
                     } -PassThru
 
                 $result = $instance.Test()
 
                 $result | Should -BeFalse
             }
         }
+
+        It 'Should return false when alert exists but should be absent' {
+            InModuleScope -ScriptBlock {
+                $script:mockAlertObject = [pscustomobject]@{
+                    Name      = 'TestAlert'
+                    Severity  = 16
+                    MessageId = 0
+                }
+
+                Mock -CommandName 'Get-SqlDscAgentAlert' -MockWith {
+                    return $script:mockAlertObject
+                }
+
+                $instance = [SqlAgentAlert] @{
+                    Name         = 'TestAlert'
+                    InstanceName = 'MSSQLSERVER'
+                    Ensure       = 'Absent'
+                } |
+                    Add-Member -Force -MemberType 'ScriptMethod' -Name 'GetServerObject' -Value {
+                        return $script:mockServerObject
+                    } -PassThru
+
+                $result = $instance.Test()
+
+                $result | Should -BeFalse
+            }
+        }

266-270: Replace “Should -Not -Throw” around Set() with direct invocation

Complies with the tests guideline. You already assert side effects via Should -Invoke.

-                    { $instance.Set() } | Should -Not -Throw
+                    $null = $instance.Set()
 
                     Should -Invoke -CommandName 'New-SqlDscAgentAlert' -Exactly -Times 1 -Scope It
                     Should -Invoke -CommandName 'Remove-SqlDscAgentAlert' -Exactly -Times 0 -Scope It
-                    { $instance.Set() } | Should -Not -Throw
+                    $null = $instance.Set()
 
                     Should -Invoke -CommandName 'New-SqlDscAgentAlert' -Exactly -Times 0 -Scope It
                     Should -Invoke -CommandName 'Remove-SqlDscAgentAlert' -Exactly -Times 1 -Scope It

Also applies to: 303-307


329-337: Don’t use “Should -Not -Throw” in AssertProperties() tests

Invoke directly; any exception will fail the test, per guideline.

-                { $instance.AssertProperties($properties) } | Should -Not -Throw
+                $null = $instance.AssertProperties($properties)

Apply the same change to the other three “Should not throw …” tests in this context.

Also applies to: 341-352, 355-366, 369-379


131-136: Minor readability: build PSCustomObject in one expression

Nit: Using [pscustomobject] with a hashtable is more concise than multiple Add-Member calls.

Example:

$script:mockAlertObject = [pscustomobject]@{
    Name      = 'TestAlert'
    Severity  = 16
    MessageId = 0
}

Also applies to: 194-198, 280-286


70-76: Optional: Add inheritance assertion test for SqlAgentAlert

The SqlAgentAlert class does inherit from SqlResourceBase (verified at source/Classes/020.SqlAgentAlert.ps1:116) so it’s safe to add a unit test enforcing this repo-wide requirement for DB Engine DSC resources.

• File: tests/Unit/Classes/SqlAgentAlert.Tests.ps1
• Location: immediately after the existing “Should be the correct type” test

Suggested diff:

         It 'Should be the correct type' {
             InModuleScope -ScriptBlock {
-                $instance.GetType().Name | Should -Be 'SqlAgentAlert'
+                $instance | Should -BeOfType ([SqlAgentAlert])
             }
         }
+
+        It 'Should derive from SqlResourceBase' {
+            InModuleScope -ScriptBlock {
+                $instance = [SqlAgentAlert]::new()
+                $instance.GetType().BaseType.Name | Should -Be 'SqlResourceBase'
+            }
+        }

This reinforces the inheritance requirement without impacting existing functionality.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

💡 Knowledge Base configuration:

  • Jira integration is disabled
  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 6a50a57 and 4d5b237.

📒 Files selected for processing (13)
  • .github/instructions/SqlServerDsc-guidelines.instructions.md (1 hunks)
  • .github/instructions/dsc-community-style-guidelines-class-resource.instructions.md (2 hunks)
  • .github/instructions/dsc-community-style-guidelines-pester.instructions.md (1 hunks)
  • .github/instructions/dsc-community-style-guidelines-powershell.instructions.md (1 hunks)
  • CHANGELOG.md (1 hunks)
  • source/Classes/020.SqlAgentAlert.ps1 (1 hunks)
  • source/DSCResources/DSC_SqlAgentAlert/DSC_SqlAgentAlert.psm1 (0 hunks)
  • source/DSCResources/DSC_SqlAgentAlert/DSC_SqlAgentAlert.schema.mof (0 hunks)
  • source/DSCResources/DSC_SqlAgentAlert/README.md (0 hunks)
  • source/DSCResources/DSC_SqlAgentAlert/en-US/DSC_SqlAgentAlert.strings.psd1 (0 hunks)
  • source/en-US/SqlAgentAlert.strings.psd1 (1 hunks)
  • tests/Unit/Classes/SqlAgentAlert.Tests.ps1 (1 hunks)
  • tests/Unit/Stubs/SMO.cs (4 hunks)
💤 Files with no reviewable changes (4)
  • source/DSCResources/DSC_SqlAgentAlert/DSC_SqlAgentAlert.schema.mof
  • source/DSCResources/DSC_SqlAgentAlert/README.md
  • source/DSCResources/DSC_SqlAgentAlert/DSC_SqlAgentAlert.psm1
  • source/DSCResources/DSC_SqlAgentAlert/en-US/DSC_SqlAgentAlert.strings.psd1
🚧 Files skipped from review as they are similar to previous changes (3)
  • CHANGELOG.md
  • source/en-US/SqlAgentAlert.strings.psd1
  • tests/Unit/Stubs/SMO.cs
🧰 Additional context used
📓 Path-based instructions (13)
**/*.{ps1,psm1,psd1}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

Always follow PowerShell code style guidelines (./instructions/dsc-community-style-guidelines-powershell.instructions.md)

**/*.{ps1,psm1,psd1}: Use 4 spaces for indentation (no tabs)
One space around operators (e.g., $a = 1 + 2)
No spaces on empty lines
Try to limit lines to 120 characters
Use single quotes unless variable expansion is needed
Arrays single-line: @('one','two','three')
Arrays multi-line: each element on its own indented line
Hashtables empty literal uses @{}
Hashtables multi-line: each property on a separate indented line
Hashtable properties use PascalCase
Single-line comments use '# Comment' style: capitalized, on own line
Multi-line comments use <# #> with brackets on their own lines and indented text
End files with only one blank line
Use CR+LF line endings
Maximum of two consecutive newlines
Use UTF-8 encoding without BOM for all files

Files:

  • tests/Unit/Classes/SqlAgentAlert.Tests.ps1
  • source/Classes/020.SqlAgentAlert.ps1
**/*.{ps1,psm1}

📄 CodeRabbit inference engine (.github/instructions/SqlServerDsc-guidelines.instructions.md)

**/*.{ps1,psm1}: Public PowerShell commands must follow the naming format: Verb-SqlDsc{Noun}
Prefer SMO over T-SQL for SQL Server interaction

**/*.{ps1,psm1}: Use descriptive names (3+ characters, no abbreviations)
Function names use PascalCase with Verb-Noun format using approved verbs
Parameter names use PascalCase
Variable names use camelCase
Keywords should be lower-case
Include scope qualifier for script/global/environment variables: $script:, $global:, $env:
One space between type and variable (e.g., [String] $name)
One space between keyword and parenthesis (e.g., if ($condition))
Newline before opening brace (except variable assignments)
One newline after opening brace
Two newlines after closing brace (one if followed by another brace or continuation)
Do not use the unary comma operator in return statements to force an array
Do not keep commented-out code
Always add comment-based help to all functions and scripts
Comment-based help must include SYNOPSIS, DESCRIPTION (40+ chars), PARAMETER, EXAMPLE sections before function/class
Comment-based help indentation: keywords at 4 spaces, text at 8 spaces
Include examples for all parameter sets and combinations in help
INPUTS: list each pipeline-accepted type (one per line) with a 1‑line description
OUTPUTS: list each return type (one per line) with a 1‑line description; must match [OutputType()] and actual returns
.NOTES only when critical (constraints, side effects, security, version compatibility, breaking behavior), ≤2 short sentences
Avoid aliases; use full command names
Avoid Write-Host; prefer Write-Verbose/Write-Information, etc.
Avoid Write-Output; use 'return' instead
Avoid ConvertTo-SecureString -AsPlainText in production code
Do not redefine reserved parameters (Verbose, Debug, etc.)
Include a Force parameter for functions that support ShouldContinue or use ShouldProcess
For state-changing functions, set SupportsShouldProcess
Use $PSCmdlet.ThrowTerminatingError() for terminating errors with relevant ...

Files:

  • tests/Unit/Classes/SqlAgentAlert.Tests.ps1
  • source/Classes/020.SqlAgentAlert.ps1
tests/Unit/**/*.Tests.ps1

📄 CodeRabbit inference engine (.github/instructions/SqlServerDsc-guidelines.instructions.md)

tests/Unit/**/*.Tests.ps1: In unit tests, use SMO stub types defined in SMO.cs
In unit tests, do not mock SMO types directly
Unit tests must set $env:SqlServerDscCI = $true in BeforeAll and remove it in AfterAll

Files:

  • tests/Unit/Classes/SqlAgentAlert.Tests.ps1
**/*.[Tt]ests.ps1

📄 CodeRabbit inference engine (.github/instructions/dsc-community-style-guidelines-pester.instructions.md)

**/*.[Tt]ests.ps1: Use Pester v5 syntax only
Use exactly one Describe block per test file, named to match the tested entity
Place all test code only inside Describe blocks
Place assertions only inside It blocks
Do not test Write-Verbose, Write-Debug, or parameter binding behavior
Always pass all mandatory parameters in tests to avoid prompts
Each scenario should be a separate Context block
Use nested Context blocks for complex scenarios
Define mocks in BeforeAll (use BeforeEach for mocking only when required)
Place setup/teardown in the nearest appropriate BeforeAll/BeforeEach/AfterAll/AfterEach to where it is used
Use PascalCase for Pester keywords: Describe, Context, It, Should, BeforeAll, BeforeEach, AfterAll, AfterEach
Start It descriptions with 'Should'
Start Context descriptions with 'When'
Prefix mock variables with 'mock'
Prefer -BeTrue and -BeFalse over -Be $true and -Be $false
Do not use 'Should -Not -Throw'; invoke commands directly instead
For data-driven tests, define variables in a separate BeforeDiscovery for -ForEach close to usage
Use -ForEach only on Context and It blocks
Keep variable and mock scope as close as possible to the usage context
Assign unused return objects to $null
Invoke the tested entity from within It blocks only
Keep results and assertions within the same It block
Use BeforeEach and AfterEach sparingly
Avoid try/catch/finally for cleanup; use AfterAll or AfterEach instead

Files:

  • tests/Unit/Classes/SqlAgentAlert.Tests.ps1

⚙️ CodeRabbit configuration file

**/*.[Tt]ests.ps1: # Tests Guidelines

Core Requirements

  • All public commands, private functions and classes must have unit tests
  • All public commands and class-based resources must have integration tests
  • Use Pester v5 syntax only
  • One Describe block per file matching the tested entity name
  • Test code only inside Describe blocks
  • Assertions only in It blocks
  • Never test verbose messages, debug messages or parameter binding behavior
  • Pass all mandatory parameters to avoid prompts

Structure & Scope

  • Public commands: Never use InModuleScope (unless retrieving localized strings)
  • Private functions/class resources: Always use InModuleScope
  • Each scenario = separate Context block
  • Use nested Context blocks for complex scenarios
  • Mocking in BeforeAll (BeforeEach only when required)
  • Setup/teardown in BeforeAll,BeforeEach/AfterAll,AfterEach close to usage

Syntax Rules

  • PascalCase: Describe, Context, It, Should, BeforeAll, BeforeEach, AfterAll, AfterEach
  • Context descriptions start with 'When'
  • It descriptions start with 'Should', must not contain 'when'
  • Mock variables prefix: 'mock'
  • Prefer -BeTrue/-BeFalse over -Be $true/-Be $false
  • No Should -Not -Throw - invoke commands directly
  • Never add an empty -MockWith block
  • Omit -MockWith when returning $null
  • Set $PSDefaultParameterValues for Mock:ModuleName, Should:ModuleName, InModuleScope:ModuleName
  • Omit -ModuleName parameter on Pester commands

File Organization

  • Class resources: tests/Unit/Classes/{Name}.Tests.ps1
  • Public commands: tests/Unit/Public/{Name}.Tests.ps1
  • Private functions: tests/Unit/Private/{Name}.Tests.ps1

Data-Driven Tests

  • Define variables in separate BeforeDiscovery for -ForEach (close to usage)
  • -ForEach allowed on Context and It blocks
  • Keep scope close to usage context

Best Practices

  • Inside It blocks, assign unused return objects to $null (unless part of ...

Files:

  • tests/Unit/Classes/SqlAgentAlert.Tests.ps1
tests/Unit/{Private,Classes}/**/*.Tests.ps1

📄 CodeRabbit inference engine (.github/instructions/dsc-community-style-guidelines-pester.instructions.md)

For private functions and class resource tests, always use InModuleScope

Files:

  • tests/Unit/Classes/SqlAgentAlert.Tests.ps1
tests/Unit/Classes/*.Tests.ps1

📄 CodeRabbit inference engine (.github/instructions/dsc-community-style-guidelines-pester.instructions.md)

Place unit tests for class resources in tests/Unit/Classes/{Name}.Tests.ps1

Add unit tests for all resources (class-based)

Files:

  • tests/Unit/Classes/SqlAgentAlert.Tests.ps1
tests/{Unit,uUnit}/**/*.[Tt]ests.ps1

📄 CodeRabbit inference engine (.github/instructions/dsc-community-style-guidelines-unit-tests.instructions.md)

tests/{Unit,uUnit}/**/*.[Tt]ests.ps1: In Pester unit tests, access localized strings using InModuleScope -ScriptBlock { $script:localizedData.Key }
When mocking file operations in tests, use the $TestDrive variable for file paths
All public commands must include parameter set validation tests
Include the exact provided setup block (SuppressMessage attributes, BeforeDiscovery, BeforeAll, AfterAll) before each Describe in unit tests
For commands with a single parameter set, include a parameter set validation test using the provided It block template
For commands with multiple parameter sets, validate each set by supplying multiple hashtables to -ForEach in the parameter set validation test
Test parameter properties explicitly; e.g., assert that a parameter is Mandatory using (Get-Command).Parameters['Name'].Attributes.Mandatory | Should -BeTrue

Files:

  • tests/Unit/Classes/SqlAgentAlert.Tests.ps1
tests/Unit/{Classes,Public,Private}/*.Tests.ps1

📄 CodeRabbit inference engine (.github/instructions/dsc-community-style-guidelines.instructions.md)

Place unit tests in tests/Unit/{Classes|Public|Private}/{Name}.Tests.ps1

Files:

  • tests/Unit/Classes/SqlAgentAlert.Tests.ps1
**

⚙️ CodeRabbit configuration file

**: # DSC Community Guidelines

Terminology

  • Command: Public command
  • Function: Private function
  • Resource: DSC class-based resource

Build & Test Workflow

  • Run project scripts in PowerShell from repository root
  • Build after source changes: .\build.ps1 -Tasks build
  • Test workflow: Build → Invoke-Pester -Path @('<test paths>') -Output Detailed
  • New session required after class changes

File Organization

  • Public commands: source/Public/{CommandName}.ps1
  • Private functions: source/Private/{FunctionName}.ps1
  • Unit tests: tests/Unit/{Classes|Public|Private}/{Name}.Tests.ps1
  • Integration tests: tests/Integration/Commands/{CommandName}.Integration.Tests.ps1

Requirements

  • Follow guidelines over existing code patterns
  • Always update CHANGELOG.md Unreleased section
  • Localize all strings using string keys; remove any orphaned string keys
  • Check DscResource.Common before creating private functions
  • Separate reusable logic into private functions
  • Add unit tests for all commands/functions/resources
  • Add integration tests for all public commands and resources

Files:

  • tests/Unit/Classes/SqlAgentAlert.Tests.ps1
  • source/Classes/020.SqlAgentAlert.ps1
**/*.ps?(m|d)1

⚙️ CodeRabbit configuration file

**/*.ps?(m|d)1: # PowerShell Guidelines

Naming

  • Use descriptive names (3+ characters, no abbreviations)
  • Functions: PascalCase with Verb-Noun format using approved verbs
  • Parameters: PascalCase
  • Variables: camelCase
  • Keywords: lower-case
  • Classes: PascalCase
  • Include scope for script/global/environment variables: $script:, $global:, $env:

File naming

  • Class files: ###.ClassName.ps1 format (e.g. 001.SqlReason.ps1, 004.StartupParameters.ps1)

Formatting

Indentation & Spacing

  • Use 4 spaces (no tabs)
  • One space around operators: $a = 1 + 2
  • One space between type and variable: [String] $name
  • One space between keyword and parenthesis: if ($condition)
  • No spaces on empty lines
  • Try to limit lines to 120 characters

Braces

  • Newline before opening brace (except variable assignments)
  • One newline after opening brace
  • Two newlines after closing brace (one if followed by another brace or continuation)

Quotes

  • Use single quotes unless variable expansion is needed: 'text' vs "text $variable"

Arrays

  • Single line: @('one', 'two', 'three')
  • Multi-line: each element on separate line with proper indentation
  • Do not use the unary comma operator (,) in return statements to force
    an array

Hashtables

  • Empty: @{}
  • Multi-line: each property on separate line with proper indentation
  • Properties: Use PascalCase

Comments

  • Single line: # Comment (capitalized, on own line)
  • Multi-line: <# Comment #> format (opening and closing brackets on own line), and indent text
  • No commented-out code

Comment-based help

  • Always add comment-based help to all functions and scripts
  • Comment-based help: SYNOPSIS, DESCRIPTION (40+ chars), PARAMETER, EXAMPLE sections before function/class
  • Comment-based help indentation: keywords 4 spaces, text 8 spaces
  • Include examples for all parameter sets and combinations
  • INPUTS: List each pipeline‑accepted type (one per line) with a 1‑line description.
  • ...

Files:

  • tests/Unit/Classes/SqlAgentAlert.Tests.ps1
  • source/Classes/020.SqlAgentAlert.ps1
source/[cC]lasses/*.ps1

📄 CodeRabbit inference engine (.github/instructions/dsc-community-style-guidelines-class-resource.instructions.md)

Place each DSC class-based resource in source/Classes/{ResourceName}.ps1

Files:

  • source/Classes/020.SqlAgentAlert.ps1
source/[cC]lasses/**/*.ps1

📄 CodeRabbit inference engine (.github/instructions/dsc-community-style-guidelines-class-resource.instructions.md)

source/[cC]lasses/**/*.ps1: Decorate the resource class with [DscResource(RunAsCredential = 'Optional')] (use 'Mandatory' if required)
Only classes with a [DscResource(...)] decoration are considered DSC resources to which these rules apply
Resource classes must inherit ResourceBase (from the DscResource.Base module)
Use $this.localizedData provided by ResourceBase (auto-populated from the localization file); do not manually populate it
Implement Get() that delegates to ([ResourceBase] $this).Get(), optionally post-processes, and returns the current state object
Implement Test() that delegates to ([ResourceBase] $this).Test(), optionally post-processes, and returns a [System.Boolean]
Implement Set() that delegates to ([ResourceBase] $this).Set(), with optional additional changes not handled by Modify()
Implement hidden [System.Collections.Hashtable] GetCurrentState([System.Collections.Hashtable] $properties) to return current state
Implement hidden [void] Modify([System.Collections.Hashtable] $properties) to set desired state only for non-compliant properties
Implement hidden [void] AssertProperties([System.Collections.Hashtable] $properties) to validate user-provided properties
Implement hidden [void] NormalizeProperties([System.Collections.Hashtable] $properties) to normalize user-provided properties

Files:

  • source/Classes/020.SqlAgentAlert.ps1

⚙️ CodeRabbit configuration file

source/[cC]lasses/**/*.ps1: # DSC Class-Based Resource Guidelines

Applies to: Classes with [DscResource(...)] decoration only.

Requirements

  • File: source/Classes/020.{ResourceName}.ps1
  • Decoration: [DscResource(RunAsCredential = 'Optional')] (replace with 'Mandatory' if required)
  • Inheritance: Must inherit ResourceBase (part of module DscResource.Base)
  • $this.localizedData hashtable auto-populated by ResourceBase from localization file

Required constructor

MyResourceName () : base ($PSScriptRoot)
{
    # Property names where state cannot be enforced, e.g Ensure
    $this.ExcludeDscProperties = @()
}

Required Method Pattern

[MyResourceName] Get()
{
    # Call base implementation to get current state
    $currentState = ([ResourceBase] $this).Get()

    # If needed, post-processing on current state that can not be handled by GetCurrentState()

    return $currentState
}

[System.Boolean] Test()
{
    # Call base implementation to test current state
    $inDesiredState = ([ResourceBase] $this).Test()

    # If needed, post-processing on test result that can not be handled by base Test()

    return $inDesiredState
}

[void] Set()
{
    # Call base implementation to set desired state
    ([ResourceBase] $this).Set()

    # If needed, additional state changes that can not be handled by Modify()
}

hidden [System.Collections.Hashtable] GetCurrentState([System.Collections.Hashtable] $properties)
{
    # Always return current state as hashtable, $properties contains key properties
}

hidden [void] Modify([System.Collections.Hashtable] $properties)
{
    # Always set desired state, $properties contain those that must change state
}

Optional Method Pattern

hidden [void] AssertProperties([System.Collections.Hashtable] $properties)
{
    # Validate user-provided properties, $properties contains user assigned values
}

hidden [void] NormalizeProperties([System.Collections.Hashtable] $pr...

Files:

  • source/Classes/020.SqlAgentAlert.ps1
source/**/*.ps1

📄 CodeRabbit inference engine (.github/instructions/dsc-community-style-guidelines-localization.instructions.md)

source/**/*.ps1: Localize all Write-Debug, Write-Verbose, Write-Error, Write-Warning, and $PSCmdlet.ThrowTerminatingError() messages
Do not hardcode user-facing strings; use localized string keys instead
Access localized strings via $script:localizedData, formatting with -f when needed

Localize all strings in source code using string keys

Files:

  • source/Classes/020.SqlAgentAlert.ps1

⚙️ CodeRabbit configuration file

source/**/*.ps1: # Localization Guidelines

Requirements

  • Localize all Write-Debug, Write-Verbose, Write-Error, Write-Warning and $PSCmdlet.ThrowTerminatingError() messages
  • Use localized string keys, not hardcoded strings
  • Assume $script:localizedData is available

String Files

  • Commands/functions: source/en-US/SqlServerDsc.strings.psd1
  • Class resources: source/en-US/{ResourceClassName}.strings.psd1

Key Naming Patterns

  • Format: Verb_FunctionName_Action (underscore separators), e.g. Get_SqlDscDatabase_ConnectingToDatabase

String Format

ConvertFrom-StringData @'
    KeyName = Message with {0} placeholder. (PREFIX0001)
'@

String IDs

  • Format: (PREFIX####)
  • PREFIX: First letter of each word in class or function name (SqlSetup → SS, Get-SqlDscDatabase → GSDD)
  • Number: Sequential from 0001

Usage

Write-Verbose -Message ($script:localizedData.KeyName -f $value1)

Files:

  • source/Classes/020.SqlAgentAlert.ps1
🧠 Learnings (49)
📓 Common learnings
Learnt from: CR
PR: dsccommunity/SqlServerDsc#0
File: .github/instructions/SqlServerDsc-guidelines.instructions.md:0-0
Timestamp: 2025-08-25T10:04:53.132Z
Learning: Applies to **/DSCResources/**.{ps1,psm1} : Database Engine DSC resources must inherit the SqlResourceBase base class
📚 Learning: 2025-08-25T10:10:02.060Z
Learnt from: CR
PR: dsccommunity/SqlServerDsc#0
File: .github/instructions/dsc-community-style-guidelines.instructions.md:0-0
Timestamp: 2025-08-25T10:10:02.060Z
Learning: Applies to tests/Unit/Classes/*.Tests.ps1 : Add unit tests for all resources (class-based)

Applied to files:

  • tests/Unit/Classes/SqlAgentAlert.Tests.ps1
📚 Learning: 2025-08-25T10:04:53.132Z
Learnt from: CR
PR: dsccommunity/SqlServerDsc#0
File: .github/instructions/SqlServerDsc-guidelines.instructions.md:0-0
Timestamp: 2025-08-25T10:04:53.132Z
Learning: Applies to tests/Unit/**/*.Tests.ps1 : Unit tests must set $env:SqlServerDscCI = $true in BeforeAll and remove it in AfterAll

Applied to files:

  • tests/Unit/Classes/SqlAgentAlert.Tests.ps1
  • .github/instructions/SqlServerDsc-guidelines.instructions.md
📚 Learning: 2025-08-25T10:07:49.119Z
Learnt from: CR
PR: dsccommunity/SqlServerDsc#0
File: .github/instructions/dsc-community-style-guidelines-pester.instructions.md:0-0
Timestamp: 2025-08-25T10:07:49.119Z
Learning: Applies to tests/Unit/Classes/*.Tests.ps1 : Place unit tests for class resources in tests/Unit/Classes/{Name}.Tests.ps1

Applied to files:

  • tests/Unit/Classes/SqlAgentAlert.Tests.ps1
📚 Learning: 2025-08-18T13:50:53.789Z
Learnt from: johlju
PR: dsccommunity/SqlServerDsc#2132
File: tests/Unit/Public/New-SqlDscLogin.Tests.ps1:0-0
Timestamp: 2025-08-18T13:50:53.789Z
Learning: In SqlServerDsc unit tests, SMO stub objects can be used to verify method calls like Create() on Login objects by adding mock verifications with Should -Invoke, providing more robust testing than just checking for no exceptions.

Applied to files:

  • tests/Unit/Classes/SqlAgentAlert.Tests.ps1
📚 Learning: 2025-08-25T10:04:53.132Z
Learnt from: CR
PR: dsccommunity/SqlServerDsc#0
File: .github/instructions/SqlServerDsc-guidelines.instructions.md:0-0
Timestamp: 2025-08-25T10:04:53.132Z
Learning: Applies to **/DSCResources/**.{ps1,psm1} : Database Engine DSC resources must inherit the SqlResourceBase base class

Applied to files:

  • source/Classes/020.SqlAgentAlert.ps1
  • .github/instructions/dsc-community-style-guidelines-class-resource.instructions.md
📚 Learning: 2025-08-25T10:04:53.132Z
Learnt from: CR
PR: dsccommunity/SqlServerDsc#0
File: .github/instructions/SqlServerDsc-guidelines.instructions.md:0-0
Timestamp: 2025-08-25T10:04:53.132Z
Learning: Applies to **/DSCResources/**.{ps1,psm1} : Resources inheriting SqlResourceBase should use its provided members: InstanceName, ServerName, Credential, Reasons, and GetServerObject()

Applied to files:

  • source/Classes/020.SqlAgentAlert.ps1
  • .github/instructions/dsc-community-style-guidelines-class-resource.instructions.md
📚 Learning: 2025-08-25T10:05:48.616Z
Learnt from: CR
PR: dsccommunity/SqlServerDsc#0
File: .github/instructions/dsc-community-style-guidelines-integration-tests.instructions.md:0-0
Timestamp: 2025-08-25T10:05:48.616Z
Learning: Applies to tests/[iI]ntegration/**/*.[iI]ntegration.[tT]ests.ps1 : Avoid using ExpectedMessage with Should -Throw assertions in Pester

Applied to files:

  • .github/instructions/dsc-community-style-guidelines-pester.instructions.md
📚 Learning: 2025-08-25T10:07:49.119Z
Learnt from: CR
PR: dsccommunity/SqlServerDsc#0
File: .github/instructions/dsc-community-style-guidelines-pester.instructions.md:0-0
Timestamp: 2025-08-25T10:07:49.119Z
Learning: Applies to **/*.[Tt]ests.ps1 : Use Pester v5 syntax only

Applied to files:

  • .github/instructions/dsc-community-style-guidelines-pester.instructions.md
📚 Learning: 2025-08-25T10:04:22.215Z
Learnt from: CR
PR: dsccommunity/SqlServerDsc#0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-08-25T10:04:22.215Z
Learning: Applies to **/*.{ps1,psm1,psd1} : Always follow PowerShell code style guidelines (./instructions/dsc-community-style-guidelines-powershell.instructions.md)

Applied to files:

  • .github/instructions/dsc-community-style-guidelines-pester.instructions.md
  • .github/instructions/dsc-community-style-guidelines-powershell.instructions.md
📚 Learning: 2025-08-25T10:07:49.119Z
Learnt from: CR
PR: dsccommunity/SqlServerDsc#0
File: .github/instructions/dsc-community-style-guidelines-pester.instructions.md:0-0
Timestamp: 2025-08-25T10:07:49.119Z
Learning: Applies to **/*.[Tt]ests.ps1 : Do not use 'Should -Not -Throw'; invoke commands directly instead

Applied to files:

  • .github/instructions/dsc-community-style-guidelines-pester.instructions.md
  • .github/instructions/dsc-community-style-guidelines-powershell.instructions.md
📚 Learning: 2025-08-17T10:15:48.194Z
Learnt from: johlju
PR: dsccommunity/SqlServerDsc#2136
File: tests/Unit/Public/Remove-SqlDscLogin.Tests.ps1:36-39
Timestamp: 2025-08-17T10:15:48.194Z
Learning: Public command unit tests guideline: Never use InModuleScope unless accessing localized strings from $script:localizedData. PSDefaultParameterValues for InModuleScope should be kept in public command tests to support localized string retrieval when necessary.

Applied to files:

  • .github/instructions/dsc-community-style-guidelines-pester.instructions.md
📚 Learning: 2025-08-25T10:07:49.119Z
Learnt from: CR
PR: dsccommunity/SqlServerDsc#0
File: .github/instructions/dsc-community-style-guidelines-pester.instructions.md:0-0
Timestamp: 2025-08-25T10:07:49.119Z
Learning: Applies to **/*.[Tt]ests.ps1 : Use PascalCase for Pester keywords: Describe, Context, It, Should, BeforeAll, BeforeEach, AfterAll, AfterEach

Applied to files:

  • .github/instructions/dsc-community-style-guidelines-pester.instructions.md
📚 Learning: 2025-08-25T10:07:49.119Z
Learnt from: CR
PR: dsccommunity/SqlServerDsc#0
File: .github/instructions/dsc-community-style-guidelines-pester.instructions.md:0-0
Timestamp: 2025-08-25T10:07:49.119Z
Learning: Applies to **/*.[Tt]ests.ps1 : Define mocks in BeforeAll (use BeforeEach for mocking only when required)

Applied to files:

  • .github/instructions/dsc-community-style-guidelines-pester.instructions.md
  • .github/instructions/SqlServerDsc-guidelines.instructions.md
📚 Learning: 2025-08-25T10:07:49.119Z
Learnt from: CR
PR: dsccommunity/SqlServerDsc#0
File: .github/instructions/dsc-community-style-guidelines-pester.instructions.md:0-0
Timestamp: 2025-08-25T10:07:49.119Z
Learning: Applies to **/*.[Tt]ests.ps1 : Keep variable and mock scope as close as possible to the usage context

Applied to files:

  • .github/instructions/dsc-community-style-guidelines-pester.instructions.md
  • .github/instructions/SqlServerDsc-guidelines.instructions.md
📚 Learning: 2025-08-25T10:07:49.119Z
Learnt from: CR
PR: dsccommunity/SqlServerDsc#0
File: .github/instructions/dsc-community-style-guidelines-pester.instructions.md:0-0
Timestamp: 2025-08-25T10:07:49.119Z
Learning: Applies to **/*.[Tt]ests.ps1 : Prefix mock variables with 'mock'

Applied to files:

  • .github/instructions/dsc-community-style-guidelines-pester.instructions.md
📚 Learning: 2025-08-25T10:07:49.119Z
Learnt from: CR
PR: dsccommunity/SqlServerDsc#0
File: .github/instructions/dsc-community-style-guidelines-pester.instructions.md:0-0
Timestamp: 2025-08-25T10:07:49.119Z
Learning: Applies to tests/Unit/Public/**/*.Tests.ps1 : For public command tests, never use InModuleScope (except when retrieving localized strings)

Applied to files:

  • .github/instructions/dsc-community-style-guidelines-pester.instructions.md
📚 Learning: 2025-08-25T10:07:49.119Z
Learnt from: CR
PR: dsccommunity/SqlServerDsc#0
File: .github/instructions/dsc-community-style-guidelines-pester.instructions.md:0-0
Timestamp: 2025-08-25T10:07:49.119Z
Learning: Applies to **/*.[Tt]ests.ps1 : Start It descriptions with 'Should'

Applied to files:

  • .github/instructions/dsc-community-style-guidelines-pester.instructions.md
📚 Learning: 2025-08-25T10:04:53.132Z
Learnt from: CR
PR: dsccommunity/SqlServerDsc#0
File: .github/instructions/SqlServerDsc-guidelines.instructions.md:0-0
Timestamp: 2025-08-25T10:04:53.132Z
Learning: Applies to tests/Unit/**/*.Tests.ps1 : In unit tests, do not mock SMO types directly

Applied to files:

  • .github/instructions/dsc-community-style-guidelines-pester.instructions.md
  • .github/instructions/SqlServerDsc-guidelines.instructions.md
📚 Learning: 2025-08-25T10:04:53.132Z
Learnt from: CR
PR: dsccommunity/SqlServerDsc#0
File: .github/instructions/SqlServerDsc-guidelines.instructions.md:0-0
Timestamp: 2025-08-25T10:04:53.132Z
Learning: Applies to tests/Unit/**/*.Tests.ps1 : In unit tests, use SMO stub types defined in SMO.cs

Applied to files:

  • .github/instructions/SqlServerDsc-guidelines.instructions.md
📚 Learning: 2025-08-25T10:04:22.216Z
Learnt from: CR
PR: dsccommunity/SqlServerDsc#0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-08-25T10:04:22.216Z
Learning: Follow SqlServerDsc project specific guidelines (./instructions/SqlServerDsc-guidelines.instructions.md)

Applied to files:

  • .github/instructions/SqlServerDsc-guidelines.instructions.md
📚 Learning: 2025-08-25T10:04:53.132Z
Learnt from: CR
PR: dsccommunity/SqlServerDsc#0
File: .github/instructions/SqlServerDsc-guidelines.instructions.md:0-0
Timestamp: 2025-08-25T10:04:53.132Z
Learning: After changing SMO.cs, run tests in a new PowerShell session

Applied to files:

  • .github/instructions/SqlServerDsc-guidelines.instructions.md
📚 Learning: 2025-08-17T10:13:30.079Z
Learnt from: johlju
PR: dsccommunity/SqlServerDsc#2136
File: source/Public/Remove-SqlDscLogin.ps1:104-108
Timestamp: 2025-08-17T10:13:30.079Z
Learning: In SqlServerDsc unit tests, SMO object stubs (like Login objects) should have properly mocked Parent properties with correct Server stub types and valid InstanceName values, rather than handling null Parent scenarios in production code.

Applied to files:

  • .github/instructions/SqlServerDsc-guidelines.instructions.md
📚 Learning: 2025-08-25T10:04:22.216Z
Learnt from: CR
PR: dsccommunity/SqlServerDsc#0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-08-25T10:04:22.216Z
Learning: SqlServerDsc-specific guidelines override general project guidelines

Applied to files:

  • .github/instructions/SqlServerDsc-guidelines.instructions.md
📚 Learning: 2025-08-25T10:04:22.216Z
Learnt from: CR
PR: dsccommunity/SqlServerDsc#0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-08-25T10:04:22.216Z
Learning: Always add Unit testing according to (./instructions/dsc-community-style-guidelines-unit-tests.instructions.md)

Applied to files:

  • .github/instructions/SqlServerDsc-guidelines.instructions.md
📚 Learning: 2025-08-25T10:04:53.132Z
Learnt from: CR
PR: dsccommunity/SqlServerDsc#0
File: .github/instructions/SqlServerDsc-guidelines.instructions.md:0-0
Timestamp: 2025-08-25T10:04:53.132Z
Learning: Applies to azure-pipelines.yml : Choose the appropriate integration test group number in azure-pipelines.yml based on required dependencies

Applied to files:

  • .github/instructions/SqlServerDsc-guidelines.instructions.md
📚 Learning: 2025-08-25T10:09:27.858Z
Learnt from: CR
PR: dsccommunity/SqlServerDsc#0
File: .github/instructions/dsc-community-style-guidelines-unit-tests.instructions.md:0-0
Timestamp: 2025-08-25T10:09:27.858Z
Learning: After modifying classes, always run tests in a new PowerShell session to pick up changes

Applied to files:

  • .github/instructions/SqlServerDsc-guidelines.instructions.md
📚 Learning: 2025-08-25T10:05:48.616Z
Learnt from: CR
PR: dsccommunity/SqlServerDsc#0
File: .github/instructions/dsc-community-style-guidelines-integration-tests.instructions.md:0-0
Timestamp: 2025-08-25T10:05:48.616Z
Learning: Applies to tests/[iI]ntegration/**/*.[iI]ntegration.[tT]ests.ps1 : Do not use mocking in integration tests; execute against a real environment

Applied to files:

  • .github/instructions/SqlServerDsc-guidelines.instructions.md
📚 Learning: 2025-08-25T10:05:48.616Z
Learnt from: CR
PR: dsccommunity/SqlServerDsc#0
File: .github/instructions/dsc-community-style-guidelines-integration-tests.instructions.md:0-0
Timestamp: 2025-08-25T10:05:48.616Z
Learning: Applies to tests/[iI]ntegration/**/*.[iI]ntegration.[tT]ests.ps1 : When calling commands, include -Force where applicable to avoid prompts

Applied to files:

  • .github/instructions/SqlServerDsc-guidelines.instructions.md
📚 Learning: 2025-08-25T10:04:22.216Z
Learnt from: CR
PR: dsccommunity/SqlServerDsc#0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-08-25T10:04:22.216Z
Learning: Follow class-based resources guidelines (./instructions/dsc-community-style-guidelines-class-resource.instructions.md)

Applied to files:

  • .github/instructions/dsc-community-style-guidelines-class-resource.instructions.md
📚 Learning: 2025-08-25T10:05:30.595Z
Learnt from: CR
PR: dsccommunity/SqlServerDsc#0
File: .github/instructions/dsc-community-style-guidelines-class-resource.instructions.md:0-0
Timestamp: 2025-08-25T10:05:30.595Z
Learning: Applies to source/[cC]lasses/**/*.ps1 : Resource classes must inherit ResourceBase (from the DscResource.Base module)

Applied to files:

  • .github/instructions/dsc-community-style-guidelines-class-resource.instructions.md
📚 Learning: 2025-08-25T10:05:30.595Z
Learnt from: CR
PR: dsccommunity/SqlServerDsc#0
File: .github/instructions/dsc-community-style-guidelines-class-resource.instructions.md:0-0
Timestamp: 2025-08-25T10:05:30.595Z
Learning: Applies to source/[cC]lasses/**/*.ps1 : Decorate the resource class with [DscResource(RunAsCredential = 'Optional')] (use 'Mandatory' if required)

Applied to files:

  • .github/instructions/dsc-community-style-guidelines-class-resource.instructions.md
📚 Learning: 2025-08-25T10:05:30.595Z
Learnt from: CR
PR: dsccommunity/SqlServerDsc#0
File: .github/instructions/dsc-community-style-guidelines-class-resource.instructions.md:0-0
Timestamp: 2025-08-25T10:05:30.595Z
Learning: Applies to source/[cC]lasses/**/*.ps1 : Use $this.localizedData provided by ResourceBase (auto-populated from the localization file); do not manually populate it

Applied to files:

  • .github/instructions/dsc-community-style-guidelines-class-resource.instructions.md
📚 Learning: 2025-08-25T10:04:22.216Z
Learnt from: CR
PR: dsccommunity/SqlServerDsc#0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-08-25T10:04:22.216Z
Learning: New DSC resources should always be created as class-based resources

Applied to files:

  • .github/instructions/dsc-community-style-guidelines-class-resource.instructions.md
📚 Learning: 2025-08-25T10:07:22.330Z
Learnt from: CR
PR: dsccommunity/SqlServerDsc#0
File: .github/instructions/dsc-community-style-guidelines-mof-resources.instructions.md:0-0
Timestamp: 2025-08-25T10:07:22.330Z
Learning: Applies to source/DSCResources/**/*.psm1 : Each MOF-based DSC resource module must define the functions Get-TargetResource, Set-TargetResource, and Test-TargetResource

Applied to files:

  • .github/instructions/dsc-community-style-guidelines-class-resource.instructions.md
📚 Learning: 2025-08-25T10:07:22.330Z
Learnt from: CR
PR: dsccommunity/SqlServerDsc#0
File: .github/instructions/dsc-community-style-guidelines-mof-resources.instructions.md:0-0
Timestamp: 2025-08-25T10:07:22.330Z
Learning: Applies to source/DSCResources/**/*.psm1 : When raising terminating errors, throw localized exceptions created via the appropriate DscResource.Common New-*Exception cmdlets (e.g., New-InvalidDataException, New-ArgumentException, New-InvalidOperationException, New-ObjectNotFoundException, New-InvalidResultException, New-NotImplementedException)

Applied to files:

  • .github/instructions/dsc-community-style-guidelines-class-resource.instructions.md
  • .github/instructions/dsc-community-style-guidelines-powershell.instructions.md
📚 Learning: 2025-08-25T10:07:22.330Z
Learnt from: CR
PR: dsccommunity/SqlServerDsc#0
File: .github/instructions/dsc-community-style-guidelines-mof-resources.instructions.md:0-0
Timestamp: 2025-08-25T10:07:22.330Z
Learning: Applies to source/DSCResources/**/*.psm1 : Get-TargetResource must return a hashtable containing all resource properties

Applied to files:

  • .github/instructions/dsc-community-style-guidelines-class-resource.instructions.md
📚 Learning: 2025-08-25T10:05:30.595Z
Learnt from: CR
PR: dsccommunity/SqlServerDsc#0
File: .github/instructions/dsc-community-style-guidelines-class-resource.instructions.md:0-0
Timestamp: 2025-08-25T10:05:30.595Z
Learning: Applies to source/[cC]lasses/**/*.ps1 : Implement hidden [void] NormalizeProperties([System.Collections.Hashtable] $properties) to normalize user-provided properties

Applied to files:

  • .github/instructions/dsc-community-style-guidelines-class-resource.instructions.md
📚 Learning: 2025-08-25T10:09:05.876Z
Learnt from: CR
PR: dsccommunity/SqlServerDsc#0
File: .github/instructions/dsc-community-style-guidelines-powershell.instructions.md:0-0
Timestamp: 2025-08-25T10:09:05.876Z
Learning: Applies to **/*.{ps1,psm1} : Comment-based help must include SYNOPSIS, DESCRIPTION (40+ chars), PARAMETER, EXAMPLE sections before function/class

Applied to files:

  • .github/instructions/dsc-community-style-guidelines-class-resource.instructions.md
📚 Learning: 2025-08-25T10:05:30.595Z
Learnt from: CR
PR: dsccommunity/SqlServerDsc#0
File: .github/instructions/dsc-community-style-guidelines-class-resource.instructions.md:0-0
Timestamp: 2025-08-25T10:05:30.595Z
Learning: Applies to source/[cC]lasses/**/*.ps1 : Implement hidden [void] Modify([System.Collections.Hashtable] $properties) to set desired state only for non-compliant properties

Applied to files:

  • .github/instructions/dsc-community-style-guidelines-class-resource.instructions.md
📚 Learning: 2025-08-25T10:09:05.876Z
Learnt from: CR
PR: dsccommunity/SqlServerDsc#0
File: .github/instructions/dsc-community-style-guidelines-powershell.instructions.md:0-0
Timestamp: 2025-08-25T10:09:05.876Z
Learning: Applies to **/*.{ps1,psm1} : .NOTES only when critical (constraints, side effects, security, version compatibility, breaking behavior), ≤2 short sentences

Applied to files:

  • .github/instructions/dsc-community-style-guidelines-powershell.instructions.md
📚 Learning: 2025-08-25T10:09:05.876Z
Learnt from: CR
PR: dsccommunity/SqlServerDsc#0
File: .github/instructions/dsc-community-style-guidelines-powershell.instructions.md:0-0
Timestamp: 2025-08-25T10:09:05.876Z
Learning: Applies to **/*.{ps1,psm1} : For state-changing functions, set SupportsShouldProcess

Applied to files:

  • .github/instructions/dsc-community-style-guidelines-powershell.instructions.md
📚 Learning: 2025-08-25T10:09:05.876Z
Learnt from: CR
PR: dsccommunity/SqlServerDsc#0
File: .github/instructions/dsc-community-style-guidelines-powershell.instructions.md:0-0
Timestamp: 2025-08-25T10:09:05.876Z
Learning: Applies to **/*.{ps1,psm1} : Use $PSCmdlet.ThrowTerminatingError() for terminating errors with relevant category

Applied to files:

  • .github/instructions/dsc-community-style-guidelines-powershell.instructions.md
📚 Learning: 2025-08-25T10:09:05.876Z
Learnt from: CR
PR: dsccommunity/SqlServerDsc#0
File: .github/instructions/dsc-community-style-guidelines-powershell.instructions.md:0-0
Timestamp: 2025-08-25T10:09:05.876Z
Learning: Applies to **/*.{ps1,psm1} : Use Write-Error for non-terminating errors with relevant category

Applied to files:

  • .github/instructions/dsc-community-style-guidelines-powershell.instructions.md
📚 Learning: 2025-08-25T10:07:22.330Z
Learnt from: CR
PR: dsccommunity/SqlServerDsc#0
File: .github/instructions/dsc-community-style-guidelines-mof-resources.instructions.md:0-0
Timestamp: 2025-08-25T10:07:22.330Z
Learning: Applies to source/DSCResources/**/*.psm1 : Do not use throw for terminating errors; handle errors via try/catch

Applied to files:

  • .github/instructions/dsc-community-style-guidelines-powershell.instructions.md
📚 Learning: 2025-08-25T10:09:05.876Z
Learnt from: CR
PR: dsccommunity/SqlServerDsc#0
File: .github/instructions/dsc-community-style-guidelines-powershell.instructions.md:0-0
Timestamp: 2025-08-25T10:09:05.876Z
Learning: Applies to **/*.{ps1,psm1} : Avoid Write-Host; prefer Write-Verbose/Write-Information, etc.

Applied to files:

  • .github/instructions/dsc-community-style-guidelines-powershell.instructions.md
📚 Learning: 2025-08-25T10:09:05.876Z
Learnt from: CR
PR: dsccommunity/SqlServerDsc#0
File: .github/instructions/dsc-community-style-guidelines-powershell.instructions.md:0-0
Timestamp: 2025-08-25T10:09:05.876Z
Learning: Applies to **/*.{ps1,psm1} : Include a Force parameter for functions that support ShouldContinue or use ShouldProcess

Applied to files:

  • .github/instructions/dsc-community-style-guidelines-powershell.instructions.md
📚 Learning: 2025-08-25T10:09:05.876Z
Learnt from: CR
PR: dsccommunity/SqlServerDsc#0
File: .github/instructions/dsc-community-style-guidelines-powershell.instructions.md:0-0
Timestamp: 2025-08-25T10:09:05.876Z
Learning: Applies to **/*.{ps1,psm1} : Avoid Write-Output; use 'return' instead

Applied to files:

  • .github/instructions/dsc-community-style-guidelines-powershell.instructions.md
📚 Learning: 2025-08-25T10:09:05.876Z
Learnt from: CR
PR: dsccommunity/SqlServerDsc#0
File: .github/instructions/dsc-community-style-guidelines-powershell.instructions.md:0-0
Timestamp: 2025-08-25T10:09:05.876Z
Learning: Applies to **/*.{ps1,psm1} : Avoid empty catch blocks; use -ErrorAction SilentlyContinue instead

Applied to files:

  • .github/instructions/dsc-community-style-guidelines-powershell.instructions.md
🪛 LanguageTool
.github/instructions/dsc-community-style-guidelines-pester.instructions.md

[grammar] ~36-~36: There might be a mistake here.
Context: ...Mock:ModuleName, Should:ModuleName, InModuleScope:ModuleName - Omit -ModuleName parameter on Pester c...

(QB_NEW_EN)

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

[grammar] ~40-~40: There might be a mistake here.
Context: ...hell session for changes to take effect.

(QB_NEW_EN)

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

[grammar] ~95-~95: There might be a mistake here.
Context: ...based help Add to .DESCRIPTION section: - ## Requirements: List minimum requirements - `## Known ...

(QB_NEW_EN)


[grammar] ~96-~96: There might be a mistake here.
Context: ...Requirements: List minimum requirements - ## Known issues: Critical issues + pattern: All issues...

(QB_NEW_EN)


[grammar] ~99-~99: There might be a mistake here.
Context: ...tle+{ResourceName}). ## Error Handling - Usetry/catch` blocks to handle excepti...

(QB_NEW_EN)

🪛 markdownlint-cli2 (0.17.2)
.github/instructions/SqlServerDsc-guidelines.instructions.md

37-37: Lists should be surrounded by blank lines

(MD032, blanks-around-lists)


40-40: Line length
Expected: 80; Actual: 100

(MD013, line-length)

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

16-16: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below

(MD022, blanks-around-headings)


17-17: Lists should be surrounded by blank lines

(MD032, blanks-around-lists)


21-21: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below

(MD022, blanks-around-headings)


22-22: Lists should be surrounded by blank lines

(MD032, blanks-around-lists)

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

82-82: Line length
Expected: 80; Actual: 114

(MD013, line-length)

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
  • GitHub Check: dsccommunity.SqlServerDsc (Build Package Module)
  • GitHub Check: PSScriptAnalyzer
  • GitHub Check: PSScriptAnalyzer

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

♻️ Duplicate comments (1)
.github/instructions/dsc-community-style-guidelines-class-resource.instructions.md (1)

99-107: *Error-handling directive is contradictory — class-based resources should throw the localized New-Exception object

For class-based resources, create a localized exception with DscResource.Common’s New-*Exception helper and throw that object. Also fix heading capitalization and add a short example.

Apply:

-## Error Handling
-- Use `try/catch` blocks to handle exceptions
-- Do not use `throw` for terminating errors, use `New-*Exception` commands:
+## Error handling
+
+- Use `try/catch` blocks to handle exceptions.
+- For terminating errors, throw a localized exception created with the
+  appropriate `New-*Exception` helper from DscResource.Common:
   - [`New‑InvalidDataException`](https://github.com/dsccommunity/DscResource.Common/wiki/New%E2%80%91InvalidDataException)
   - [`New-ArgumentException`](https://github.com/dsccommunity/DscResource.Common/wiki/New%E2%80%91ArgumentException)
   - [`New-InvalidOperationException`](https://github.com/dsccommunity/DscResource.Common/wiki/New%E2%80%91InvalidOperationException)
   - [`New-ObjectNotFoundException`](https://github.com/dsccommunity/DscResource.Common/wiki/New%E2%80%91ObjectNotFoundException)
   - [`New-InvalidResultException`](https://github.com/dsccommunity/DscResource.Common/wiki/New%E2%80%91InvalidResultException)
   - [`New-NotImplementedException`](https://github.com/dsccommunity/DscResource.Common/wiki/New%E2%80%91NotImplementedException)
+
+Example:
+```powershell
+catch
+{
+    $msg = $this.localizedData.{ResourceName}_Action_Failed -f $this.Name, $_.Exception.Message
+    throw (New-InvalidOperationException -Message $msg -ErrorRecord $_)
+}
+```
🧹 Nitpick comments (4)
.github/instructions/dsc-community-style-guidelines-class-resource.instructions.md (4)

17-25: Duplicate “Required constructor” sections and inconsistent sample — consolidate and keep the base($PSScriptRoot) pattern

There are two constructor sections; keep a single canonical example using base($PSScriptRoot). Also fix example comment to realistic properties and wrap for readability.

Apply:

-## Required constructor
-
-```powershell
-MyResourceName () : base ()
-{
-    # Property names where state cannot be enforced, e.g. IsSingleInstance, Force
-    $this.ExcludeDscProperties = @()
-}
-```
-
-## Required constructor
+## Required constructor
@@
-MyResourceName () : base ($PSScriptRoot)
+MyResourceName () : base ($PSScriptRoot)
 {
-    # Property names where state cannot be enforced, e.g Ensure
+    # Property names where state cannot be enforced,
+    # e.g., IsSingleInstance, Force
     $this.ExcludeDscProperties = @()
 }


Also applies to: 27-35

---

`73-76`: **Clarify Modify() contract to change only non-compliant properties**

Match repository guidance: Modify should enforce desired state only for properties not already compliant, to minimize churn and support ShouldProcess accurately.



Apply:

```diff
 hidden [void] Modify([System.Collections.Hashtable] $properties)
 {
-    # Always set desired state, $properties contain those that must change state
+    # Set desired state only for non-compliant properties.
+    # $properties contains the subset that must change state.
 }

93-98: Fix markdown formatting and wording in “Required comment-based help”

Add blank lines around the list, wrap long line, and clarify wording to satisfy markdownlint and readability.

Apply:

-## Required comment-based help
-
-Add to .DESCRIPTION section:
-- `## Requirements`: List minimum requirements
-- `## Known issues`: Critical issues + pattern: `All issues are not listed here, see [all open issues](https://github.com/{owner}/{repo}/issues?q=is%3Aissue+is%3Aopen+in%3Atitle+{ResourceName}).`
+## Required comment-based help
+
+Add to the .DESCRIPTION section:
+
+- `## Requirements`: List minimum requirements.
+- `## Known issues`: List only critical/known issues. For the full list, see:
+  [all open issues](https://github.com/{owner}/{repo}/issues?q=is%3Aissue+is%3Aopen+in%3Atitle+{ResourceName}).
+

81-91: Update class-resource style guidelines: Mark NormalizeProperties as Recommended

Based on a scan of the repository, nine class resources currently lack a NormalizeProperties implementation. To ensure consistent Test()/Get() comparisons, we should update the guidance to treat NormalizeProperties as a recommended (not purely optional) method while keeping AssertProperties optional.

• Files missing NormalizeProperties (implement as hidden [void] NormalizeProperties([Hashtable] $properties)):

  • source/Classes/001.SqlReason.ps1
  • source/Classes/002.DatabasePermission.ps1
  • source/Classes/002.ServerPermission.ps1
  • source/Classes/004.StartupParameters.ps1
  • source/Classes/011.SqlResourceBase.ps1
  • source/Classes/020.SqlAudit.ps1
  • source/Classes/020.SqlDatabasePermission.ps1
  • source/Classes/020.SqlPermission.ps1
  • source/Classes/020.SqlAgentAlert.ps1

Apply the following update in .github/instructions/dsc-community-style-guidelines-class-resource.instructions.md:

-## Optional Method Pattern
+## Optional/Recommended Method Pattern
@@
 hidden [void] NormalizeProperties([System.Collections.Hashtable] $properties)
 {
-    # Normalize user-provided properties, $properties contains user assigned values
+    # Recommended: Normalize user-provided properties (e.g., trim strings,
+    # expand paths, canonicalize names) so Test() comparisons are reliable.
+    # $properties contains user-assigned values.
 }

Leave the AssertProperties entry under “Optional Method Pattern” unchanged.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

💡 Knowledge Base configuration:

  • Jira integration is disabled
  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 4d5b237 and 4897a08.

📒 Files selected for processing (1)
  • .github/instructions/dsc-community-style-guidelines-class-resource.instructions.md (2 hunks)
🧰 Additional context used
🧠 Learnings (16)
📓 Common learnings
Learnt from: CR
PR: dsccommunity/SqlServerDsc#0
File: .github/instructions/SqlServerDsc-guidelines.instructions.md:0-0
Timestamp: 2025-08-25T10:04:53.132Z
Learning: Applies to **/DSCResources/**.{ps1,psm1} : Database Engine DSC resources must inherit the SqlResourceBase base class
📚 Learning: 2025-08-25T10:04:22.216Z
Learnt from: CR
PR: dsccommunity/SqlServerDsc#0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-08-25T10:04:22.216Z
Learning: Follow class-based resources guidelines (./instructions/dsc-community-style-guidelines-class-resource.instructions.md)

Applied to files:

  • .github/instructions/dsc-community-style-guidelines-class-resource.instructions.md
📚 Learning: 2025-08-25T10:05:30.595Z
Learnt from: CR
PR: dsccommunity/SqlServerDsc#0
File: .github/instructions/dsc-community-style-guidelines-class-resource.instructions.md:0-0
Timestamp: 2025-08-25T10:05:30.595Z
Learning: Applies to source/[cC]lasses/**/*.ps1 : Resource classes must inherit ResourceBase (from the DscResource.Base module)

Applied to files:

  • .github/instructions/dsc-community-style-guidelines-class-resource.instructions.md
📚 Learning: 2025-08-25T10:04:53.132Z
Learnt from: CR
PR: dsccommunity/SqlServerDsc#0
File: .github/instructions/SqlServerDsc-guidelines.instructions.md:0-0
Timestamp: 2025-08-25T10:04:53.132Z
Learning: Applies to **/DSCResources/**.{ps1,psm1} : Database Engine DSC resources must inherit the SqlResourceBase base class

Applied to files:

  • .github/instructions/dsc-community-style-guidelines-class-resource.instructions.md
📚 Learning: 2025-08-25T10:04:53.132Z
Learnt from: CR
PR: dsccommunity/SqlServerDsc#0
File: .github/instructions/SqlServerDsc-guidelines.instructions.md:0-0
Timestamp: 2025-08-25T10:04:53.132Z
Learning: Applies to **/DSCResources/**.{ps1,psm1} : Resources inheriting SqlResourceBase should use its provided members: InstanceName, ServerName, Credential, Reasons, and GetServerObject()

Applied to files:

  • .github/instructions/dsc-community-style-guidelines-class-resource.instructions.md
📚 Learning: 2025-08-25T10:07:22.330Z
Learnt from: CR
PR: dsccommunity/SqlServerDsc#0
File: .github/instructions/dsc-community-style-guidelines-mof-resources.instructions.md:0-0
Timestamp: 2025-08-25T10:07:22.330Z
Learning: Applies to source/DSCResources/**/*.psm1 : When raising terminating errors, throw localized exceptions created via the appropriate DscResource.Common New-*Exception cmdlets (e.g., New-InvalidDataException, New-ArgumentException, New-InvalidOperationException, New-ObjectNotFoundException, New-InvalidResultException, New-NotImplementedException)

Applied to files:

  • .github/instructions/dsc-community-style-guidelines-class-resource.instructions.md
📚 Learning: 2025-08-25T10:07:22.330Z
Learnt from: CR
PR: dsccommunity/SqlServerDsc#0
File: .github/instructions/dsc-community-style-guidelines-mof-resources.instructions.md:0-0
Timestamp: 2025-08-25T10:07:22.330Z
Learning: Applies to source/DSCResources/**/*.psm1 : Do not use throw for terminating errors; handle errors via try/catch

Applied to files:

  • .github/instructions/dsc-community-style-guidelines-class-resource.instructions.md
📚 Learning: 2025-08-17T10:48:15.384Z
Learnt from: johlju
PR: dsccommunity/SqlServerDsc#2136
File: source/suffix.ps1:24-24
Timestamp: 2025-08-17T10:48:15.384Z
Learning: In source/suffix.ps1, the Write-Verbose message in the catch block for Import-SqlDscPreferredModule does not need localization because the exception message from Import-SqlDscPreferredModule is already localized by that command, making it an edge case exception to the localization guidelines.

Applied to files:

  • .github/instructions/dsc-community-style-guidelines-class-resource.instructions.md
📚 Learning: 2025-08-25T10:05:30.595Z
Learnt from: CR
PR: dsccommunity/SqlServerDsc#0
File: .github/instructions/dsc-community-style-guidelines-class-resource.instructions.md:0-0
Timestamp: 2025-08-25T10:05:30.595Z
Learning: Applies to source/[cC]lasses/**/*.ps1 : Decorate the resource class with [DscResource(RunAsCredential = 'Optional')] (use 'Mandatory' if required)

Applied to files:

  • .github/instructions/dsc-community-style-guidelines-class-resource.instructions.md
📚 Learning: 2025-08-25T10:04:22.216Z
Learnt from: CR
PR: dsccommunity/SqlServerDsc#0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-08-25T10:04:22.216Z
Learning: New DSC resources should always be created as class-based resources

Applied to files:

  • .github/instructions/dsc-community-style-guidelines-class-resource.instructions.md
📚 Learning: 2025-08-25T10:05:30.595Z
Learnt from: CR
PR: dsccommunity/SqlServerDsc#0
File: .github/instructions/dsc-community-style-guidelines-class-resource.instructions.md:0-0
Timestamp: 2025-08-25T10:05:30.595Z
Learning: Applies to source/[cC]lasses/**/*.ps1 : Use $this.localizedData provided by ResourceBase (auto-populated from the localization file); do not manually populate it

Applied to files:

  • .github/instructions/dsc-community-style-guidelines-class-resource.instructions.md
📚 Learning: 2025-08-25T10:07:22.330Z
Learnt from: CR
PR: dsccommunity/SqlServerDsc#0
File: .github/instructions/dsc-community-style-guidelines-mof-resources.instructions.md:0-0
Timestamp: 2025-08-25T10:07:22.330Z
Learning: Applies to source/DSCResources/**/*.psm1 : Each MOF-based DSC resource module must define the functions Get-TargetResource, Set-TargetResource, and Test-TargetResource

Applied to files:

  • .github/instructions/dsc-community-style-guidelines-class-resource.instructions.md
📚 Learning: 2025-08-25T10:07:22.330Z
Learnt from: CR
PR: dsccommunity/SqlServerDsc#0
File: .github/instructions/dsc-community-style-guidelines-mof-resources.instructions.md:0-0
Timestamp: 2025-08-25T10:07:22.330Z
Learning: Applies to source/DSCResources/**/*.psm1 : Get-TargetResource must return a hashtable containing all resource properties

Applied to files:

  • .github/instructions/dsc-community-style-guidelines-class-resource.instructions.md
📚 Learning: 2025-08-25T10:05:30.595Z
Learnt from: CR
PR: dsccommunity/SqlServerDsc#0
File: .github/instructions/dsc-community-style-guidelines-class-resource.instructions.md:0-0
Timestamp: 2025-08-25T10:05:30.595Z
Learning: Applies to source/[cC]lasses/**/*.ps1 : Implement hidden [void] NormalizeProperties([System.Collections.Hashtable] $properties) to normalize user-provided properties

Applied to files:

  • .github/instructions/dsc-community-style-guidelines-class-resource.instructions.md
📚 Learning: 2025-08-25T10:09:05.876Z
Learnt from: CR
PR: dsccommunity/SqlServerDsc#0
File: .github/instructions/dsc-community-style-guidelines-powershell.instructions.md:0-0
Timestamp: 2025-08-25T10:09:05.876Z
Learning: Applies to **/*.{ps1,psm1} : Comment-based help must include SYNOPSIS, DESCRIPTION (40+ chars), PARAMETER, EXAMPLE sections before function/class

Applied to files:

  • .github/instructions/dsc-community-style-guidelines-class-resource.instructions.md
📚 Learning: 2025-08-25T10:05:30.595Z
Learnt from: CR
PR: dsccommunity/SqlServerDsc#0
File: .github/instructions/dsc-community-style-guidelines-class-resource.instructions.md:0-0
Timestamp: 2025-08-25T10:05:30.595Z
Learning: Applies to source/[cC]lasses/**/*.ps1 : Implement hidden [void] Modify([System.Collections.Hashtable] $properties) to set desired state only for non-compliant properties

Applied to files:

  • .github/instructions/dsc-community-style-guidelines-class-resource.instructions.md
🪛 LanguageTool
.github/instructions/dsc-community-style-guidelines-class-resource.instructions.md

[grammar] ~95-~95: There might be a mistake here.
Context: ...based help Add to .DESCRIPTION section: - ## Requirements: List minimum requirements - `## Known ...

(QB_NEW_EN)


[grammar] ~96-~96: There might be a mistake here.
Context: ...Requirements: List minimum requirements - ## Known issues: Critical issues + pattern: All issues...

(QB_NEW_EN)


[grammar] ~99-~99: There might be a mistake here.
Context: ...tle+{ResourceName}). ## Error Handling - Usetry/catch` blocks to handle excepti...

(QB_NEW_EN)

🪛 markdownlint-cli2 (0.17.2)
.github/instructions/dsc-community-style-guidelines-class-resource.instructions.md

96-96: Lists should be surrounded by blank lines

(MD032, blanks-around-lists)


97-97: Line length
Expected: 80; Actual: 195

(MD013, line-length)


99-99: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below

(MD022, blanks-around-headings)


100-100: Lists should be surrounded by blank lines

(MD032, blanks-around-lists)

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (4)
  • GitHub Check: dsccommunity.SqlServerDsc (Quality Test and Unit Test HQRM)
  • GitHub Check: dsccommunity.SqlServerDsc (Quality Test and Unit Test Unit)
  • GitHub Check: dsccommunity.SqlServerDsc (Quality Test and Unit Test Determine DSC Resource Test Requirements)
  • GitHub Check: dsccommunity.SqlServerDsc (Build Package Module)
🔇 Additional comments (1)
.github/instructions/dsc-community-style-guidelines-class-resource.instructions.md (1)

13-16: No DB Engine resources improperly inheriting ResourceBase

All true Database Engine DSC resources in source/Classes inherit SqlResourceBase —as intended—while the only remaining class inheriting ResourceBase and referencing InstanceName is SqlRSSetup, which is for Reporting Services, not the Database Engine. No Database Engine resource needs to be switched to SqlResourceBase.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

♻️ Duplicate comments (2)
source/Classes/020.SqlAgentAlert.ps1 (2)

55-61: Idempotency gap: 0 allowed by validation/help but ignored in state detection (Severity/MessageId).

GetCurrentState only considers values > 0 as “set”, while ValidateRange and help allow 0. A desired Severity/MessageId = 0 will never reflect in current state, causing perpetual drift.

Two ways to resolve:

  • Preferred: Disallow 0 (tighten ranges) and update help text accordingly.
  • Alternative: Keep 0 valid but change GetCurrentState comparisons to -ge 0.

Below is the “disallow 0” option (keeps -gt 0 logic untouched) with doc/help alignment.

@@
-    .PARAMETER Severity
-        The severity of the _SQL Server Agent_ alert. Valid range is 0 to 25.
+    .PARAMETER Severity
+        The severity of the _SQL Server Agent_ alert. Valid range is 1 to 25.
@@
-    .PARAMETER MessageId
-        The message id of the _SQL Server Agent_ alert. Valid range is 0 to 2147483647.
+    .PARAMETER MessageId
+        The message id of the _SQL Server Agent_ alert. Valid range is 1 to 2147483647.
@@
-    [ValidateRange(0, 25)]
+    [ValidateRange(1, 25)]
@@
-    [ValidateRange(0, 2147483647)]
+    [ValidateRange(1, 2147483647)]

If you prefer the “keep 0” option, apply this instead:

@@
-            if ($alertObject.Severity -gt 0)
+            if ($alertObject.Severity -ge 0)
@@
-            if ($alertObject.MessageId -gt 0)
+            if ($alertObject.MessageId -ge 0)

To avoid regressions, confirm the intended SQL Agent semantics for 0 (especially for Severity). If 0 isn’t meaningful in alerts, the first diff is safer and clearer.

Also applies to: 127-135, 196-205


169-173: Require exactly one of Severity or MessageId when Ensure = 'Present'.

Currently only mutual exclusivity is enforced. Creating/updating an alert without either property likely fails deeper or creates an invalid alert. Validate early with a localized error.

 hidden [void] AssertProperties([System.Collections.Hashtable] $properties)
 {
     # Validate that both Severity and MessageId are not specified
     Assert-BoundParameter -BoundParameterList $properties -MutuallyExclusiveList1 @('Severity') -MutuallyExclusiveList2 @('MessageId')
+
+    # When ensuring presence, require exactly one of Severity or MessageId
+    if ($this.Ensure -eq 'Present')
+    {
+        $hasSeverity  = $properties.ContainsKey('Severity')
+        $hasMessageId = $properties.ContainsKey('MessageId')
+
+        if (-not ($hasSeverity -xor $hasMessageId))
+        {
+            $message = $this.localizedData.SqlAgentAlert_SeverityOrMessageIdRequired -f $this.Name
+            throw (New-ArgumentException -Message $message -ArgumentName 'Severity,MessageId')
+        }
+    }
 }

Add this localized string (outside the selected range) to source/en-US/SqlAgentAlert.strings.psd1:

SqlAgentAlert_SeverityOrMessageIdRequired = 'Specify exactly one of Severity or MessageId for alert {0}.' (SAA0001)
#!/bin/bash
# Verify the new localization key exists and is referenced
rg -n "SqlAgentAlert_SeverityOrMessageIdRequired" source/en-US/SqlAgentAlert.strings.psd1
rg -n "SqlAgentAlert_SeverityOrMessageIdRequired" source/Classes/020.SqlAgentAlert.ps1
🧹 Nitpick comments (5)
.github/instructions/SqlServerDsc-guidelines.instructions.md (1)

38-41: Tighten SMO stub testing guidance and fix markdownlint/grammar nits

  • Add a blank line before the list (MD032).
  • Wrap long lines to ≤80 chars (MD013).
  • Slight grammar tweak: “a new PowerShell session for the changes to take effect.”

Apply:

-## Unit tests
-- When unit test tests classes or commands that contain SMO types, e.g. `[Microsoft.SqlServer.Management.Smo.*]`
-  - Ensure they are properly stubbed in SMO.cs
-  - Load SMO stub types from SMO.cs in unit test files, e.g. `Add-Type -Path "$PSScriptRoot/../Stubs/SMO.cs"`
-  - After changing SMO stub types, run tests in a new PowerShell session for changes to take effect.
+## Unit tests
+
+- When a unit test targets classes or commands that contain SMO types
+  (for example, `[Microsoft.SqlServer.Management.Smo.*]`):
+  - Ensure they are properly stubbed in `SMO.cs`.
+  - Load SMO stub types from `SMO.cs` in unit test files, for example:
+    `Add-Type -Path "$PSScriptRoot/../Stubs/SMO.cs"`.
+  - After changing SMO stub types, run tests in a new PowerShell session
+    for the changes to take effect.
source/Classes/020.SqlAgentAlert.ps1 (1)

10-14: Comment-based help: tighten grammar and clarity (nit).

Minor grammar/wording issues that could confuse users, e.g. “It also possible…”, “that using advanced type…”, subject‑verb agreement, and repeated “account”. Suggest edits below.

-        The built-in parameter **PSDscRunAsCredential** can be used to run the resource
-        as another user. The resource will then authenticate to the _SQL Server_
-        instance as that user. It also possible to instead use impersonation by the
-        parameter **Credential**.
+        The built-in parameter **PSDscRunAsCredential** can run the resource
+        as another user. The resource will then authenticate to the _SQL Server_
+        instance as that user. It is also possible to use impersonation via the
+        **Credential** parameter.

@@
-        When using the built-in parameter **PSDscRunAsCredential** the read-only
-        property **Reasons** will return empty values for the properties **Code**
-        and **Phrase**. The built-in property **PSDscRunAsCredential** does not work
-        together with class-based resources that using advanced type like the parameter
-        **Reasons** have.
+        When using **PSDscRunAsCredential**, the read-only property **Reasons**
+        returns empty values for **Code** and **Phrase**. **PSDscRunAsCredential**
+        does not work with class-based resources that use advanced types such as
+        the **Reasons** parameter.

@@
-        SQL Authentication and Group Managed Service Accounts is not supported as
-        impersonation credentials. Currently only Windows Integrated Security is
+        SQL Authentication and Group Managed Service Accounts are not supported as
+        impersonation credentials. Currently, only Windows Integrated Security is
         supported to use as credentials.

@@
-        (for example a local Windows Server account) account the username must be
+        (for example, a local Windows Server account) the username must be
         provided without the NetBIOS name, e.g. `username`. Using the NetBIOS name, e.g
-        using the format `DOMAIN\username` will not work.
+        `DOMAIN\username`, will not work.

Also applies to: 26-47

tests/Integration/Resources/DSC_SqlAgentAlert.Integration.Tests.ps1 (3)

110-111: Prefer -BeTrue for boolean assertions.

Asserting against the string 'True' is brittle. Use -BeTrue per test guidelines.

-            Test-DscConfiguration -Verbose -ErrorAction 'Stop' | Should -Be 'True'
+            Test-DscConfiguration -Verbose -ErrorAction 'Stop' | Should -BeTrue
-            Test-DscConfiguration -Verbose -ErrorAction 'Stop' | Should -Be 'True'
+            Test-DscConfiguration -Verbose -ErrorAction 'Stop' | Should -BeTrue

Also applies to: 165-167


79-85: Use Get-ComputerName for CI portability.

Hardcoding 'localhost' is discouraged; use Get-ComputerName to align with integration test guidelines.

-                    ComputerName = 'localhost'
+                    ComputerName = (Get-ComputerName)

53-61: Consider migrating this integration test to the class-based resource harness and file naming.

This test still targets “DSC_SqlAgentAlert” and initializes ResourceType 'Mof'. Given the resource is now class-based, consider:

  • Renaming file to tests/Integration/Resources/SqlAgentAlert.Integration.Tests.ps1
  • Updating Initialize-TestEnvironment to the class-based pattern (ResourceType 'Class' or module-level invocation as applicable)
  • Ensuring the config uses the SqlAgentAlert resource directly

If you want, I can draft the updated integration test skeleton aligned with the class-based resource conventions.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

💡 Knowledge Base configuration:

  • Jira integration is disabled
  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 11a2f00 and d74eedd.

📒 Files selected for processing (4)
  • .github/instructions/SqlServerDsc-guidelines.instructions.md (2 hunks)
  • source/Classes/020.SqlAgentAlert.ps1 (1 hunks)
  • tests/Integration/Resources/DSC_SqlAgentAlert.Integration.Tests.ps1 (1 hunks)
  • tests/Integration/Resources/DSC_SqlAgentAlert.config.ps1 (0 hunks)
💤 Files with no reviewable changes (1)
  • tests/Integration/Resources/DSC_SqlAgentAlert.config.ps1
🧰 Additional context used
📓 Path-based instructions (11)
**/*.{ps1,psm1,psd1}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

Always follow PowerShell code style guidelines (./instructions/dsc-community-style-guidelines-powershell.instructions.md)

**/*.{ps1,psm1,psd1}: Use 4 spaces for indentation (no tabs)
One space around operators (e.g., $a = 1 + 2)
No spaces on empty lines
Try to limit lines to 120 characters
Use single quotes unless variable expansion is needed
Arrays single-line: @('one','two','three')
Arrays multi-line: each element on its own indented line
Hashtables empty literal uses @{}
Hashtables multi-line: each property on a separate indented line
Hashtable properties use PascalCase
Single-line comments use '# Comment' style: capitalized, on own line
Multi-line comments use <# #> with brackets on their own lines and indented text
End files with only one blank line
Use CR+LF line endings
Maximum of two consecutive newlines
Use UTF-8 encoding without BOM for all files

Files:

  • tests/Integration/Resources/DSC_SqlAgentAlert.Integration.Tests.ps1
  • source/Classes/020.SqlAgentAlert.ps1
**/*.{ps1,psm1}

📄 CodeRabbit inference engine (.github/instructions/SqlServerDsc-guidelines.instructions.md)

**/*.{ps1,psm1}: Public PowerShell commands must follow the naming format: Verb-SqlDsc{Noun}
Prefer SMO over T-SQL for SQL Server interaction

**/*.{ps1,psm1}: Use descriptive names (3+ characters, no abbreviations)
Function names use PascalCase with Verb-Noun format using approved verbs
Parameter names use PascalCase
Variable names use camelCase
Keywords should be lower-case
Include scope qualifier for script/global/environment variables: $script:, $global:, $env:
One space between type and variable (e.g., [String] $name)
One space between keyword and parenthesis (e.g., if ($condition))
Newline before opening brace (except variable assignments)
One newline after opening brace
Two newlines after closing brace (one if followed by another brace or continuation)
Do not use the unary comma operator in return statements to force an array
Do not keep commented-out code
Always add comment-based help to all functions and scripts
Comment-based help must include SYNOPSIS, DESCRIPTION (40+ chars), PARAMETER, EXAMPLE sections before function/class
Comment-based help indentation: keywords at 4 spaces, text at 8 spaces
Include examples for all parameter sets and combinations in help
INPUTS: list each pipeline-accepted type (one per line) with a 1‑line description
OUTPUTS: list each return type (one per line) with a 1‑line description; must match [OutputType()] and actual returns
.NOTES only when critical (constraints, side effects, security, version compatibility, breaking behavior), ≤2 short sentences
Avoid aliases; use full command names
Avoid Write-Host; prefer Write-Verbose/Write-Information, etc.
Avoid Write-Output; use 'return' instead
Avoid ConvertTo-SecureString -AsPlainText in production code
Do not redefine reserved parameters (Verbose, Debug, etc.)
Include a Force parameter for functions that support ShouldContinue or use ShouldProcess
For state-changing functions, set SupportsShouldProcess
Use $PSCmdlet.ThrowTerminatingError() for terminating errors with relevant ...

Files:

  • tests/Integration/Resources/DSC_SqlAgentAlert.Integration.Tests.ps1
  • source/Classes/020.SqlAgentAlert.ps1
tests/Integration/**/*.Tests.ps1

📄 CodeRabbit inference engine (.github/instructions/SqlServerDsc-guidelines.instructions.md)

Integration tests must call Disconnect-SqlDscDatabaseEngine after Connect-SqlDscDatabaseEngine

Files:

  • tests/Integration/Resources/DSC_SqlAgentAlert.Integration.Tests.ps1
tests/[iI]ntegration/[rR]esources/*.[iI]ntegration.[tT]ests.ps1

📄 CodeRabbit inference engine (.github/instructions/dsc-community-style-guidelines-integration-tests.instructions.md)

Place resource integration tests at tests/Integration/Resources/{ResourceName}.Integration.Tests.ps1

Files:

  • tests/Integration/Resources/DSC_SqlAgentAlert.Integration.Tests.ps1
tests/[iI]ntegration/**/*.[iI]ntegration.[tT]ests.ps1

📄 CodeRabbit inference engine (.github/instructions/dsc-community-style-guidelines-integration-tests.instructions.md)

tests/[iI]ntegration/**/*.[iI]ntegration.[tT]ests.ps1: Include the required Pester setup block (the provided BeforeDiscovery, BeforeAll, module import, and suppression) in every integration test file
Do not use mocking in integration tests; execute against a real environment
Use Get-ComputerName to resolve computer names in CI
Avoid using ExpectedMessage with Should -Throw assertions in Pester
When calling commands, include -Force where applicable to avoid prompts

Files:

  • tests/Integration/Resources/DSC_SqlAgentAlert.Integration.Tests.ps1

⚙️ CodeRabbit configuration file

tests/[iI]ntegration/**/*.[iI]ntegration.[tT]ests.ps1: # Integration Tests Guidelines

Requirements

  • Location Commands: tests/Integration/Commands/{CommandName}.Integration.Tests.ps1
  • Location Resources: tests/Integration/Resources/{ResourceName}.Integration.Tests.ps1
  • No mocking - real environment only
  • Cover all scenarios and code paths
  • Use Get-ComputerName for computer names in CI
  • Avoid ExpectedMessage for Should -Throw assertions
  • Only run integration tests in CI unless explicitly instructed.
  • Call commands with -Force parameter where applicable (avoids prompting).
  • Use -ErrorAction Stop on commands so failures surface immediately

Required Setup Block

[System.Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseDeclaredVarsMoreThanAssignments', '', Justification = 'Suppressing this rule because Script Analyzer does not understand Pester syntax.')]
param ()

BeforeDiscovery {
    try
    {
        if (-not (Get-Module -Name 'DscResource.Test'))
        {
            # Assumes dependencies have 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' 3>&1 4>&1 5>&1 6>&1 > $null
            }

            # If the dependencies have 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'

    Import-Module -Name $script:dscModuleName -Force -ErrorAction 'Stop'
}

Files:

  • tests/Integration/Resources/DSC_SqlAgentAlert.Integration.Tests.ps1
**/*.[Tt]ests.ps1

📄 CodeRabbit inference engine (.github/instructions/dsc-community-style-guidelines-pester.instructions.md)

**/*.[Tt]ests.ps1: Use Pester v5 syntax only
Use exactly one Describe block per test file, named to match the tested entity
Place all test code only inside Describe blocks
Place assertions only inside It blocks
Do not test Write-Verbose, Write-Debug, or parameter binding behavior
Always pass all mandatory parameters in tests to avoid prompts
Each scenario should be a separate Context block
Use nested Context blocks for complex scenarios
Define mocks in BeforeAll (use BeforeEach for mocking only when required)
Place setup/teardown in the nearest appropriate BeforeAll/BeforeEach/AfterAll/AfterEach to where it is used
Use PascalCase for Pester keywords: Describe, Context, It, Should, BeforeAll, BeforeEach, AfterAll, AfterEach
Start It descriptions with 'Should'
Start Context descriptions with 'When'
Prefix mock variables with 'mock'
Prefer -BeTrue and -BeFalse over -Be $true and -Be $false
Do not use 'Should -Not -Throw'; invoke commands directly instead
For data-driven tests, define variables in a separate BeforeDiscovery for -ForEach close to usage
Use -ForEach only on Context and It blocks
Keep variable and mock scope as close as possible to the usage context
Assign unused return objects to $null
Invoke the tested entity from within It blocks only
Keep results and assertions within the same It block
Use BeforeEach and AfterEach sparingly
Avoid try/catch/finally for cleanup; use AfterAll or AfterEach instead

Files:

  • tests/Integration/Resources/DSC_SqlAgentAlert.Integration.Tests.ps1

⚙️ CodeRabbit configuration file

**/*.[Tt]ests.ps1: # Tests Guidelines

Core Requirements

  • All public commands, private functions and classes must have unit tests
  • All public commands and class-based resources must have integration tests
  • Use Pester v5 syntax only
  • One Describe block per file matching the tested entity name
  • Test code only inside Describe blocks
  • Assertions only in It blocks
  • Never test verbose messages, debug messages or parameter binding behavior
  • Pass all mandatory parameters to avoid prompts

Structure & Scope

  • Public commands: Never use InModuleScope (unless retrieving localized strings)
  • Private functions/class resources: Always use InModuleScope
  • Each scenario = separate Context block
  • Use nested Context blocks for complex scenarios
  • Mocking in BeforeAll (BeforeEach only when required)
  • Setup/teardown in BeforeAll,BeforeEach/AfterAll,AfterEach close to usage

Syntax Rules

  • PascalCase: Describe, Context, It, Should, BeforeAll, BeforeEach, AfterAll, AfterEach
  • Context descriptions start with 'When'
  • It descriptions start with 'Should', must not contain 'when'
  • Mock variables prefix: 'mock'
  • Prefer -BeTrue/-BeFalse over -Be $true/-Be $false
  • No Should -Not -Throw - invoke commands directly
  • Never add an empty -MockWith block
  • Omit -MockWith when returning $null
  • Set $PSDefaultParameterValues for Mock:ModuleName, Should:ModuleName, InModuleScope:ModuleName
  • Omit -ModuleName parameter on Pester commands

File Organization

  • Class resources: tests/Unit/Classes/{Name}.Tests.ps1
  • Public commands: tests/Unit/Public/{Name}.Tests.ps1
  • Private functions: tests/Unit/Private/{Name}.Tests.ps1

Data-Driven Tests

  • Define variables in separate BeforeDiscovery for -ForEach (close to usage)
  • -ForEach allowed on Context and It blocks
  • Keep scope close to usage context

Best Practices

  • Inside It blocks, assign unused return objects to $null (unless part of ...

Files:

  • tests/Integration/Resources/DSC_SqlAgentAlert.Integration.Tests.ps1
**

⚙️ CodeRabbit configuration file

**: # DSC Community Guidelines

Terminology

  • Command: Public command
  • Function: Private function
  • Resource: DSC class-based resource

Build & Test Workflow

  • Run project scripts in PowerShell from repository root
  • Build after source changes: .\build.ps1 -Tasks build
  • Test workflow: Build → Invoke-Pester -Path @('<test paths>') -Output Detailed
  • New session required after class changes

File Organization

  • Public commands: source/Public/{CommandName}.ps1
  • Private functions: source/Private/{FunctionName}.ps1
  • Unit tests: tests/Unit/{Classes|Public|Private}/{Name}.Tests.ps1
  • Integration tests: tests/Integration/Commands/{CommandName}.Integration.Tests.ps1

Requirements

  • Follow guidelines over existing code patterns
  • Always update CHANGELOG.md Unreleased section
  • Localize all strings using string keys; remove any orphaned string keys
  • Check DscResource.Common before creating private functions
  • Separate reusable logic into private functions
  • Add unit tests for all commands/functions/resources
  • Add integration tests for all public commands and resources

Files:

  • tests/Integration/Resources/DSC_SqlAgentAlert.Integration.Tests.ps1
  • source/Classes/020.SqlAgentAlert.ps1
**/*.ps?(m|d)1

⚙️ CodeRabbit configuration file

**/*.ps?(m|d)1: # PowerShell Guidelines

Naming

  • Use descriptive names (3+ characters, no abbreviations)
  • Functions: PascalCase with Verb-Noun format using approved verbs
  • Parameters: PascalCase
  • Variables: camelCase
  • Keywords: lower-case
  • Classes: PascalCase
  • Include scope for script/global/environment variables: $script:, $global:, $env:

File naming

  • Class files: ###.ClassName.ps1 format (e.g. 001.SqlReason.ps1, 004.StartupParameters.ps1)

Formatting

Indentation & Spacing

  • Use 4 spaces (no tabs)
  • One space around operators: $a = 1 + 2
  • One space between type and variable: [String] $name
  • One space between keyword and parenthesis: if ($condition)
  • No spaces on empty lines
  • Try to limit lines to 120 characters

Braces

  • Newline before opening brace (except variable assignments)
  • One newline after opening brace
  • Two newlines after closing brace (one if followed by another brace or continuation)

Quotes

  • Use single quotes unless variable expansion is needed: 'text' vs "text $variable"

Arrays

  • Single line: @('one', 'two', 'three')
  • Multi-line: each element on separate line with proper indentation
  • Do not use the unary comma operator (,) in return statements to force
    an array

Hashtables

  • Empty: @{}
  • Multi-line: each property on separate line with proper indentation
  • Properties: Use PascalCase

Comments

  • Single line: # Comment (capitalized, on own line)
  • Multi-line: <# Comment #> format (opening and closing brackets on own line), and indent text
  • No commented-out code

Comment-based help

  • Always add comment-based help to all functions and scripts
  • Comment-based help: SYNOPSIS, DESCRIPTION (40+ chars), PARAMETER, EXAMPLE sections before function/class
  • Comment-based help indentation: keywords 4 spaces, text 8 spaces
  • Include examples for all parameter sets and combinations
  • INPUTS: List each pipeline‑accepted type (one per line) with a 1‑line description.
  • ...

Files:

  • tests/Integration/Resources/DSC_SqlAgentAlert.Integration.Tests.ps1
  • source/Classes/020.SqlAgentAlert.ps1
source/[cC]lasses/*.ps1

📄 CodeRabbit inference engine (.github/instructions/dsc-community-style-guidelines-class-resource.instructions.md)

Place each DSC class-based resource in source/Classes/{ResourceName}.ps1

Files:

  • source/Classes/020.SqlAgentAlert.ps1
source/[cC]lasses/**/*.ps1

📄 CodeRabbit inference engine (.github/instructions/dsc-community-style-guidelines-class-resource.instructions.md)

source/[cC]lasses/**/*.ps1: Decorate the resource class with [DscResource(RunAsCredential = 'Optional')] (use 'Mandatory' if required)
Only classes with a [DscResource(...)] decoration are considered DSC resources to which these rules apply
Resource classes must inherit ResourceBase (from the DscResource.Base module)
Use $this.localizedData provided by ResourceBase (auto-populated from the localization file); do not manually populate it
Implement Get() that delegates to ([ResourceBase] $this).Get(), optionally post-processes, and returns the current state object
Implement Test() that delegates to ([ResourceBase] $this).Test(), optionally post-processes, and returns a [System.Boolean]
Implement Set() that delegates to ([ResourceBase] $this).Set(), with optional additional changes not handled by Modify()
Implement hidden [System.Collections.Hashtable] GetCurrentState([System.Collections.Hashtable] $properties) to return current state
Implement hidden [void] Modify([System.Collections.Hashtable] $properties) to set desired state only for non-compliant properties
Implement hidden [void] AssertProperties([System.Collections.Hashtable] $properties) to validate user-provided properties
Implement hidden [void] NormalizeProperties([System.Collections.Hashtable] $properties) to normalize user-provided properties

Files:

  • source/Classes/020.SqlAgentAlert.ps1

⚙️ CodeRabbit configuration file

source/[cC]lasses/**/*.ps1: # DSC Class-Based Resource Guidelines

Applies to: Classes with [DscResource(...)] decoration only.

Requirements

  • File: source/Classes/020.{ResourceName}.ps1
  • Decoration: [DscResource(RunAsCredential = 'Optional')] (replace with 'Mandatory' if required)
  • Inheritance: Must inherit ResourceBase (part of module DscResource.Base)
  • $this.localizedData hashtable auto-populated by ResourceBase from localization file

Required constructor

MyResourceName () : base ($PSScriptRoot)
{
    # Property names where state cannot be enforced, e.g Ensure
    $this.ExcludeDscProperties = @()
}

Required Method Pattern

[MyResourceName] Get()
{
    # Call base implementation to get current state
    $currentState = ([ResourceBase] $this).Get()

    # If needed, post-processing on current state that can not be handled by GetCurrentState()

    return $currentState
}

[System.Boolean] Test()
{
    # Call base implementation to test current state
    $inDesiredState = ([ResourceBase] $this).Test()

    # If needed, post-processing on test result that can not be handled by base Test()

    return $inDesiredState
}

[void] Set()
{
    # Call base implementation to set desired state
    ([ResourceBase] $this).Set()

    # If needed, additional state changes that can not be handled by Modify()
}

hidden [System.Collections.Hashtable] GetCurrentState([System.Collections.Hashtable] $properties)
{
    # Always return current state as hashtable, $properties contains key properties
}

hidden [void] Modify([System.Collections.Hashtable] $properties)
{
    # Always set desired state, $properties contain those that must change state
}

Optional Method Pattern

hidden [void] AssertProperties([System.Collections.Hashtable] $properties)
{
    # Validate user-provided properties, $properties contains user assigned values
}

hidden [void] NormalizeProperties([System.Collections.Hashtable] $pr...

Files:

  • source/Classes/020.SqlAgentAlert.ps1
source/**/*.ps1

📄 CodeRabbit inference engine (.github/instructions/dsc-community-style-guidelines-localization.instructions.md)

source/**/*.ps1: Localize all Write-Debug, Write-Verbose, Write-Error, Write-Warning, and $PSCmdlet.ThrowTerminatingError() messages
Do not hardcode user-facing strings; use localized string keys instead
Access localized strings via $script:localizedData, formatting with -f when needed

Localize all strings in source code using string keys

Files:

  • source/Classes/020.SqlAgentAlert.ps1

⚙️ CodeRabbit configuration file

source/**/*.ps1: # Localization Guidelines

Requirements

  • Localize all Write-Debug, Write-Verbose, Write-Error, Write-Warning and $PSCmdlet.ThrowTerminatingError() messages
  • Use localized string keys, not hardcoded strings
  • Assume $script:localizedData is available

String Files

  • Commands/functions: source/en-US/SqlServerDsc.strings.psd1
  • Class resources: source/en-US/{ResourceClassName}.strings.psd1

Key Naming Patterns

  • Format: Verb_FunctionName_Action (underscore separators), e.g. Get_SqlDscDatabase_ConnectingToDatabase

String Format

ConvertFrom-StringData @'
    KeyName = Message with {0} placeholder. (PREFIX0001)
'@

String IDs

  • Format: (PREFIX####)
  • PREFIX: First letter of each word in class or function name (SqlSetup → SS, Get-SqlDscDatabase → GSDD)
  • Number: Sequential from 0001

Usage

Write-Verbose -Message ($script:localizedData.KeyName -f $value1)

Files:

  • source/Classes/020.SqlAgentAlert.ps1
🧠 Learnings (22)
📓 Common learnings
Learnt from: CR
PR: dsccommunity/SqlServerDsc#0
File: .github/instructions/SqlServerDsc-guidelines.instructions.md:0-0
Timestamp: 2025-08-25T10:04:53.158Z
Learning: Applies to **/DSCResources/**.{ps1,psm1} : Database Engine DSC resources must inherit the SqlResourceBase base class
📚 Learning: 2025-08-25T10:04:53.158Z
Learnt from: CR
PR: dsccommunity/SqlServerDsc#0
File: .github/instructions/SqlServerDsc-guidelines.instructions.md:0-0
Timestamp: 2025-08-25T10:04:53.158Z
Learning: Applies to tests/Unit/**/*.Tests.ps1 : Unit tests must set $env:SqlServerDscCI = $true in BeforeAll and remove it in AfterAll

Applied to files:

  • tests/Integration/Resources/DSC_SqlAgentAlert.Integration.Tests.ps1
  • .github/instructions/SqlServerDsc-guidelines.instructions.md
📚 Learning: 2025-08-25T10:05:48.627Z
Learnt from: CR
PR: dsccommunity/SqlServerDsc#0
File: .github/instructions/dsc-community-style-guidelines-integration-tests.instructions.md:0-0
Timestamp: 2025-08-25T10:05:48.627Z
Learning: Applies to tests/[iI]ntegration/[rR]esources/*.[iI]ntegration.[tT]ests.ps1 : Place resource integration tests at tests/Integration/Resources/{ResourceName}.Integration.Tests.ps1

Applied to files:

  • tests/Integration/Resources/DSC_SqlAgentAlert.Integration.Tests.ps1
📚 Learning: 2025-08-25T10:05:48.627Z
Learnt from: CR
PR: dsccommunity/SqlServerDsc#0
File: .github/instructions/dsc-community-style-guidelines-integration-tests.instructions.md:0-0
Timestamp: 2025-08-25T10:05:48.627Z
Learning: Applies to tests/[iI]ntegration/**/*.[iI]ntegration.[tT]ests.ps1 : Avoid using ExpectedMessage with Should -Throw assertions in Pester

Applied to files:

  • tests/Integration/Resources/DSC_SqlAgentAlert.Integration.Tests.ps1
📚 Learning: 2025-08-25T10:04:53.158Z
Learnt from: CR
PR: dsccommunity/SqlServerDsc#0
File: .github/instructions/SqlServerDsc-guidelines.instructions.md:0-0
Timestamp: 2025-08-25T10:04:53.158Z
Learning: Applies to tests/Integration/**/*.Tests.ps1 : Integration tests must call Disconnect-SqlDscDatabaseEngine after Connect-SqlDscDatabaseEngine

Applied to files:

  • tests/Integration/Resources/DSC_SqlAgentAlert.Integration.Tests.ps1
📚 Learning: 2025-08-25T10:07:22.349Z
Learnt from: CR
PR: dsccommunity/SqlServerDsc#0
File: .github/instructions/dsc-community-style-guidelines-mof-resources.instructions.md:0-0
Timestamp: 2025-08-25T10:07:22.349Z
Learning: Applies to source/DSCResources/**/*.psm1 : Test-TargetResource verbose message should start with "Determining the current state of..."

Applied to files:

  • tests/Integration/Resources/DSC_SqlAgentAlert.Integration.Tests.ps1
📚 Learning: 2025-08-25T10:04:53.158Z
Learnt from: CR
PR: dsccommunity/SqlServerDsc#0
File: .github/instructions/SqlServerDsc-guidelines.instructions.md:0-0
Timestamp: 2025-08-25T10:04:53.158Z
Learning: Applies to **/DSCResources/**.{ps1,psm1} : Database Engine DSC resources must inherit the SqlResourceBase base class

Applied to files:

  • source/Classes/020.SqlAgentAlert.ps1
  • .github/instructions/SqlServerDsc-guidelines.instructions.md
📚 Learning: 2025-08-25T10:05:30.603Z
Learnt from: CR
PR: dsccommunity/SqlServerDsc#0
File: .github/instructions/dsc-community-style-guidelines-class-resource.instructions.md:0-0
Timestamp: 2025-08-25T10:05:30.603Z
Learning: Applies to source/[cC]lasses/**/*.ps1 : Resource classes must inherit ResourceBase (from the DscResource.Base module)

Applied to files:

  • source/Classes/020.SqlAgentAlert.ps1
📚 Learning: 2025-08-25T10:04:53.158Z
Learnt from: CR
PR: dsccommunity/SqlServerDsc#0
File: .github/instructions/SqlServerDsc-guidelines.instructions.md:0-0
Timestamp: 2025-08-25T10:04:53.158Z
Learning: Applies to **/DSCResources/**.{ps1,psm1} : Resources inheriting SqlResourceBase should use its provided members: InstanceName, ServerName, Credential, Reasons, and GetServerObject()

Applied to files:

  • source/Classes/020.SqlAgentAlert.ps1
  • .github/instructions/SqlServerDsc-guidelines.instructions.md
📚 Learning: 2025-08-25T10:05:30.603Z
Learnt from: CR
PR: dsccommunity/SqlServerDsc#0
File: .github/instructions/dsc-community-style-guidelines-class-resource.instructions.md:0-0
Timestamp: 2025-08-25T10:05:30.603Z
Learning: Applies to source/[cC]lasses/**/*.ps1 : Implement hidden [void] AssertProperties([System.Collections.Hashtable] $properties) to validate user-provided properties

Applied to files:

  • source/Classes/020.SqlAgentAlert.ps1
📚 Learning: 2025-08-25T10:04:22.244Z
Learnt from: CR
PR: dsccommunity/SqlServerDsc#0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-08-25T10:04:22.244Z
Learning: Follow SqlServerDsc project specific guidelines (./instructions/SqlServerDsc-guidelines.instructions.md)

Applied to files:

  • .github/instructions/SqlServerDsc-guidelines.instructions.md
📚 Learning: 2025-08-25T10:04:22.244Z
Learnt from: CR
PR: dsccommunity/SqlServerDsc#0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-08-25T10:04:22.244Z
Learning: SqlServerDsc-specific guidelines override general project guidelines

Applied to files:

  • .github/instructions/SqlServerDsc-guidelines.instructions.md
📚 Learning: 2025-08-17T10:13:30.079Z
Learnt from: johlju
PR: dsccommunity/SqlServerDsc#2136
File: source/Public/Remove-SqlDscLogin.ps1:104-108
Timestamp: 2025-08-17T10:13:30.079Z
Learning: In SqlServerDsc unit tests, SMO object stubs (like Login objects) should have properly mocked Parent properties with correct Server stub types and valid InstanceName values, rather than handling null Parent scenarios in production code.

Applied to files:

  • .github/instructions/SqlServerDsc-guidelines.instructions.md
📚 Learning: 2025-08-25T10:04:53.158Z
Learnt from: CR
PR: dsccommunity/SqlServerDsc#0
File: .github/instructions/SqlServerDsc-guidelines.instructions.md:0-0
Timestamp: 2025-08-25T10:04:53.158Z
Learning: Applies to **/*.{ps1,psm1} : Prefer SMO over T-SQL for SQL Server interaction

Applied to files:

  • .github/instructions/SqlServerDsc-guidelines.instructions.md
📚 Learning: 2025-08-25T10:04:53.158Z
Learnt from: CR
PR: dsccommunity/SqlServerDsc#0
File: .github/instructions/SqlServerDsc-guidelines.instructions.md:0-0
Timestamp: 2025-08-25T10:04:53.158Z
Learning: Applies to tests/Unit/**/*.Tests.ps1 : In unit tests, use SMO stub types defined in SMO.cs

Applied to files:

  • .github/instructions/SqlServerDsc-guidelines.instructions.md
📚 Learning: 2025-08-25T10:04:53.158Z
Learnt from: CR
PR: dsccommunity/SqlServerDsc#0
File: .github/instructions/SqlServerDsc-guidelines.instructions.md:0-0
Timestamp: 2025-08-25T10:04:53.158Z
Learning: Applies to tests/Unit/**/*.Tests.ps1 : In unit tests, do not mock SMO types directly

Applied to files:

  • .github/instructions/SqlServerDsc-guidelines.instructions.md
📚 Learning: 2025-08-25T10:04:53.158Z
Learnt from: CR
PR: dsccommunity/SqlServerDsc#0
File: .github/instructions/SqlServerDsc-guidelines.instructions.md:0-0
Timestamp: 2025-08-25T10:04:53.158Z
Learning: After changing SMO.cs, run tests in a new PowerShell session

Applied to files:

  • .github/instructions/SqlServerDsc-guidelines.instructions.md
📚 Learning: 2025-08-25T10:04:53.158Z
Learnt from: CR
PR: dsccommunity/SqlServerDsc#0
File: .github/instructions/SqlServerDsc-guidelines.instructions.md:0-0
Timestamp: 2025-08-25T10:04:53.158Z
Learning: Applies to azure-pipelines.yml : Choose the appropriate integration test group number in azure-pipelines.yml based on required dependencies

Applied to files:

  • .github/instructions/SqlServerDsc-guidelines.instructions.md
📚 Learning: 2025-08-25T10:07:49.137Z
Learnt from: CR
PR: dsccommunity/SqlServerDsc#0
File: .github/instructions/dsc-community-style-guidelines-pester.instructions.md:0-0
Timestamp: 2025-08-25T10:07:49.137Z
Learning: Applies to **/*.[Tt]ests.ps1 : Define mocks in BeforeAll (use BeforeEach for mocking only when required)

Applied to files:

  • .github/instructions/SqlServerDsc-guidelines.instructions.md
📚 Learning: 2025-08-25T10:09:27.870Z
Learnt from: CR
PR: dsccommunity/SqlServerDsc#0
File: .github/instructions/dsc-community-style-guidelines-unit-tests.instructions.md:0-0
Timestamp: 2025-08-25T10:09:27.870Z
Learning: After modifying classes, always run tests in a new PowerShell session to pick up changes

Applied to files:

  • .github/instructions/SqlServerDsc-guidelines.instructions.md
📚 Learning: 2025-08-25T10:05:48.627Z
Learnt from: CR
PR: dsccommunity/SqlServerDsc#0
File: .github/instructions/dsc-community-style-guidelines-integration-tests.instructions.md:0-0
Timestamp: 2025-08-25T10:05:48.627Z
Learning: Applies to tests/[iI]ntegration/**/*.[iI]ntegration.[tT]ests.ps1 : Do not use mocking in integration tests; execute against a real environment

Applied to files:

  • .github/instructions/SqlServerDsc-guidelines.instructions.md
📚 Learning: 2025-08-25T10:07:49.137Z
Learnt from: CR
PR: dsccommunity/SqlServerDsc#0
File: .github/instructions/dsc-community-style-guidelines-pester.instructions.md:0-0
Timestamp: 2025-08-25T10:07:49.137Z
Learning: Applies to **/*.[Tt]ests.ps1 : Keep variable and mock scope as close as possible to the usage context

Applied to files:

  • .github/instructions/SqlServerDsc-guidelines.instructions.md
🧬 Code graph analysis (2)
source/Classes/020.SqlAgentAlert.ps1 (1)
tests/Unit/Stubs/SMO.cs (2)
  • Alert (1604-1646)
  • Microsoft (1499-1649)
.github/instructions/SqlServerDsc-guidelines.instructions.md (1)
tests/Unit/Stubs/SMO.cs (9)
  • Microsoft (12-1048)
  • Microsoft (1086-1497)
  • Server (278-373)
  • Database (558-617)
  • SmoException (664-671)
  • Login (379-532)
  • Service (1149-1181)
  • Microsoft (1050-1084)
  • SqlServerManagementException (651-658)
🪛 markdownlint-cli2 (0.17.2)
.github/instructions/SqlServerDsc-guidelines.instructions.md

14-14: Line length
Expected: 80; Actual: 116

(MD013, line-length)


15-15: Line length
Expected: 80; Actual: 106

(MD013, line-length)


38-38: Lists should be surrounded by blank lines

(MD032, blanks-around-lists)


41-41: Line length
Expected: 80; Actual: 100

(MD013, line-length)

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

[grammar] ~41-~41: There might be a mistake here.
Context: ...hell session for changes to take effect.

(QB_NEW_EN)

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
  • GitHub Check: dsccommunity.SqlServerDsc (Build Package Module)
  • GitHub Check: PSScriptAnalyzer
  • GitHub Check: PSScriptAnalyzer
🔇 Additional comments (2)
source/Classes/020.SqlAgentAlert.ps1 (1)

115-117: Resource skeleton looks correct (attribute + base class).

Decorated with [DscResource(RunAsCredential = 'Optional')] and inheriting SqlResourceBase as expected for SQL Database Engine resources. Good use of $this.localizedData and base Get/Test/Set pattern.

tests/Integration/Resources/DSC_SqlAgentAlert.Integration.Tests.ps1 (1)

161-163: LGTM: Name asserted explicitly in Absent path.

Asserting Name equals the configured value when Ensure = 'Absent' matches the resource’s GetCurrentState implementation (Name is always populated). Good adjustment.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

♻️ Duplicate comments (2)
source/Classes/020.SqlAgentAlert.ps1 (2)

127-136: Align allowed ranges with GetCurrentState semantics (and update help).

GetCurrentState treats values as “set” only when > 0. Allowing 0 for Severity/MessageId introduces an idempotency gap: Desired value 0 will never be observed as current, causing perpetual drift. Tighten ranges to start at 1 and update the parameter help to match.

@@
-    .PARAMETER Severity
-        The severity of the _SQL Server Agent_ alert. Valid range is 0 to 25.
+    .PARAMETER Severity
+        The severity of the _SQL Server Agent_ alert. Valid range is 1 to 25.
         Cannot be used together with **MessageId**.
@@
-    .PARAMETER MessageId
-        The message id of the _SQL Server Agent_ alert. Valid range is 0 to 2147483647.
+    .PARAMETER MessageId
+        The message id of the _SQL Server Agent_ alert. Valid range is 1 to 2147483647.
         Cannot be used together with **Severity**.
@@
-    [ValidateRange(0, 25)]
+    [ValidateRange(1, 25)]
     [Nullable[System.Int32]]
     $Severity
@@
-    [ValidateRange(0, 2147483647)]
+    [ValidateRange(1, 2147483647)]
     [Nullable[System.Int32]]
     $MessageId

If you must support 0, instead change GetCurrentState comparisons from -gt 0 to -ge 0 and keep the help text as-is.

Also applies to: 204-213, 55-62


262-275: When switching between Severity and MessageId, clear the non-selected property.

If an existing alert has Severity and desired state specifies MessageId (or vice versa), current code sets the new property but never clears the old one. Persisting both can violate SQL Agent alert invariants and yield confusing state. Ensure the opposite property is cleared to 0.

-                if ($properties.ContainsKey('Severity') -and $alertObject.Severity -ne $properties.Severity)
-                {
-                    $setAlertParameters.Severity = $properties.Severity
-                    $needsUpdate = $true
-                }
-
-                if ($properties.ContainsKey('MessageId') -and $alertObject.MessageId -ne $properties.MessageId)
-                {
-                    $setAlertParameters.MessageId = $properties.MessageId
-                    $needsUpdate = $true
-                }
+                # If Severity is desired, set it and clear MessageId
+                if ($properties.ContainsKey('Severity'))
+                {
+                    if ($alertObject.Severity -ne $properties.Severity)
+                    {
+                        $setAlertParameters.Severity = $properties.Severity
+                        $needsUpdate = $true
+                    }
+
+                    if ($alertObject.MessageId -ne 0)
+                    {
+                        $setAlertParameters.MessageId = 0
+                        $needsUpdate = $true
+                    }
+                }
+
+                # If MessageId is desired, set it and clear Severity
+                if ($properties.ContainsKey('MessageId'))
+                {
+                    if ($alertObject.MessageId -ne $properties.MessageId)
+                    {
+                        $setAlertParameters.MessageId = $properties.MessageId
+                        $needsUpdate = $true
+                    }
+
+                    if ($alertObject.Severity -ne 0)
+                    {
+                        $setAlertParameters.Severity = 0
+                        $needsUpdate = $true
+                    }
+                }

Consider adding unit tests for Severity→MessageId and MessageId→Severity transitions that assert the cleared field is 0.

🧹 Nitpick comments (3)
source/Classes/020.SqlAgentAlert.ps1 (3)

118-121: Key property should guard against null/empty.

Add [ValidateNotNullOrEmpty()] to the Key property Name to fail fast and align with typical SqlServerDsc patterns for key identifiers.

     [DscProperty(Key)]
-    [System.String]
-    $Name
+    [ValidateNotNullOrEmpty()]
+    [System.String]
+    $Name

169-181: Clean up commented code and clarify validation intent.

Guidelines say not to keep commented-out code. Since Assert-BoundParameter with -MutuallyExclusiveList1/-MutuallyExclusiveList2 enforces “exactly one present,” the AtLeastOneList TODO is redundant. Tighten the comment and remove dead code.

-        # TODO: Waiting for issue: https://github.com/dsccommunity/DscResource.Common/issues/160
         if ($properties.Ensure -eq 'Present')
         {
-            # Validate that at least one of Severity or MessageId is specified
-            # TODO: Waiting for issue: https://github.com/dsccommunity/DscResource.Common/issues/161
-            #Assert-BoundParameter -BoundParameterList $properties -AtLeastOneList @('Severity', 'MessageId')
-
-            # Validate that both Severity and MessageId are not specified
+            # Require exactly one of Severity or MessageId (handles presence + mutual exclusivity)
             Assert-BoundParameter -BoundParameterList $properties -MutuallyExclusiveList1 @('Severity') -MutuallyExclusiveList2 @('MessageId')
         }

55-62: Help text: document the “exactly one” requirement explicitly.

Since Assert-BoundParameter enforces exactly one of Severity/MessageId when Ensure = 'Present', reflect that in help to guide authors and avoid confusion.

-    .PARAMETER Severity
-        The severity of the _SQL Server Agent_ alert. Valid range is 0 to 25.
-        Cannot be used together with **MessageId**.
+    .PARAMETER Severity
+        The severity of the _SQL Server Agent_ alert. Valid range is 1 to 25.
+        Exactly one of **Severity** or **MessageId** must be specified when **Ensure** = 'Present'.
@@
-    .PARAMETER MessageId
-        The message id of the _SQL Server Agent_ alert. Valid range is 0 to 2147483647.
-        Cannot be used together with **Severity**.
+    .PARAMETER MessageId
+        The message id of the _SQL Server Agent_ alert. Valid range is 1 to 2147483647.
+        Exactly one of **MessageId** or **Severity** must be specified when **Ensure** = 'Present'.
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

💡 Knowledge Base configuration:

  • Jira integration is disabled
  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between d74eedd and 9a5cba3.

📒 Files selected for processing (1)
  • source/Classes/020.SqlAgentAlert.ps1 (1 hunks)
🧰 Additional context used
📓 Path-based instructions (7)
**/*.{ps1,psm1,psd1}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

Always follow PowerShell code style guidelines (./instructions/dsc-community-style-guidelines-powershell.instructions.md)

**/*.{ps1,psm1,psd1}: Use 4 spaces for indentation (no tabs)
One space around operators (e.g., $a = 1 + 2)
No spaces on empty lines
Try to limit lines to 120 characters
Use single quotes unless variable expansion is needed
Arrays single-line: @('one','two','three')
Arrays multi-line: each element on its own indented line
Hashtables empty literal uses @{}
Hashtables multi-line: each property on a separate indented line
Hashtable properties use PascalCase
Single-line comments use '# Comment' style: capitalized, on own line
Multi-line comments use <# #> with brackets on their own lines and indented text
End files with only one blank line
Use CR+LF line endings
Maximum of two consecutive newlines
Use UTF-8 encoding without BOM for all files

Files:

  • source/Classes/020.SqlAgentAlert.ps1
**/*.{ps1,psm1}

📄 CodeRabbit inference engine (.github/instructions/SqlServerDsc-guidelines.instructions.md)

**/*.{ps1,psm1}: Public PowerShell commands must follow the naming format: Verb-SqlDsc{Noun}
Prefer SMO over T-SQL for SQL Server interaction

**/*.{ps1,psm1}: Use descriptive names (3+ characters, no abbreviations)
Function names use PascalCase with Verb-Noun format using approved verbs
Parameter names use PascalCase
Variable names use camelCase
Keywords should be lower-case
Include scope qualifier for script/global/environment variables: $script:, $global:, $env:
One space between type and variable (e.g., [String] $name)
One space between keyword and parenthesis (e.g., if ($condition))
Newline before opening brace (except variable assignments)
One newline after opening brace
Two newlines after closing brace (one if followed by another brace or continuation)
Do not use the unary comma operator in return statements to force an array
Do not keep commented-out code
Always add comment-based help to all functions and scripts
Comment-based help must include SYNOPSIS, DESCRIPTION (40+ chars), PARAMETER, EXAMPLE sections before function/class
Comment-based help indentation: keywords at 4 spaces, text at 8 spaces
Include examples for all parameter sets and combinations in help
INPUTS: list each pipeline-accepted type (one per line) with a 1‑line description
OUTPUTS: list each return type (one per line) with a 1‑line description; must match [OutputType()] and actual returns
.NOTES only when critical (constraints, side effects, security, version compatibility, breaking behavior), ≤2 short sentences
Avoid aliases; use full command names
Avoid Write-Host; prefer Write-Verbose/Write-Information, etc.
Avoid Write-Output; use 'return' instead
Avoid ConvertTo-SecureString -AsPlainText in production code
Do not redefine reserved parameters (Verbose, Debug, etc.)
Include a Force parameter for functions that support ShouldContinue or use ShouldProcess
For state-changing functions, set SupportsShouldProcess
Use $PSCmdlet.ThrowTerminatingError() for terminating errors with relevant ...

Files:

  • source/Classes/020.SqlAgentAlert.ps1
source/[cC]lasses/*.ps1

📄 CodeRabbit inference engine (.github/instructions/dsc-community-style-guidelines-class-resource.instructions.md)

Place each DSC class-based resource in source/Classes/{ResourceName}.ps1

Files:

  • source/Classes/020.SqlAgentAlert.ps1
source/[cC]lasses/**/*.ps1

📄 CodeRabbit inference engine (.github/instructions/dsc-community-style-guidelines-class-resource.instructions.md)

source/[cC]lasses/**/*.ps1: Decorate the resource class with [DscResource(RunAsCredential = 'Optional')] (use 'Mandatory' if required)
Only classes with a [DscResource(...)] decoration are considered DSC resources to which these rules apply
Resource classes must inherit ResourceBase (from the DscResource.Base module)
Use $this.localizedData provided by ResourceBase (auto-populated from the localization file); do not manually populate it
Implement Get() that delegates to ([ResourceBase] $this).Get(), optionally post-processes, and returns the current state object
Implement Test() that delegates to ([ResourceBase] $this).Test(), optionally post-processes, and returns a [System.Boolean]
Implement Set() that delegates to ([ResourceBase] $this).Set(), with optional additional changes not handled by Modify()
Implement hidden [System.Collections.Hashtable] GetCurrentState([System.Collections.Hashtable] $properties) to return current state
Implement hidden [void] Modify([System.Collections.Hashtable] $properties) to set desired state only for non-compliant properties
Implement hidden [void] AssertProperties([System.Collections.Hashtable] $properties) to validate user-provided properties
Implement hidden [void] NormalizeProperties([System.Collections.Hashtable] $properties) to normalize user-provided properties

Files:

  • source/Classes/020.SqlAgentAlert.ps1

⚙️ CodeRabbit configuration file

source/[cC]lasses/**/*.ps1: # DSC Class-Based Resource Guidelines

Applies to: Classes with [DscResource(...)] decoration only.

Requirements

  • File: source/Classes/020.{ResourceName}.ps1
  • Decoration: [DscResource(RunAsCredential = 'Optional')] (replace with 'Mandatory' if required)
  • Inheritance: Must inherit ResourceBase (part of module DscResource.Base)
  • $this.localizedData hashtable auto-populated by ResourceBase from localization file

Required constructor

MyResourceName () : base ($PSScriptRoot)
{
    # Property names where state cannot be enforced, e.g Ensure
    $this.ExcludeDscProperties = @()
}

Required Method Pattern

[MyResourceName] Get()
{
    # Call base implementation to get current state
    $currentState = ([ResourceBase] $this).Get()

    # If needed, post-processing on current state that can not be handled by GetCurrentState()

    return $currentState
}

[System.Boolean] Test()
{
    # Call base implementation to test current state
    $inDesiredState = ([ResourceBase] $this).Test()

    # If needed, post-processing on test result that can not be handled by base Test()

    return $inDesiredState
}

[void] Set()
{
    # Call base implementation to set desired state
    ([ResourceBase] $this).Set()

    # If needed, additional state changes that can not be handled by Modify()
}

hidden [System.Collections.Hashtable] GetCurrentState([System.Collections.Hashtable] $properties)
{
    # Always return current state as hashtable, $properties contains key properties
}

hidden [void] Modify([System.Collections.Hashtable] $properties)
{
    # Always set desired state, $properties contain those that must change state
}

Optional Method Pattern

hidden [void] AssertProperties([System.Collections.Hashtable] $properties)
{
    # Validate user-provided properties, $properties contains user assigned values
}

hidden [void] NormalizeProperties([System.Collections.Hashtable] $pr...

Files:

  • source/Classes/020.SqlAgentAlert.ps1
source/**/*.ps1

📄 CodeRabbit inference engine (.github/instructions/dsc-community-style-guidelines-localization.instructions.md)

source/**/*.ps1: Localize all Write-Debug, Write-Verbose, Write-Error, Write-Warning, and $PSCmdlet.ThrowTerminatingError() messages
Do not hardcode user-facing strings; use localized string keys instead
Access localized strings via $script:localizedData, formatting with -f when needed

Localize all strings in source code using string keys

Files:

  • source/Classes/020.SqlAgentAlert.ps1

⚙️ CodeRabbit configuration file

source/**/*.ps1: # Localization Guidelines

Requirements

  • Localize all Write-Debug, Write-Verbose, Write-Error, Write-Warning and $PSCmdlet.ThrowTerminatingError() messages
  • Use localized string keys, not hardcoded strings
  • Assume $script:localizedData is available

String Files

  • Commands/functions: source/en-US/SqlServerDsc.strings.psd1
  • Class resources: source/en-US/{ResourceClassName}.strings.psd1

Key Naming Patterns

  • Format: Verb_FunctionName_Action (underscore separators), e.g. Get_SqlDscDatabase_ConnectingToDatabase

String Format

ConvertFrom-StringData @'
    KeyName = Message with {0} placeholder. (PREFIX0001)
'@

String IDs

  • Format: (PREFIX####)
  • PREFIX: First letter of each word in class or function name (SqlSetup → SS, Get-SqlDscDatabase → GSDD)
  • Number: Sequential from 0001

Usage

Write-Verbose -Message ($script:localizedData.KeyName -f $value1)

Files:

  • source/Classes/020.SqlAgentAlert.ps1
**

⚙️ CodeRabbit configuration file

**: # DSC Community Guidelines

Terminology

  • Command: Public command
  • Function: Private function
  • Resource: DSC class-based resource

Build & Test Workflow

  • Run project scripts in PowerShell from repository root
  • Build after source changes: .\build.ps1 -Tasks build
  • Test workflow: Build → Invoke-Pester -Path @('<test paths>') -Output Detailed
  • New session required after class changes

File Organization

  • Public commands: source/Public/{CommandName}.ps1
  • Private functions: source/Private/{FunctionName}.ps1
  • Unit tests: tests/Unit/{Classes|Public|Private}/{Name}.Tests.ps1
  • Integration tests: tests/Integration/Commands/{CommandName}.Integration.Tests.ps1

Requirements

  • Follow guidelines over existing code patterns
  • Always update CHANGELOG.md Unreleased section
  • Localize all strings using string keys; remove any orphaned string keys
  • Check DscResource.Common before creating private functions
  • Separate reusable logic into private functions
  • Add unit tests for all commands/functions/resources
  • Add integration tests for all public commands and resources

Files:

  • source/Classes/020.SqlAgentAlert.ps1
**/*.ps?(m|d)1

⚙️ CodeRabbit configuration file

**/*.ps?(m|d)1: # PowerShell Guidelines

Naming

  • Use descriptive names (3+ characters, no abbreviations)
  • Functions: PascalCase with Verb-Noun format using approved verbs
  • Parameters: PascalCase
  • Variables: camelCase
  • Keywords: lower-case
  • Classes: PascalCase
  • Include scope for script/global/environment variables: $script:, $global:, $env:

File naming

  • Class files: ###.ClassName.ps1 format (e.g. 001.SqlReason.ps1, 004.StartupParameters.ps1)

Formatting

Indentation & Spacing

  • Use 4 spaces (no tabs)
  • One space around operators: $a = 1 + 2
  • One space between type and variable: [String] $name
  • One space between keyword and parenthesis: if ($condition)
  • No spaces on empty lines
  • Try to limit lines to 120 characters

Braces

  • Newline before opening brace (except variable assignments)
  • One newline after opening brace
  • Two newlines after closing brace (one if followed by another brace or continuation)

Quotes

  • Use single quotes unless variable expansion is needed: 'text' vs "text $variable"

Arrays

  • Single line: @('one', 'two', 'three')
  • Multi-line: each element on separate line with proper indentation
  • Do not use the unary comma operator (,) in return statements to force
    an array

Hashtables

  • Empty: @{}
  • Multi-line: each property on separate line with proper indentation
  • Properties: Use PascalCase

Comments

  • Single line: # Comment (capitalized, on own line)
  • Multi-line: <# Comment #> format (opening and closing brackets on own line), and indent text
  • No commented-out code

Comment-based help

  • Always add comment-based help to all functions and scripts
  • Comment-based help: SYNOPSIS, DESCRIPTION (40+ chars), PARAMETER, EXAMPLE sections before function/class
  • Comment-based help indentation: keywords 4 spaces, text 8 spaces
  • Include examples for all parameter sets and combinations
  • INPUTS: List each pipeline‑accepted type (one per line) with a 1‑line description.
  • ...

Files:

  • source/Classes/020.SqlAgentAlert.ps1
🧠 Learnings (6)
📓 Common learnings
Learnt from: CR
PR: dsccommunity/SqlServerDsc#0
File: .github/instructions/SqlServerDsc-guidelines.instructions.md:0-0
Timestamp: 2025-08-25T10:04:53.158Z
Learning: Applies to **/DSCResources/**.{ps1,psm1} : Database Engine DSC resources must inherit the SqlResourceBase base class
📚 Learning: 2025-08-25T10:04:53.158Z
Learnt from: CR
PR: dsccommunity/SqlServerDsc#0
File: .github/instructions/SqlServerDsc-guidelines.instructions.md:0-0
Timestamp: 2025-08-25T10:04:53.158Z
Learning: Applies to **/DSCResources/**.{ps1,psm1} : Database Engine DSC resources must inherit the SqlResourceBase base class

Applied to files:

  • source/Classes/020.SqlAgentAlert.ps1
📚 Learning: 2025-08-25T10:05:30.603Z
Learnt from: CR
PR: dsccommunity/SqlServerDsc#0
File: .github/instructions/dsc-community-style-guidelines-class-resource.instructions.md:0-0
Timestamp: 2025-08-25T10:05:30.603Z
Learning: Applies to source/[cC]lasses/**/*.ps1 : Resource classes must inherit ResourceBase (from the DscResource.Base module)

Applied to files:

  • source/Classes/020.SqlAgentAlert.ps1
📚 Learning: 2025-08-25T10:04:53.158Z
Learnt from: CR
PR: dsccommunity/SqlServerDsc#0
File: .github/instructions/SqlServerDsc-guidelines.instructions.md:0-0
Timestamp: 2025-08-25T10:04:53.158Z
Learning: Applies to **/DSCResources/**.{ps1,psm1} : Resources inheriting SqlResourceBase should use its provided members: InstanceName, ServerName, Credential, Reasons, and GetServerObject()

Applied to files:

  • source/Classes/020.SqlAgentAlert.ps1
📚 Learning: 2025-08-25T10:05:30.603Z
Learnt from: CR
PR: dsccommunity/SqlServerDsc#0
File: .github/instructions/dsc-community-style-guidelines-class-resource.instructions.md:0-0
Timestamp: 2025-08-25T10:05:30.603Z
Learning: Applies to source/[cC]lasses/**/*.ps1 : Implement hidden [void] AssertProperties([System.Collections.Hashtable] $properties) to validate user-provided properties

Applied to files:

  • source/Classes/020.SqlAgentAlert.ps1
📚 Learning: 2025-08-26T12:02:40.945Z
Learnt from: johlju
PR: dsccommunity/SqlServerDsc#2150
File: source/Classes/020.SqlAgentAlert.ps1:169-173
Timestamp: 2025-08-26T12:02:40.945Z
Learning: Assert-BoundParameter with -MutuallyExclusiveList1 and -MutuallyExclusiveList2 parameters enforces that exactly one of the parameter groups must be present, not just mutual exclusivity. It handles both "not both" and "must have one" validation in DSC resources.

Applied to files:

  • source/Classes/020.SqlAgentAlert.ps1
🧬 Code graph analysis (1)
source/Classes/020.SqlAgentAlert.ps1 (1)
tests/Unit/Stubs/SMO.cs (2)
  • Alert (1604-1646)
  • Microsoft (1499-1649)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
  • GitHub Check: dsccommunity.SqlServerDsc (Build Package Module)
  • GitHub Check: PSScriptAnalyzer
  • GitHub Check: PSScriptAnalyzer
🔇 Additional comments (5)
source/Classes/020.SqlAgentAlert.ps1 (5)

115-117: DSC decoration and inheritance look correct.

Resource is properly decorated with [DscResource(RunAsCredential = 'Optional')] and inherits SqlResourceBase, which aligns with SqlServerDsc conventions for Database Engine resources.


185-221: GetCurrentState logic and localization are solid.

  • Uses GetServerObject() from the base.
  • Localized Write-Verbose messages.
  • Only returns Severity/MessageId when > 0, consistent if we disallow 0 via ValidateRange.

223-292: Set/Remove flows are clear and localized.

  • Create/Update/Remove paths use named parameters, localized verbose messages, and ErrorAction = 'Stop' for state changes.
  • Early exit when no changes are needed is good for idempotency.

137-145: Consistent base constructor usage confirmed

Verified that among the five DSC class resources inheriting SqlResourceBase, four—including SqlAgentAlert—use the pattern : base() and only SqlRSSetup explicitly passes $PSScriptRoot. Since the base class SqlResourceBase already invokes : base($PSScriptRoot), explicit arguments in child constructors are redundant. No change is required in SqlAgentAlert, as it already follows the prevailing : base() pattern.

• Outlier for future cleanup:
– File: source/Classes/020.SqlRSSetup.ps1
– Line: 219
– Current: SqlRSSetup () : base ($PSScriptRoot)
– Suggested: change to SqlRSSetup () : base () for consistency


139-145: No change required for ExcludeDscProperties

A review of all ExcludeDscProperties declarations in source/Classes shows that no resource explicitly excludes 'Ensure'. Each resource omits only the properties that cannot be enforced in its own context:

  • SqlRSSetup (020.SqlRSSetup.ps1:222–225) excludes Action, AcceptLicensingTerms, MediaPath
  • SqlAudit (020.SqlAudit.ps1:195–198) excludes ServerName, InstanceName, Name
  • SqlAgentAlert (020.SqlAgentAlert.ps1:140–143) excludes InstanceName, ServerName, Credential
  • SqlPermission, SqlDatabasePermission follow the same pattern

Because none of the peers exclude Ensure and the base class handles enforcement of the Ensure property, adding it here would be inconsistent and unnecessary.

…is set to 'Absent' and update tests accordingly
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

♻️ Duplicate comments (2)
source/Classes/020.SqlAgentAlert.ps1 (2)

269-289: When switching between Severity and MessageId, clear the other selector

If an existing alert was configured by Severity and the desired state uses MessageId (or vice versa), we should also clear the previously set selector to maintain invariants and avoid ambiguous state.

Apply:

-                $needsUpdate = $false
-
-                if ($properties.ContainsKey('Severity') -and $alertObject.Severity -ne $properties.Severity)
-                {
-                    $setAlertParameters.Severity = $properties.Severity
-                    $needsUpdate = $true
-                }
-
-                if ($properties.ContainsKey('MessageId') -and $alertObject.MessageId -ne $properties.MessageId)
-                {
-                    $setAlertParameters.MessageId = $properties.MessageId
-                    $needsUpdate = $true
-                }
+                $needsUpdate = $false
+
+                # If Severity is desired, set it and clear MessageId
+                if ($properties.ContainsKey('Severity'))
+                {
+                    if ($alertObject.Severity -ne $properties.Severity)
+                    {
+                        $setAlertParameters.Severity = $properties.Severity
+                        $needsUpdate = $true
+                    }
+
+                    if ($alertObject.MessageId -ne 0)
+                    {
+                        $setAlertParameters.MessageId = 0
+                        $needsUpdate = $true
+                    }
+                }
+
+                # If MessageId is desired, set it and clear Severity
+                if ($properties.ContainsKey('MessageId'))
+                {
+                    if ($alertObject.MessageId -ne $properties.MessageId)
+                    {
+                        $setAlertParameters.MessageId = $properties.MessageId
+                        $needsUpdate = $true
+                    }
+
+                    if ($alertObject.Severity -ne 0)
+                    {
+                        $setAlertParameters.Severity = 0
+                        $needsUpdate = $true
+                    }
+                }

Follow-up: I can add unit tests that cover Severity→MessageId and MessageId→Severity transitions.


127-135: Tighten ValidateRange to avoid idempotency gap with GetCurrentState(-gt 0)

Zero is allowed here but treated as “unset” in GetCurrentState (only values > 0 are surfaced). Desired values of 0 would never converge. Start both ranges at 1 (or, alternatively, change the -gt 0 checks to -ge 0 everywhere).

Apply:

     [DscProperty()]
-    [ValidateRange(0, 25)]
+    [ValidateRange(1, 25)]
     [Nullable[System.Int32]]
     $Severity

     [DscProperty()]
-    [ValidateRange(0, 2147483647)]
+    [ValidateRange(1, 2147483647)]
     [Nullable[System.Int32]]
     $MessageId
🧹 Nitpick comments (4)
source/Classes/020.SqlAgentAlert.ps1 (4)

55-62: Docs: Update stated valid ranges to match implementation/semantics

Comment-based help lists Severity range 0–25 and MessageId 0–2147483647. Given the current-state checks use -gt 0, zero can never materialize in Get() results, creating an idempotency gap. If you keep zero invalid (recommended), update the docs to start at 1.

Apply:

-    .PARAMETER Severity
-        The severity of the _SQL Server Agent_ alert. Valid range is 0 to 25.
+    .PARAMETER Severity
+        The severity of the _SQL Server Agent_ alert. Valid range is 1 to 25.
@@
-    .PARAMETER MessageId
-        The message id of the _SQL Server Agent_ alert. Valid range is 0 to 2147483647.
+    .PARAMETER MessageId
+        The message id of the _SQL Server Agent_ alert. Valid range is 1 to 2147483647.

215-224: Align “> 0” checks with parameter validation

These guards only surface values when greater than zero. This is fine if zero is disallowed at the parameter layer (recommended in a separate comment). If you decide zero must be valid, change -gt 0 to -ge 0 here and in any other comparisons.


10-14: Minor help text polish for clarity

Two small grammar/clarity improvements in the comment-based help.

Apply:

-        The built-in parameter **PSDscRunAsCredential** can be used to run the resource
-        as another user. The resource will then authenticate to the _SQL Server_
-        instance as that user. It also possible to instead use impersonation by the
-        parameter **Credential**.
+        The built-in parameter **PSDscRunAsCredential** can run the resource
+        as another user. The resource will then authenticate to the _SQL Server_
+        instance as that user. It is also possible to use impersonation via the
+        **Credential** parameter.
@@
-        together with class-based resources that using advanced type like the parameter
-        **Reasons** have.
+        together with class-based resources that use advanced types such as the
+        **Reasons** parameter.

Also applies to: 28-33


296-303: Optional: Avoid remove call when alert is already absent

Non-blocking. If Remove-SqlDscAgentAlert -Force is a no-op when the alert does not exist, this is fine. Otherwise, pre-check existence to skip unnecessary calls.

You can confirm behavior via unit tests or by checking the Remove-SqlDscAgentAlert implementation. If needed, I can draft a quick test to assert idempotent removal with -Force.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

💡 Knowledge Base configuration:

  • Jira integration is disabled
  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 9a5cba3 and 017f3a8.

📒 Files selected for processing (3)
  • source/Classes/020.SqlAgentAlert.ps1 (1 hunks)
  • source/en-US/SqlAgentAlert.strings.psd1 (1 hunks)
  • tests/Unit/Classes/SqlAgentAlert.Tests.ps1 (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
  • source/en-US/SqlAgentAlert.strings.psd1
  • tests/Unit/Classes/SqlAgentAlert.Tests.ps1
🧰 Additional context used
📓 Path-based instructions (7)
**/*.{ps1,psm1,psd1}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

Always follow PowerShell code style guidelines (./instructions/dsc-community-style-guidelines-powershell.instructions.md)

**/*.{ps1,psm1,psd1}: Use 4 spaces for indentation (no tabs)
One space around operators (e.g., $a = 1 + 2)
No spaces on empty lines
Try to limit lines to 120 characters
Use single quotes unless variable expansion is needed
Arrays single-line: @('one','two','three')
Arrays multi-line: each element on its own indented line
Hashtables empty literal uses @{}
Hashtables multi-line: each property on a separate indented line
Hashtable properties use PascalCase
Single-line comments use '# Comment' style: capitalized, on own line
Multi-line comments use <# #> with brackets on their own lines and indented text
End files with only one blank line
Use CR+LF line endings
Maximum of two consecutive newlines
Use UTF-8 encoding without BOM for all files

Files:

  • source/Classes/020.SqlAgentAlert.ps1
**/*.{ps1,psm1}

📄 CodeRabbit inference engine (.github/instructions/SqlServerDsc-guidelines.instructions.md)

**/*.{ps1,psm1}: Public PowerShell commands must follow the naming format: Verb-SqlDsc{Noun}
Prefer SMO over T-SQL for SQL Server interaction

**/*.{ps1,psm1}: Use descriptive names (3+ characters, no abbreviations)
Function names use PascalCase with Verb-Noun format using approved verbs
Parameter names use PascalCase
Variable names use camelCase
Keywords should be lower-case
Include scope qualifier for script/global/environment variables: $script:, $global:, $env:
One space between type and variable (e.g., [String] $name)
One space between keyword and parenthesis (e.g., if ($condition))
Newline before opening brace (except variable assignments)
One newline after opening brace
Two newlines after closing brace (one if followed by another brace or continuation)
Do not use the unary comma operator in return statements to force an array
Do not keep commented-out code
Always add comment-based help to all functions and scripts
Comment-based help must include SYNOPSIS, DESCRIPTION (40+ chars), PARAMETER, EXAMPLE sections before function/class
Comment-based help indentation: keywords at 4 spaces, text at 8 spaces
Include examples for all parameter sets and combinations in help
INPUTS: list each pipeline-accepted type (one per line) with a 1‑line description
OUTPUTS: list each return type (one per line) with a 1‑line description; must match [OutputType()] and actual returns
.NOTES only when critical (constraints, side effects, security, version compatibility, breaking behavior), ≤2 short sentences
Avoid aliases; use full command names
Avoid Write-Host; prefer Write-Verbose/Write-Information, etc.
Avoid Write-Output; use 'return' instead
Avoid ConvertTo-SecureString -AsPlainText in production code
Do not redefine reserved parameters (Verbose, Debug, etc.)
Include a Force parameter for functions that support ShouldContinue or use ShouldProcess
For state-changing functions, set SupportsShouldProcess
Use $PSCmdlet.ThrowTerminatingError() for terminating errors with relevant ...

Files:

  • source/Classes/020.SqlAgentAlert.ps1
source/[cC]lasses/*.ps1

📄 CodeRabbit inference engine (.github/instructions/dsc-community-style-guidelines-class-resource.instructions.md)

Place each DSC class-based resource in source/Classes/{ResourceName}.ps1

Files:

  • source/Classes/020.SqlAgentAlert.ps1
source/[cC]lasses/**/*.ps1

📄 CodeRabbit inference engine (.github/instructions/dsc-community-style-guidelines-class-resource.instructions.md)

source/[cC]lasses/**/*.ps1: Decorate the resource class with [DscResource(RunAsCredential = 'Optional')] (use 'Mandatory' if required)
Only classes with a [DscResource(...)] decoration are considered DSC resources to which these rules apply
Resource classes must inherit ResourceBase (from the DscResource.Base module)
Use $this.localizedData provided by ResourceBase (auto-populated from the localization file); do not manually populate it
Implement Get() that delegates to ([ResourceBase] $this).Get(), optionally post-processes, and returns the current state object
Implement Test() that delegates to ([ResourceBase] $this).Test(), optionally post-processes, and returns a [System.Boolean]
Implement Set() that delegates to ([ResourceBase] $this).Set(), with optional additional changes not handled by Modify()
Implement hidden [System.Collections.Hashtable] GetCurrentState([System.Collections.Hashtable] $properties) to return current state
Implement hidden [void] Modify([System.Collections.Hashtable] $properties) to set desired state only for non-compliant properties
Implement hidden [void] AssertProperties([System.Collections.Hashtable] $properties) to validate user-provided properties
Implement hidden [void] NormalizeProperties([System.Collections.Hashtable] $properties) to normalize user-provided properties

Files:

  • source/Classes/020.SqlAgentAlert.ps1

⚙️ CodeRabbit configuration file

source/[cC]lasses/**/*.ps1: # DSC Class-Based Resource Guidelines

Applies to: Classes with [DscResource(...)] decoration only.

Requirements

  • File: source/Classes/020.{ResourceName}.ps1
  • Decoration: [DscResource(RunAsCredential = 'Optional')] (replace with 'Mandatory' if required)
  • Inheritance: Must inherit ResourceBase (part of module DscResource.Base)
  • $this.localizedData hashtable auto-populated by ResourceBase from localization file

Required constructor

MyResourceName () : base ($PSScriptRoot)
{
    # Property names where state cannot be enforced, e.g Ensure
    $this.ExcludeDscProperties = @()
}

Required Method Pattern

[MyResourceName] Get()
{
    # Call base implementation to get current state
    $currentState = ([ResourceBase] $this).Get()

    # If needed, post-processing on current state that can not be handled by GetCurrentState()

    return $currentState
}

[System.Boolean] Test()
{
    # Call base implementation to test current state
    $inDesiredState = ([ResourceBase] $this).Test()

    # If needed, post-processing on test result that can not be handled by base Test()

    return $inDesiredState
}

[void] Set()
{
    # Call base implementation to set desired state
    ([ResourceBase] $this).Set()

    # If needed, additional state changes that can not be handled by Modify()
}

hidden [System.Collections.Hashtable] GetCurrentState([System.Collections.Hashtable] $properties)
{
    # Always return current state as hashtable, $properties contains key properties
}

hidden [void] Modify([System.Collections.Hashtable] $properties)
{
    # Always set desired state, $properties contain those that must change state
}

Optional Method Pattern

hidden [void] AssertProperties([System.Collections.Hashtable] $properties)
{
    # Validate user-provided properties, $properties contains user assigned values
}

hidden [void] NormalizeProperties([System.Collections.Hashtable] $pr...

Files:

  • source/Classes/020.SqlAgentAlert.ps1
source/**/*.ps1

📄 CodeRabbit inference engine (.github/instructions/dsc-community-style-guidelines-localization.instructions.md)

source/**/*.ps1: Localize all Write-Debug, Write-Verbose, Write-Error, Write-Warning, and $PSCmdlet.ThrowTerminatingError() messages
Do not hardcode user-facing strings; use localized string keys instead
Access localized strings via $script:localizedData, formatting with -f when needed

Localize all strings in source code using string keys

Files:

  • source/Classes/020.SqlAgentAlert.ps1

⚙️ CodeRabbit configuration file

source/**/*.ps1: # Localization Guidelines

Requirements

  • Localize all Write-Debug, Write-Verbose, Write-Error, Write-Warning and $PSCmdlet.ThrowTerminatingError() messages
  • Use localized string keys, not hardcoded strings
  • Assume $script:localizedData is available

String Files

  • Commands/functions: source/en-US/SqlServerDsc.strings.psd1
  • Class resources: source/en-US/{ResourceClassName}.strings.psd1

Key Naming Patterns

  • Format: Verb_FunctionName_Action (underscore separators), e.g. Get_SqlDscDatabase_ConnectingToDatabase

String Format

ConvertFrom-StringData @'
    KeyName = Message with {0} placeholder. (PREFIX0001)
'@

String IDs

  • Format: (PREFIX####)
  • PREFIX: First letter of each word in class or function name (SqlSetup → SS, Get-SqlDscDatabase → GSDD)
  • Number: Sequential from 0001

Usage

Write-Verbose -Message ($script:localizedData.KeyName -f $value1)

Files:

  • source/Classes/020.SqlAgentAlert.ps1
**

⚙️ CodeRabbit configuration file

**: # DSC Community Guidelines

Terminology

  • Command: Public command
  • Function: Private function
  • Resource: DSC class-based resource

Build & Test Workflow

  • Run project scripts in PowerShell from repository root
  • Build after source changes: .\build.ps1 -Tasks build
  • Test workflow: Build → Invoke-Pester -Path @('<test paths>') -Output Detailed
  • New session required after class changes

File Organization

  • Public commands: source/Public/{CommandName}.ps1
  • Private functions: source/Private/{FunctionName}.ps1
  • Unit tests: tests/Unit/{Classes|Public|Private}/{Name}.Tests.ps1
  • Integration tests: tests/Integration/Commands/{CommandName}.Integration.Tests.ps1

Requirements

  • Follow guidelines over existing code patterns
  • Always update CHANGELOG.md Unreleased section
  • Localize all strings using string keys; remove any orphaned string keys
  • Check DscResource.Common before creating private functions
  • Separate reusable logic into private functions
  • Add unit tests for all commands/functions/resources
  • Add integration tests for all public commands and resources

Files:

  • source/Classes/020.SqlAgentAlert.ps1
**/*.ps?(m|d)1

⚙️ CodeRabbit configuration file

**/*.ps?(m|d)1: # PowerShell Guidelines

Naming

  • Use descriptive names (3+ characters, no abbreviations)
  • Functions: PascalCase with Verb-Noun format using approved verbs
  • Parameters: PascalCase
  • Variables: camelCase
  • Keywords: lower-case
  • Classes: PascalCase
  • Include scope for script/global/environment variables: $script:, $global:, $env:

File naming

  • Class files: ###.ClassName.ps1 format (e.g. 001.SqlReason.ps1, 004.StartupParameters.ps1)

Formatting

Indentation & Spacing

  • Use 4 spaces (no tabs)
  • One space around operators: $a = 1 + 2
  • One space between type and variable: [String] $name
  • One space between keyword and parenthesis: if ($condition)
  • No spaces on empty lines
  • Try to limit lines to 120 characters

Braces

  • Newline before opening brace (except variable assignments)
  • One newline after opening brace
  • Two newlines after closing brace (one if followed by another brace or continuation)

Quotes

  • Use single quotes unless variable expansion is needed: 'text' vs "text $variable"

Arrays

  • Single line: @('one', 'two', 'three')
  • Multi-line: each element on separate line with proper indentation
  • Do not use the unary comma operator (,) in return statements to force
    an array

Hashtables

  • Empty: @{}
  • Multi-line: each property on separate line with proper indentation
  • Properties: Use PascalCase

Comments

  • Single line: # Comment (capitalized, on own line)
  • Multi-line: <# Comment #> format (opening and closing brackets on own line), and indent text
  • No commented-out code

Comment-based help

  • Always add comment-based help to all functions and scripts
  • Comment-based help: SYNOPSIS, DESCRIPTION (40+ chars), PARAMETER, EXAMPLE sections before function/class
  • Comment-based help indentation: keywords 4 spaces, text 8 spaces
  • Include examples for all parameter sets and combinations
  • INPUTS: List each pipeline‑accepted type (one per line) with a 1‑line description.
  • ...

Files:

  • source/Classes/020.SqlAgentAlert.ps1
🧠 Learnings (5)
📓 Common learnings
Learnt from: CR
PR: dsccommunity/SqlServerDsc#0
File: .github/instructions/SqlServerDsc-guidelines.instructions.md:0-0
Timestamp: 2025-08-25T10:04:53.158Z
Learning: Applies to **/DSCResources/**.{ps1,psm1} : Database Engine DSC resources must inherit the SqlResourceBase base class
📚 Learning: 2025-08-25T10:04:53.158Z
Learnt from: CR
PR: dsccommunity/SqlServerDsc#0
File: .github/instructions/SqlServerDsc-guidelines.instructions.md:0-0
Timestamp: 2025-08-25T10:04:53.158Z
Learning: Applies to **/DSCResources/**.{ps1,psm1} : Database Engine DSC resources must inherit the SqlResourceBase base class

Applied to files:

  • source/Classes/020.SqlAgentAlert.ps1
📚 Learning: 2025-08-25T10:05:30.603Z
Learnt from: CR
PR: dsccommunity/SqlServerDsc#0
File: .github/instructions/dsc-community-style-guidelines-class-resource.instructions.md:0-0
Timestamp: 2025-08-25T10:05:30.603Z
Learning: Applies to source/[cC]lasses/**/*.ps1 : Implement hidden [void] AssertProperties([System.Collections.Hashtable] $properties) to validate user-provided properties

Applied to files:

  • source/Classes/020.SqlAgentAlert.ps1
📚 Learning: 2025-08-26T12:02:40.945Z
Learnt from: johlju
PR: dsccommunity/SqlServerDsc#2150
File: source/Classes/020.SqlAgentAlert.ps1:169-173
Timestamp: 2025-08-26T12:02:40.945Z
Learning: Assert-BoundParameter with -MutuallyExclusiveList1 and -MutuallyExclusiveList2 parameters enforces that exactly one of the parameter groups must be present, not just mutual exclusivity. It handles both "not both" and "must have one" validation in DSC resources.

Applied to files:

  • source/Classes/020.SqlAgentAlert.ps1
📚 Learning: 2025-08-25T10:04:53.158Z
Learnt from: CR
PR: dsccommunity/SqlServerDsc#0
File: .github/instructions/SqlServerDsc-guidelines.instructions.md:0-0
Timestamp: 2025-08-25T10:04:53.158Z
Learning: Applies to **/DSCResources/**.{ps1,psm1} : Resources inheriting SqlResourceBase should use its provided members: InstanceName, ServerName, Credential, Reasons, and GetServerObject()

Applied to files:

  • source/Classes/020.SqlAgentAlert.ps1
🧬 Code graph analysis (1)
source/Classes/020.SqlAgentAlert.ps1 (1)
tests/Unit/Stubs/SMO.cs (2)
  • Alert (1604-1646)
  • Microsoft (1499-1649)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
  • GitHub Check: dsccommunity.SqlServerDsc (Build Package Module)
  • GitHub Check: PSScriptAnalyzer
  • GitHub Check: PSScriptAnalyzer
🔇 Additional comments (2)
source/Classes/020.SqlAgentAlert.ps1 (2)

115-126: Good: Correct DSC decoration and default Ensure

The resource is properly decorated with [DscResource(RunAsCredential = 'Optional')] and exposes Ensure with a sane default. This aligns with the class-based resource guidance.


137-146: No action needed: Child constructors correctly delegate to SqlResourceBase

The SqlResourceBase class (source/Classes/011.SqlResourceBase.ps1) defines only a parameterless constructor that itself calls ResourceBase($PSScriptRoot). By invoking : base() in each derived class (including SqlAgentAlert), you correctly delegate into that parameterless ctor, which wires up the module root for you. There is no overload on SqlResourceBase accepting a $PSScriptRoot argument, so changing to : base($PSScriptRoot) would break compilation.

• Confirmed in SqlResourceBase:

# Passing the module's base directory to the base constructor.
SqlResourceBase () : base ($PSScriptRoot) { … }

• All other class-based resources likewise use : base() to invoke that parameterless constructor.

You can safely keep the constructor as-is.

Likely an incorrect or invalid review comment.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
tests/Integration/Resources/DSC_SqlAgentAlert.config.ps1 (1)

21-22: Standardize property casing: replace $Node.Username with $Node.UserName

The search revealed numerous leftover references to $Node.Username across the integration test resources. Please update all of them to $Node.UserName for consistency:

• tests/Integration/Resources/DSC_SqlDatabase.config.ps1
• tests/Integration/Resources/DSC_SqlProtocol.config.ps1
• tests/Integration/Resources/DSC_SqlDatabaseObjectPermission.config.ps1
• tests/Integration/Resources/DSC_SqlAgentAlert.config.ps1
• tests/Integration/Resources/DSC_SqlTraceFlag.config.ps1
• tests/Integration/Resources/DSC_SqlRSSetup.config.ps1
• tests/Integration/Resources/DSC_SqlProtocolTcpIp.config.ps1
• tests/Integration/Resources/DSC_SqlDatabaseDefaultLocation.config.ps1
• tests/Integration/Resources/DSC_SqlAlwaysOnService.config.ps1
• tests/Integration/Resources/DSC_SqlAgentFailsafe.config.ps1
• tests/Integration/Resources/DSC_SqlReplication.config.ps1
• tests/Integration/Resources/DSC_SqlDatabaseMail.config.ps1
• tests/Integration/Resources/DSC_SqlAgentOperator.config.ps1
• tests/Integration/Resources/DSC_SqlAudit.config.ps1
• tests/Integration/Resources/DSC_SqlRole.config.ps1

Example diff:

-    -ArgumentList @($Node.Username, (ConvertTo-SecureString -String $Node.Password -AsPlainText -Force))
+    -ArgumentList @($Node.UserName, (ConvertTo-SecureString -String $Node.Password -AsPlainText -Force))
♻️ Duplicate comments (2)
.github/instructions/dsc-community-style-guidelines-class-resource.instructions.md (2)

13-15: Default base class should be SqlResourceBase for Database Engine; relax nullable-type rule

Align the guidance with module conventions and retrieved learnings: DB Engine resources should default to SqlResourceBase (exposes InstanceName, ServerName, Credential, Reasons, GetServerObject()), while other resources use ResourceBase. Also soften the blanket nullable-types mandate to “where appropriate.” This prevents misleading authors of Sql* resources and avoids forcing nullable types on required properties.

I used the retrieved learnings to justify this change (see: “Database Engine DSC resources must inherit the SqlResourceBase base class” and “Resources inheriting SqlResourceBase should use its provided members”).

- - Inheritance: Must inherit `ResourceBase` (part of module DscResource.Base)
- - `$this.localizedData` hashtable auto-populated by `ResourceBase` from localization file
- - value-type properties: Use `[Nullable[{FullTypeName}]]` (e.g., `[Nullable[System.Int32]]`)
+ - Inheritance:
+   - Database Engine–related resources: inherit `SqlResourceBase` (from module
+     `DscResource.Sql`). Use its common members: `InstanceName`, `ServerName`,
+     `Credential`, `Reasons`, and `GetServerObject()`.
+   - Other resources: inherit `ResourceBase` (from `DscResource.Base`).
+ - `$this.localizedData` is auto-populated by the chosen base class from the
+   localization file.
+ - Use nullable types where appropriate (e.g., `[Nullable[System.Int32]]` or
+   `[int?]` for optional value types). Do not force nullable for required props.

89-97: *Error handling: for class-based resources, throw the localized New-Exception

“Do not use throw” contradicts class-based guidance. For class-based resources, create a localized exception via DscResource.Common New-*Exception and throw it. Include a minimal example.

-## Error Handling
-- Use `try/catch` blocks to handle exceptions
-- Do not use `throw` for terminating errors, use `New-*Exception` commands:
+## Error handling
+- Use `try/catch` blocks to handle exceptions.
+- For terminating errors in class-based resources, create a localized exception
+  using the appropriate `New-*Exception` helper (DscResource.Common) and `throw`
+  that exception to terminate:
   - [`New‑InvalidDataException`](https://github.com/dsccommunity/DscResource.Common/wiki/New%E2%80%91InvalidDataException)
   - [`New-ArgumentException`](https://github.com/dsccommunity/DscResource.Common/wiki/New%E2%80%91ArgumentException)
   - [`New-InvalidOperationException`](https://github.com/dsccommunity/DscResource.Common/wiki/New%E2%80%91InvalidOperationException)
   - [`New-ObjectNotFoundException`](https://github.com/dsccommunity/DscResource.Common/wiki/New%E2%80%91ObjectNotFoundException)
   - [`New-InvalidResultException`](https://github.com/dsccommunity/DscResource.Common/wiki/New%E2%80%91InvalidResultException)
   - [`New-NotImplementedException`](https://github.com/dsccommunity/DscResource.Common/wiki/New%E2%80%91NotImplementedException)
+
+Example:
+
+```powershell
+catch
+{
+    $msg = $this.localizedData.Resource_Action_Failed -f $this.Name, $_.Exception.Message
+    throw (New-InvalidOperationException -Message $msg -ErrorRecord $_)
+}
+```
🧹 Nitpick comments (9)
.github/instructions/dsc-community-style-guidelines-class-resource.instructions.md (2)

20-24: Constructor sample: use a consistent placeholder name and tighten the comment

Small polish for consistency with the rest of the doc and to avoid implying specific properties.

-MyResourceName () : base ()
+{ResourceName} () : base ()
 {
-    # Property names where state cannot be enforced, e.g. IsSingleInstance, Force
+    # Property names where state cannot be enforced (example: 'IsSingleInstance')
     $this.ExcludeDscProperties = @()
 }

83-88: Fix markdown formatting and grammar in “Required comment-based help”

Add the missing blank lines around the list and wrap lines to satisfy markdownlint (MD022/MD032/MD013) and improve readability.

-## Required comment-based help
-
-Add to .DESCRIPTION section:
-- `## Requirements`: List minimum requirements
-- `## Known issues`: Critical issues + pattern: `All issues are not listed here, see [all open issues](https://github.com/{owner}/{repo}/issues?q=is%3Aissue+is%3Aopen+in%3Atitle+{ResourceName}).`
+## Required comment-based help
+
+Add the following to the `.DESCRIPTION` section:
+
+- `## Requirements`: List minimum requirements.
+- `## Known issues`: Keep this brief and add the pattern:
+  `All issues are not listed here. See
+  [all open issues](https://github.com/{owner}/{repo}/issues?q=is%3Aissue+is%3Aopen+in%3Atitle+{ResourceName}).`
tests/Integration/Resources/DSC_SqlAgentAlert.config.ps1 (7)

27-30: Use numeric types for Severity and MessageId in node data

These are integers in the resource surface; avoid quoting them as strings to reduce implicit conversions during MOF compilation and improve readability.

-                Name            = 'MockAlert'
-                Severity        = '17'
-                MessageId       = '50001'
+                Name            = 'MockAlert'
+                Severity        = 17
+                MessageId       = 50001

55-57: Remove backticks and fix casing: use multiline array for ArgumentList

Avoid the backtick for line continuation and keep property casing consistent with the node data (UserName). This also conforms to the style guideline on avoiding backticks.

-            PsDscRunAsCredential = New-Object `
-                -TypeName System.Management.Automation.PSCredential `
-                -ArgumentList @($Node.Username, (ConvertTo-SecureString -String $Node.Password -AsPlainText -Force))
+            PsDscRunAsCredential = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList @(
+                $Node.UserName,
+                (ConvertTo-SecureString -String $Node.Password -AsPlainText -Force)
+            )

78-90: Prefer expandable here-strings for multi-line T-SQL

Here-strings improve readability and avoid quoting pitfalls while still allowing variable expansion.

-            SetQuery             = "
-                IF NOT EXISTS (SELECT 1 FROM sys.messages WHERE message_id = $($Node.MessageId) AND language_id = 1033)
-                BEGIN
-                    EXEC sp_addmessage
-                        @msgnum = $($Node.MessageId),
-                        @severity = 16,
-                        @msgtext = N'Custom test message for SqlAgentAlert integration test',
-                        @lang = 'us_english'
-                END
-            "
-            TestQuery            = "SELECT 1 FROM sys.messages WHERE message_id = $($Node.MessageId) AND language_id = 1033"
-            GetQuery             = "SELECT message_id, text FROM sys.messages WHERE message_id = $($Node.MessageId) AND language_id = 1033"
+            SetQuery             = @"
+IF NOT EXISTS (SELECT 1 FROM sys.messages WHERE message_id = $($Node.MessageId) AND language_id = 1033)
+BEGIN
+    EXEC sp_addmessage
+        @msgnum   = $($Node.MessageId),
+        @severity = 16,
+        @msgtext  = N'Custom test message for SqlAgentAlert integration test',
+        @lang     = 'us_english'
+END
+"@
+
+            TestQuery            = @"
+SELECT 1 FROM sys.messages WHERE message_id = $($Node.MessageId) AND language_id = 1033
+"@
+
+            GetQuery             = @"
+SELECT message_id, text
+FROM sys.messages
+WHERE message_id = $($Node.MessageId) AND language_id = 1033
+"@

91-94: Remove backticks and fix casing for credential creation (CreateCustomMessage)

Same rationale as above.

-            PsDscRunAsCredential = New-Object `
-                -TypeName System.Management.Automation.PSCredential `
-                -ArgumentList @($Node.Username, (ConvertTo-SecureString -String $Node.Password -AsPlainText -Force))
+            PsDscRunAsCredential = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList @(
+                $Node.UserName,
+                (ConvertTo-SecureString -String $Node.Password -AsPlainText -Force)
+            )

104-107: Remove backticks and fix casing for credential creation (SqlAgentAlert switch)

Mirror the credential style consistently.

-            PsDscRunAsCredential = New-Object `
-                -TypeName System.Management.Automation.PSCredential `
-                -ArgumentList @($Node.Username, (ConvertTo-SecureString -String $Node.Password -AsPlainText -Force))
+            PsDscRunAsCredential = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList @(
+                $Node.UserName,
+                (ConvertTo-SecureString -String $Node.Password -AsPlainText -Force)
+            )

141-151: Use here-strings for cleanup queries too

Keep the SQL formatting consistent and readable in the removal block.

-            SetQuery             = "
-                IF EXISTS (SELECT 1 FROM sys.messages WHERE message_id = $($Node.MessageId) AND language_id = 1033)
-                BEGIN
-                    EXEC sp_dropmessage
-                        @msgnum = $($Node.MessageId),
-                        @lang = 'us_english'
-                END
-            "
-            TestQuery            = "SELECT CASE WHEN NOT EXISTS (SELECT 1 FROM sys.messages WHERE message_id = $($Node.MessageId) AND language_id = 1033) THEN 1 ELSE 0 END AS MessageRemoved"
-            GetQuery             = "SELECT COUNT(*) as MessageCount FROM sys.messages WHERE message_id = $($Node.MessageId) AND language_id = 1033"
+            SetQuery             = @"
+IF EXISTS (SELECT 1 FROM sys.messages WHERE message_id = $($Node.MessageId) AND language_id = 1033)
+BEGIN
+    EXEC sp_dropmessage
+        @msgnum = $($Node.MessageId),
+        @lang   = 'us_english'
+END
+"@
+
+            TestQuery            = @"
+SELECT CASE
+         WHEN NOT EXISTS (SELECT 1 FROM sys.messages WHERE message_id = $($Node.MessageId) AND language_id = 1033)
+         THEN 1 ELSE 0
+       END AS MessageRemoved
+"@
+
+            GetQuery             = @"
+SELECT COUNT(*) AS MessageCount
+FROM sys.messages
+WHERE message_id = $($Node.MessageId) AND language_id = 1033
+"@

152-155: Remove backticks and fix casing for credential creation (cleanup)

Consistent style and casing across all blocks.

-            PsDscRunAsCredential = New-Object `
-                -TypeName System.Management.Automation.PSCredential `
-                -ArgumentList @($Node.Username, (ConvertTo-SecureString -String $Node.Password -AsPlainText -Force))
+            PsDscRunAsCredential = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList @(
+                $Node.UserName,
+                (ConvertTo-SecureString -String $Node.Password -AsPlainText -Force)
+            )
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

💡 Knowledge Base configuration:

  • Jira integration is disabled
  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 017f3a8 and 207ce9c.

📒 Files selected for processing (3)
  • .github/instructions/dsc-community-style-guidelines-class-resource.instructions.md (2 hunks)
  • tests/Integration/Resources/DSC_SqlAgentAlert.Integration.Tests.ps1 (3 hunks)
  • tests/Integration/Resources/DSC_SqlAgentAlert.config.ps1 (3 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • tests/Integration/Resources/DSC_SqlAgentAlert.Integration.Tests.ps1
🧰 Additional context used
📓 Path-based instructions (4)
**/*.{ps1,psm1,psd1}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

Always follow PowerShell code style guidelines (./instructions/dsc-community-style-guidelines-powershell.instructions.md)

**/*.{ps1,psm1,psd1}: Use 4 spaces for indentation (no tabs)
One space around operators (e.g., $a = 1 + 2)
No spaces on empty lines
Try to limit lines to 120 characters
Use single quotes unless variable expansion is needed
Arrays single-line: @('one','two','three')
Arrays multi-line: each element on its own indented line
Hashtables empty literal uses @{}
Hashtables multi-line: each property on a separate indented line
Hashtable properties use PascalCase
Single-line comments use '# Comment' style: capitalized, on own line
Multi-line comments use <# #> with brackets on their own lines and indented text
End files with only one blank line
Use CR+LF line endings
Maximum of two consecutive newlines
Use UTF-8 encoding without BOM for all files

Files:

  • tests/Integration/Resources/DSC_SqlAgentAlert.config.ps1
**/*.{ps1,psm1}

📄 CodeRabbit inference engine (.github/instructions/SqlServerDsc-guidelines.instructions.md)

**/*.{ps1,psm1}: Public PowerShell commands must follow the naming format: Verb-SqlDsc{Noun}
Prefer SMO over T-SQL for SQL Server interaction

**/*.{ps1,psm1}: Use descriptive names (3+ characters, no abbreviations)
Function names use PascalCase with Verb-Noun format using approved verbs
Parameter names use PascalCase
Variable names use camelCase
Keywords should be lower-case
Include scope qualifier for script/global/environment variables: $script:, $global:, $env:
One space between type and variable (e.g., [String] $name)
One space between keyword and parenthesis (e.g., if ($condition))
Newline before opening brace (except variable assignments)
One newline after opening brace
Two newlines after closing brace (one if followed by another brace or continuation)
Do not use the unary comma operator in return statements to force an array
Do not keep commented-out code
Always add comment-based help to all functions and scripts
Comment-based help must include SYNOPSIS, DESCRIPTION (40+ chars), PARAMETER, EXAMPLE sections before function/class
Comment-based help indentation: keywords at 4 spaces, text at 8 spaces
Include examples for all parameter sets and combinations in help
INPUTS: list each pipeline-accepted type (one per line) with a 1‑line description
OUTPUTS: list each return type (one per line) with a 1‑line description; must match [OutputType()] and actual returns
.NOTES only when critical (constraints, side effects, security, version compatibility, breaking behavior), ≤2 short sentences
Avoid aliases; use full command names
Avoid Write-Host; prefer Write-Verbose/Write-Information, etc.
Avoid Write-Output; use 'return' instead
Avoid ConvertTo-SecureString -AsPlainText in production code
Do not redefine reserved parameters (Verbose, Debug, etc.)
Include a Force parameter for functions that support ShouldContinue or use ShouldProcess
For state-changing functions, set SupportsShouldProcess
Use $PSCmdlet.ThrowTerminatingError() for terminating errors with relevant ...

Files:

  • tests/Integration/Resources/DSC_SqlAgentAlert.config.ps1
**

⚙️ CodeRabbit configuration file

**: # DSC Community Guidelines

Terminology

  • Command: Public command
  • Function: Private function
  • Resource: DSC class-based resource

Build & Test Workflow

  • Run project scripts in PowerShell from repository root
  • Build after source changes: .\build.ps1 -Tasks build
  • Test workflow: Build → Invoke-Pester -Path @('<test paths>') -Output Detailed
  • New session required after class changes

File Organization

  • Public commands: source/Public/{CommandName}.ps1
  • Private functions: source/Private/{FunctionName}.ps1
  • Unit tests: tests/Unit/{Classes|Public|Private}/{Name}.Tests.ps1
  • Integration tests: tests/Integration/Commands/{CommandName}.Integration.Tests.ps1

Requirements

  • Follow guidelines over existing code patterns
  • Always update CHANGELOG.md Unreleased section
  • Localize all strings using string keys; remove any orphaned string keys
  • Check DscResource.Common before creating private functions
  • Separate reusable logic into private functions
  • Add unit tests for all commands/functions/resources
  • Add integration tests for all public commands and resources

Files:

  • tests/Integration/Resources/DSC_SqlAgentAlert.config.ps1
**/*.ps?(m|d)1

⚙️ CodeRabbit configuration file

**/*.ps?(m|d)1: # PowerShell Guidelines

Naming

  • Use descriptive names (3+ characters, no abbreviations)
  • Functions: PascalCase with Verb-Noun format using approved verbs
  • Parameters: PascalCase
  • Variables: camelCase
  • Keywords: lower-case
  • Classes: PascalCase
  • Include scope for script/global/environment variables: $script:, $global:, $env:

File naming

  • Class files: ###.ClassName.ps1 format (e.g. 001.SqlReason.ps1, 004.StartupParameters.ps1)

Formatting

Indentation & Spacing

  • Use 4 spaces (no tabs)
  • One space around operators: $a = 1 + 2
  • One space between type and variable: [String] $name
  • One space between keyword and parenthesis: if ($condition)
  • No spaces on empty lines
  • Try to limit lines to 120 characters

Braces

  • Newline before opening brace (except variable assignments)
  • One newline after opening brace
  • Two newlines after closing brace (one if followed by another brace or continuation)

Quotes

  • Use single quotes unless variable expansion is needed: 'text' vs "text $variable"

Arrays

  • Single line: @('one', 'two', 'three')
  • Multi-line: each element on separate line with proper indentation
  • Do not use the unary comma operator (,) in return statements to force
    an array

Hashtables

  • Empty: @{}
  • Multi-line: each property on separate line with proper indentation
  • Properties: Use PascalCase

Comments

  • Single line: # Comment (capitalized, on own line)
  • Multi-line: <# Comment #> format (opening and closing brackets on own line), and indent text
  • No commented-out code

Comment-based help

  • Always add comment-based help to all functions and scripts
  • Comment-based help: SYNOPSIS, DESCRIPTION (40+ chars), PARAMETER, EXAMPLE sections before function/class
  • Comment-based help indentation: keywords 4 spaces, text 8 spaces
  • Include examples for all parameter sets and combinations
  • INPUTS: List each pipeline‑accepted type (one per line) with a 1‑line description.
  • ...

Files:

  • tests/Integration/Resources/DSC_SqlAgentAlert.config.ps1
🧠 Learnings (14)
📚 Learning: 2025-08-25T10:04:22.244Z
Learnt from: CR
PR: dsccommunity/SqlServerDsc#0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-08-25T10:04:22.244Z
Learning: Follow class-based resources guidelines (./instructions/dsc-community-style-guidelines-class-resource.instructions.md)

Applied to files:

  • .github/instructions/dsc-community-style-guidelines-class-resource.instructions.md
📚 Learning: 2025-08-25T10:05:30.603Z
Learnt from: CR
PR: dsccommunity/SqlServerDsc#0
File: .github/instructions/dsc-community-style-guidelines-class-resource.instructions.md:0-0
Timestamp: 2025-08-25T10:05:30.603Z
Learning: Applies to source/[cC]lasses/**/*.ps1 : Resource classes must inherit ResourceBase (from the DscResource.Base module)

Applied to files:

  • .github/instructions/dsc-community-style-guidelines-class-resource.instructions.md
📚 Learning: 2025-08-25T10:09:05.899Z
Learnt from: CR
PR: dsccommunity/SqlServerDsc#0
File: .github/instructions/dsc-community-style-guidelines-powershell.instructions.md:0-0
Timestamp: 2025-08-25T10:09:05.899Z
Learning: Applies to **/*.{ps1,psm1} : .NOTES only when critical (constraints, side effects, security, version compatibility, breaking behavior), ≤2 short sentences

Applied to files:

  • .github/instructions/dsc-community-style-guidelines-class-resource.instructions.md
📚 Learning: 2025-08-25T10:04:53.158Z
Learnt from: CR
PR: dsccommunity/SqlServerDsc#0
File: .github/instructions/SqlServerDsc-guidelines.instructions.md:0-0
Timestamp: 2025-08-25T10:04:53.158Z
Learning: Applies to **/DSCResources/**.{ps1,psm1} : Database Engine DSC resources must inherit the SqlResourceBase base class

Applied to files:

  • .github/instructions/dsc-community-style-guidelines-class-resource.instructions.md
📚 Learning: 2025-08-25T10:04:53.158Z
Learnt from: CR
PR: dsccommunity/SqlServerDsc#0
File: .github/instructions/SqlServerDsc-guidelines.instructions.md:0-0
Timestamp: 2025-08-25T10:04:53.158Z
Learning: Applies to **/DSCResources/**.{ps1,psm1} : Resources inheriting SqlResourceBase should use its provided members: InstanceName, ServerName, Credential, Reasons, and GetServerObject()

Applied to files:

  • .github/instructions/dsc-community-style-guidelines-class-resource.instructions.md
📚 Learning: 2025-08-25T10:07:22.349Z
Learnt from: CR
PR: dsccommunity/SqlServerDsc#0
File: .github/instructions/dsc-community-style-guidelines-mof-resources.instructions.md:0-0
Timestamp: 2025-08-25T10:07:22.349Z
Learning: Applies to source/DSCResources/**/*.psm1 : When raising terminating errors, throw localized exceptions created via the appropriate DscResource.Common New-*Exception cmdlets (e.g., New-InvalidDataException, New-ArgumentException, New-InvalidOperationException, New-ObjectNotFoundException, New-InvalidResultException, New-NotImplementedException)

Applied to files:

  • .github/instructions/dsc-community-style-guidelines-class-resource.instructions.md
📚 Learning: 2025-08-25T10:07:22.349Z
Learnt from: CR
PR: dsccommunity/SqlServerDsc#0
File: .github/instructions/dsc-community-style-guidelines-mof-resources.instructions.md:0-0
Timestamp: 2025-08-25T10:07:22.349Z
Learning: Applies to source/DSCResources/**/*.psm1 : Do not use throw for terminating errors; handle errors via try/catch

Applied to files:

  • .github/instructions/dsc-community-style-guidelines-class-resource.instructions.md
📚 Learning: 2025-08-17T10:48:15.384Z
Learnt from: johlju
PR: dsccommunity/SqlServerDsc#2136
File: source/suffix.ps1:24-24
Timestamp: 2025-08-17T10:48:15.384Z
Learning: In source/suffix.ps1, the Write-Verbose message in the catch block for Import-SqlDscPreferredModule does not need localization because the exception message from Import-SqlDscPreferredModule is already localized by that command, making it an edge case exception to the localization guidelines.

Applied to files:

  • .github/instructions/dsc-community-style-guidelines-class-resource.instructions.md
📚 Learning: 2025-08-25T10:05:30.603Z
Learnt from: CR
PR: dsccommunity/SqlServerDsc#0
File: .github/instructions/dsc-community-style-guidelines-class-resource.instructions.md:0-0
Timestamp: 2025-08-25T10:05:30.603Z
Learning: Applies to source/[cC]lasses/**/*.ps1 : Decorate the resource class with [DscResource(RunAsCredential = 'Optional')] (use 'Mandatory' if required)

Applied to files:

  • .github/instructions/dsc-community-style-guidelines-class-resource.instructions.md
📚 Learning: 2025-08-25T10:05:30.603Z
Learnt from: CR
PR: dsccommunity/SqlServerDsc#0
File: .github/instructions/dsc-community-style-guidelines-class-resource.instructions.md:0-0
Timestamp: 2025-08-25T10:05:30.603Z
Learning: Applies to source/[cC]lasses/**/*.ps1 : Use $this.localizedData provided by ResourceBase (auto-populated from the localization file); do not manually populate it

Applied to files:

  • .github/instructions/dsc-community-style-guidelines-class-resource.instructions.md
📚 Learning: 2025-08-25T10:04:22.244Z
Learnt from: CR
PR: dsccommunity/SqlServerDsc#0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-08-25T10:04:22.244Z
Learning: New DSC resources should always be created as class-based resources

Applied to files:

  • .github/instructions/dsc-community-style-guidelines-class-resource.instructions.md
📚 Learning: 2025-08-25T10:05:30.603Z
Learnt from: CR
PR: dsccommunity/SqlServerDsc#0
File: .github/instructions/dsc-community-style-guidelines-class-resource.instructions.md:0-0
Timestamp: 2025-08-25T10:05:30.603Z
Learning: Applies to source/[cC]lasses/**/*.ps1 : Implement hidden [void] NormalizeProperties([System.Collections.Hashtable] $properties) to normalize user-provided properties

Applied to files:

  • .github/instructions/dsc-community-style-guidelines-class-resource.instructions.md
📚 Learning: 2025-08-25T10:09:05.899Z
Learnt from: CR
PR: dsccommunity/SqlServerDsc#0
File: .github/instructions/dsc-community-style-guidelines-powershell.instructions.md:0-0
Timestamp: 2025-08-25T10:09:05.899Z
Learning: Applies to **/*.{ps1,psm1} : Comment-based help must include SYNOPSIS, DESCRIPTION (40+ chars), PARAMETER, EXAMPLE sections before function/class

Applied to files:

  • .github/instructions/dsc-community-style-guidelines-class-resource.instructions.md
📚 Learning: 2025-08-25T10:05:30.603Z
Learnt from: CR
PR: dsccommunity/SqlServerDsc#0
File: .github/instructions/dsc-community-style-guidelines-class-resource.instructions.md:0-0
Timestamp: 2025-08-25T10:05:30.603Z
Learning: Applies to source/[cC]lasses/**/*.ps1 : Implement hidden [void] Modify([System.Collections.Hashtable] $properties) to set desired state only for non-compliant properties

Applied to files:

  • .github/instructions/dsc-community-style-guidelines-class-resource.instructions.md
🧬 Code graph analysis (1)
tests/Integration/Resources/DSC_SqlAgentAlert.config.ps1 (1)
tests/Unit/Stubs/SMO.cs (3)
  • Alert (1604-1646)
  • Microsoft (1499-1649)
  • AlertCollection (1561-1595)
🪛 LanguageTool
.github/instructions/dsc-community-style-guidelines-class-resource.instructions.md

[grammar] ~85-~85: There might be a mistake here.
Context: ...based help Add to .DESCRIPTION section: - ## Requirements: List minimum requirements - `## Known ...

(QB_NEW_EN)


[grammar] ~86-~86: There might be a mistake here.
Context: ...Requirements: List minimum requirements - ## Known issues: Critical issues + pattern: All issues...

(QB_NEW_EN)


[grammar] ~89-~89: There might be a mistake here.
Context: ...tle+{ResourceName}). ## Error Handling - Usetry/catch` blocks to handle excepti...

(QB_NEW_EN)

🪛 markdownlint-cli2 (0.17.2)
.github/instructions/dsc-community-style-guidelines-class-resource.instructions.md

86-86: Lists should be surrounded by blank lines

(MD032, blanks-around-lists)


87-87: Line length
Expected: 80; Actual: 195

(MD013, line-length)


89-89: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below

(MD022, blanks-around-headings)


90-90: Lists should be surrounded by blank lines

(MD032, blanks-around-lists)

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
  • GitHub Check: dsccommunity.SqlServerDsc (Build Package Module)
  • GitHub Check: PSScriptAnalyzer
  • GitHub Check: PSScriptAnalyzer
🔇 Additional comments (2)
tests/Integration/Resources/DSC_SqlAgentAlert.config.ps1 (2)

96-109: Order-of-operations via DependsOn looks correct

The alert depends on the custom message creation, ensuring idempotent sequencing when switching from Severity to MessageId. LGTM.


156-157: Cleanup sequencing is safe

Depending on the alert removal ensures the custom message isn’t dropped while the alert still references it. LGTM.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (7)
.github/instructions/dsc-community-style-guidelines-powershell.instructions.md (2)

52-52: Grammar nit: add missing article in hashtable guideline

Use “a” for correctness and readability.

- - Each property on separate line with proper indentation
+ - Each property on a separate line with proper indentation

84-93: Clarify class-based error handling and wrap long bullets (fix MD013) in “Output streams”

Adds explicit guidance for classes and restructures bullets to satisfy line-length rules without altering meaning.

 ## Output streams

-- Never output sensitive data/secrets
-- Use `Write-Debug` for: Internal diagnostics; Variable values/traces; Developer-focused details
-- Use `Write-Verbose` for: High-level execution flow only; User-actionable information
-- Use `Write-Information` for: User-facing status updates; Important operational messages; Non-error state changes
-- Use `Write-Warning` for: Non-fatal issues requiring attention; Deprecated functionality usage; Configuration problems that don't block execution
-- Use `$PSCmdlet.ThrowTerminatingError()` for terminating errors (except for classes), use relevant error category
-- Use `Write-Error` for non-terminating errors, use relevant error category
+- Never output sensitive data/secrets
+- Use `Write-Debug` for:
+  - Internal diagnostics
+  - Variable values/traces
+  - Developer-focused details
+- Use `Write-Verbose` for:
+  - High-level execution flow only
+  - User-actionable information
+- Use `Write-Information` for:
+  - User-facing status updates
+  - Important operational messages
+  - Non-error state changes
+- Use `Write-Warning` for:
+  - Non-fatal issues requiring attention
+  - Deprecated functionality usage
+  - Configuration problems that don't block execution
+- Terminating errors:
+  - Advanced functions: Use `$PSCmdlet.ThrowTerminatingError()` with a relevant error category.
+  - Classes: Use `throw` with an appropriate Exception or `ErrorRecord`; do not use `Write-Error` for terminating scenarios.
+- Non-terminating errors:
+  - Use `Write-Error` with a relevant error category.
tests/Integration/Resources/DSC_SqlAgentAlert.config.ps1 (5)

27-31: Minor consistency and typing nits for node data.

  • Prefer integers for Severity/MessageId to avoid implicit conversions.
  • File uses $Node.Username later, while the key here is UserName. PowerShell is case-insensitive, but keep it consistent within this file.
-                Name            = 'MockAlert'
-                Severity        = '17'
-                MessageId       = '50001'
+                Name            = 'MockAlert'
+                Severity        = 17
+                MessageId       = 50001

Additionally update usages below for consistency (outside this hunk):

# Replace all occurrences
$Node.Username  ->  $Node.UserName

62-123: Reduce duplication: create one PSCredential and stop using backticks for line continuation.
Define $credential once per node and reuse it; improves readability and aligns with “avoid backticks” guidance.

 Configuration DSC_SqlAgentAlert_ChangeToMessageId_Config
 {
     Import-DscResource -ModuleName 'SqlServerDsc'

     node $AllNodes.NodeName
     {
+        # Reuse a single credential within the node
+        $securePassword = ConvertTo-SecureString -String $Node.Password -AsPlainText -Force
+        $credential     = [System.Management.Automation.PSCredential]::new($Node.UserName, $securePassword)
 
         # First, create the custom system message
         SqlScriptQuery 'CreateCustomMessage'
         {
             Id                   = 'CreateCustomMessage'
             InstanceName         = $Node.InstanceName
             ServerName           = $Node.ServerName
             Encrypt              = 'Optional'
@@
-            PsDscRunAsCredential = New-Object `
-                -TypeName System.Management.Automation.PSCredential `
-                -ArgumentList @($Node.Username, (ConvertTo-SecureString -String $Node.Password -AsPlainText -Force))
+            PsDscRunAsCredential = $credential
         }
 
         SqlAgentAlert 'Integration_Test'
         {
             Ensure               = 'Present'
             ServerName           = $Node.ServerName
             InstanceName         = $Node.InstanceName
             Name                 = $Node.Name
             MessageId            = $Node.MessageId
 
-            PsDscRunAsCredential = New-Object `
-                -TypeName System.Management.Automation.PSCredential `
-                -ArgumentList @($Node.Username, (ConvertTo-SecureString -String $Node.Password -AsPlainText -Force))
+            PsDscRunAsCredential = $credential
 
             DependsOn            = '[SqlScriptQuery]CreateCustomMessage'
         }
     }
 }

90-99: Fix minor grammar in TestQuery messages.
These strings surface in CI logs.

-                    RAISERROR ('Did not found message id [$($Node.MessageId)]', 16, 1)
+                    RAISERROR ('Did not find message id [$($Node.MessageId)]', 16, 1)
@@
-                    PRINT 'Found a message id [$($Node.MessageId)]'
+                    PRINT 'Found message id [$($Node.MessageId)]'

146-181: Apply the same credential reuse and backtick removal in cleanup block.
Keeps style consistent with the creation block and reduces noise.

         # Clean up the custom system message
         SqlScriptQuery 'RemoveCustomMessage'
         {
             Id                   = 'RemoveCustomMessage'
             InstanceName         = $Node.InstanceName
             ServerName           = $Node.ServerName
             Encrypt              = 'Optional'
@@
-            GetQuery             = "SELECT message_id, text FROM sys.messages WHERE message_id = $($Node.MessageId) AND language_id = 1033 FOR JSON AUTO"
+            GetQuery             = "SELECT message_id, text FROM sys.messages WHERE message_id = $($Node.MessageId) AND language_id = 1033 FOR JSON AUTO"
 
-            PsDscRunAsCredential = New-Object `
-                -TypeName System.Management.Automation.PSCredential `
-                -ArgumentList @($Node.Username, (ConvertTo-SecureString -String $Node.Password -AsPlainText -Force))
+            PsDscRunAsCredential = $credential
 
             DependsOn            = '[SqlAgentAlert]Integration_Test'
         }

162-171: Fix minor grammar in cleanup TestQuery messages.

-                    RAISERROR ('Found message id [$($Node.MessageId)]', 16, 1)
+                    RAISERROR ('Found message id [$($Node.MessageId)]', 16, 1) -- keep as-is if raising is intentional
@@
-                    PRINT 'Did not found a message id [$($Node.MessageId)]'
+                    PRINT 'Did not find message id [$($Node.MessageId)]'

Note: If the RAISERROR on “Found message id …” is intentional (to signal failure when it still exists), keep it; this change only addresses the PRINT text.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

💡 Knowledge Base configuration:

  • Jira integration is disabled
  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between d75a5da and b3a7de8.

📒 Files selected for processing (4)
  • .github/instructions/dsc-community-style-guidelines-integration-tests.instructions.md (1 hunks)
  • .github/instructions/dsc-community-style-guidelines-powershell.instructions.md (2 hunks)
  • .github/instructions/dsc-community-style-guidelines-unit-tests.instructions.md (2 hunks)
  • tests/Integration/Resources/DSC_SqlAgentAlert.config.ps1 (3 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • .github/instructions/dsc-community-style-guidelines-unit-tests.instructions.md
🧰 Additional context used
📓 Path-based instructions (4)
**/*.{ps1,psm1,psd1}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

Always follow PowerShell code style guidelines (./instructions/dsc-community-style-guidelines-powershell.instructions.md)

**/*.{ps1,psm1,psd1}: Use 4 spaces for indentation (no tabs)
One space around operators (e.g., $a = 1 + 2)
No spaces on empty lines
Try to limit lines to 120 characters
Use single quotes unless variable expansion is needed
Arrays single-line: @('one','two','three')
Arrays multi-line: each element on its own indented line
Hashtables empty literal uses @{}
Hashtables multi-line: each property on a separate indented line
Hashtable properties use PascalCase
Single-line comments use '# Comment' style: capitalized, on own line
Multi-line comments use <# #> with brackets on their own lines and indented text
End files with only one blank line
Use CR+LF line endings
Maximum of two consecutive newlines
Use UTF-8 encoding without BOM for all files

Files:

  • tests/Integration/Resources/DSC_SqlAgentAlert.config.ps1
**/*.{ps1,psm1}

📄 CodeRabbit inference engine (.github/instructions/SqlServerDsc-guidelines.instructions.md)

**/*.{ps1,psm1}: Public PowerShell commands must follow the naming format: Verb-SqlDsc{Noun}
Prefer SMO over T-SQL for SQL Server interaction

**/*.{ps1,psm1}: Use descriptive names (3+ characters, no abbreviations)
Function names use PascalCase with Verb-Noun format using approved verbs
Parameter names use PascalCase
Variable names use camelCase
Keywords should be lower-case
Include scope qualifier for script/global/environment variables: $script:, $global:, $env:
One space between type and variable (e.g., [String] $name)
One space between keyword and parenthesis (e.g., if ($condition))
Newline before opening brace (except variable assignments)
One newline after opening brace
Two newlines after closing brace (one if followed by another brace or continuation)
Do not use the unary comma operator in return statements to force an array
Do not keep commented-out code
Always add comment-based help to all functions and scripts
Comment-based help must include SYNOPSIS, DESCRIPTION (40+ chars), PARAMETER, EXAMPLE sections before function/class
Comment-based help indentation: keywords at 4 spaces, text at 8 spaces
Include examples for all parameter sets and combinations in help
INPUTS: list each pipeline-accepted type (one per line) with a 1‑line description
OUTPUTS: list each return type (one per line) with a 1‑line description; must match [OutputType()] and actual returns
.NOTES only when critical (constraints, side effects, security, version compatibility, breaking behavior), ≤2 short sentences
Avoid aliases; use full command names
Avoid Write-Host; prefer Write-Verbose/Write-Information, etc.
Avoid Write-Output; use 'return' instead
Avoid ConvertTo-SecureString -AsPlainText in production code
Do not redefine reserved parameters (Verbose, Debug, etc.)
Include a Force parameter for functions that support ShouldContinue or use ShouldProcess
For state-changing functions, set SupportsShouldProcess
Use $PSCmdlet.ThrowTerminatingError() for terminating errors with relevant ...

Files:

  • tests/Integration/Resources/DSC_SqlAgentAlert.config.ps1
**

⚙️ CodeRabbit configuration file

**: # DSC Community Guidelines

Terminology

  • Command: Public command
  • Function: Private function
  • Resource: DSC class-based resource

Build & Test Workflow

  • Run project scripts in PowerShell from repository root
  • Build after source changes: .\build.ps1 -Tasks build
  • Test workflow: Build → Invoke-Pester -Path @('<test paths>') -Output Detailed
  • New session required after class changes

File Organization

  • Public commands: source/Public/{CommandName}.ps1
  • Private functions: source/Private/{FunctionName}.ps1
  • Unit tests: tests/Unit/{Classes|Public|Private}/{Name}.Tests.ps1
  • Integration tests: tests/Integration/Commands/{CommandName}.Integration.Tests.ps1

Requirements

  • Follow guidelines over existing code patterns
  • Always update CHANGELOG.md Unreleased section
  • Localize all strings using string keys; remove any orphaned string keys
  • Check DscResource.Common before creating private functions
  • Separate reusable logic into private functions
  • Add unit tests for all commands/functions/resources
  • Add integration tests for all public commands and resources

Files:

  • tests/Integration/Resources/DSC_SqlAgentAlert.config.ps1
**/*.ps?(m|d)1

⚙️ CodeRabbit configuration file

**/*.ps?(m|d)1: # PowerShell Guidelines

Naming

  • Use descriptive names (3+ characters, no abbreviations)
  • Functions: PascalCase with Verb-Noun format using approved verbs
  • Parameters: PascalCase
  • Variables: camelCase
  • Keywords: lower-case
  • Classes: PascalCase
  • Include scope for script/global/environment variables: $script:, $global:, $env:

File naming

  • Class files: ###.ClassName.ps1 format (e.g. 001.SqlReason.ps1, 004.StartupParameters.ps1)

Formatting

Indentation & Spacing

  • Use 4 spaces (no tabs)
  • One space around operators: $a = 1 + 2
  • One space between type and variable: [String] $name
  • One space between keyword and parenthesis: if ($condition)
  • No spaces on empty lines
  • Try to limit lines to 120 characters

Braces

  • Newline before opening brace (except variable assignments)
  • One newline after opening brace
  • Two newlines after closing brace (one if followed by another brace or continuation)

Quotes

  • Use single quotes unless variable expansion is needed: 'text' vs "text $variable"

Arrays

  • Single line: @('one', 'two', 'three')
  • Multi-line: each element on separate line with proper indentation
  • Do not use the unary comma operator (,) in return statements to force
    an array

Hashtables

  • Empty: @{}
  • Multi-line: each property on separate line with proper indentation
  • Properties: Use PascalCase

Comments

  • Single line: # Comment (capitalized, on own line)
  • Multi-line: <# Comment #> format (opening and closing brackets on own line), and indent text
  • No commented-out code

Comment-based help

  • Always add comment-based help to all functions and scripts
  • Comment-based help: SYNOPSIS, DESCRIPTION (40+ chars), PARAMETER, EXAMPLE sections before function/class
  • Comment-based help indentation: keywords 4 spaces, text 8 spaces
  • Include examples for all parameter sets and combinations
  • INPUTS: List each pipeline‑accepted type (one per line) with a 1‑line description.
  • ...

Files:

  • tests/Integration/Resources/DSC_SqlAgentAlert.config.ps1
🧠 Learnings (28)
📓 Common learnings
Learnt from: CR
PR: dsccommunity/SqlServerDsc#0
File: .github/instructions/SqlServerDsc-guidelines.instructions.md:0-0
Timestamp: 2025-08-25T10:04:53.158Z
Learning: Applies to **/DSCResources/**.{ps1,psm1} : Database Engine DSC resources must inherit the SqlResourceBase base class
📚 Learning: 2025-08-25T10:04:22.244Z
Learnt from: CR
PR: dsccommunity/SqlServerDsc#0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-08-25T10:04:22.244Z
Learning: Always add Integration testing according to (./instructions/dsc-community-style-guidelines-integration-tests.instructions.md)

Applied to files:

  • .github/instructions/dsc-community-style-guidelines-integration-tests.instructions.md
📚 Learning: 2025-08-17T10:15:48.194Z
Learnt from: johlju
PR: dsccommunity/SqlServerDsc#2136
File: tests/Unit/Public/Remove-SqlDscLogin.Tests.ps1:36-39
Timestamp: 2025-08-17T10:15:48.194Z
Learning: Public command unit tests guideline: Never use InModuleScope unless accessing localized strings from $script:localizedData. PSDefaultParameterValues for InModuleScope should be kept in public command tests to support localized string retrieval when necessary.

Applied to files:

  • .github/instructions/dsc-community-style-guidelines-integration-tests.instructions.md
📚 Learning: 2025-08-25T10:04:53.158Z
Learnt from: CR
PR: dsccommunity/SqlServerDsc#0
File: .github/instructions/SqlServerDsc-guidelines.instructions.md:0-0
Timestamp: 2025-08-25T10:04:53.158Z
Learning: Applies to tests/Unit/**/*.Tests.ps1 : Unit tests must set $env:SqlServerDscCI = $true in BeforeAll and remove it in AfterAll

Applied to files:

  • .github/instructions/dsc-community-style-guidelines-integration-tests.instructions.md
📚 Learning: 2025-08-25T10:07:49.137Z
Learnt from: CR
PR: dsccommunity/SqlServerDsc#0
File: .github/instructions/dsc-community-style-guidelines-pester.instructions.md:0-0
Timestamp: 2025-08-25T10:07:49.137Z
Learning: Applies to **/*.[Tt]ests.ps1 : Define mocks in BeforeAll (use BeforeEach for mocking only when required)

Applied to files:

  • .github/instructions/dsc-community-style-guidelines-integration-tests.instructions.md
📚 Learning: 2025-08-25T10:09:05.899Z
Learnt from: CR
PR: dsccommunity/SqlServerDsc#0
File: .github/instructions/dsc-community-style-guidelines-powershell.instructions.md:0-0
Timestamp: 2025-08-25T10:09:05.899Z
Learning: Applies to **/*.{ps1,psm1} : Avoid global variables (exception: $global:DSCMachineStatus)

Applied to files:

  • .github/instructions/dsc-community-style-guidelines-integration-tests.instructions.md
📚 Learning: 2025-08-25T10:07:49.137Z
Learnt from: CR
PR: dsccommunity/SqlServerDsc#0
File: .github/instructions/dsc-community-style-guidelines-pester.instructions.md:0-0
Timestamp: 2025-08-25T10:07:49.137Z
Learning: Applies to tests/Unit/{Private,Classes}/**/*.Tests.ps1 : For private functions and class resource tests, always use InModuleScope

Applied to files:

  • .github/instructions/dsc-community-style-guidelines-integration-tests.instructions.md
📚 Learning: 2025-08-25T10:07:49.137Z
Learnt from: CR
PR: dsccommunity/SqlServerDsc#0
File: .github/instructions/dsc-community-style-guidelines-pester.instructions.md:0-0
Timestamp: 2025-08-25T10:07:49.137Z
Learning: Applies to **/*.[Tt]ests.ps1 : Use BeforeEach and AfterEach sparingly

Applied to files:

  • .github/instructions/dsc-community-style-guidelines-integration-tests.instructions.md
📚 Learning: 2025-08-25T10:07:49.137Z
Learnt from: CR
PR: dsccommunity/SqlServerDsc#0
File: .github/instructions/dsc-community-style-guidelines-pester.instructions.md:0-0
Timestamp: 2025-08-25T10:07:49.137Z
Learning: Applies to **/*.[Tt]ests.ps1 : Place setup/teardown in the nearest appropriate BeforeAll/BeforeEach/AfterAll/AfterEach to where it is used

Applied to files:

  • .github/instructions/dsc-community-style-guidelines-integration-tests.instructions.md
📚 Learning: 2025-08-25T10:07:22.349Z
Learnt from: CR
PR: dsccommunity/SqlServerDsc#0
File: .github/instructions/dsc-community-style-guidelines-mof-resources.instructions.md:0-0
Timestamp: 2025-08-25T10:07:22.349Z
Learning: Applies to source/DSCResources/**/*.psm1 : Import localized strings at the top of the module using Get-LocalizedData

Applied to files:

  • .github/instructions/dsc-community-style-guidelines-integration-tests.instructions.md
📚 Learning: 2025-08-25T10:05:48.627Z
Learnt from: CR
PR: dsccommunity/SqlServerDsc#0
File: .github/instructions/dsc-community-style-guidelines-integration-tests.instructions.md:0-0
Timestamp: 2025-08-25T10:05:48.627Z
Learning: Applies to tests/[iI]ntegration/**/*.[iI]ntegration.[tT]ests.ps1 : Include the required Pester setup block (the provided BeforeDiscovery, BeforeAll, module import, and suppression) in every integration test file

Applied to files:

  • .github/instructions/dsc-community-style-guidelines-integration-tests.instructions.md
📚 Learning: 2025-08-25T10:07:49.137Z
Learnt from: CR
PR: dsccommunity/SqlServerDsc#0
File: .github/instructions/dsc-community-style-guidelines-pester.instructions.md:0-0
Timestamp: 2025-08-25T10:07:49.137Z
Learning: Applies to **/*.[Tt]ests.ps1 : For data-driven tests, define variables in a separate BeforeDiscovery for -ForEach close to usage

Applied to files:

  • .github/instructions/dsc-community-style-guidelines-integration-tests.instructions.md
📚 Learning: 2025-08-25T10:04:22.244Z
Learnt from: CR
PR: dsccommunity/SqlServerDsc#0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-08-25T10:04:22.244Z
Learning: Applies to **/*.{ps1,psm1,psd1} : Always follow PowerShell code style guidelines (./instructions/dsc-community-style-guidelines-powershell.instructions.md)

Applied to files:

  • .github/instructions/dsc-community-style-guidelines-powershell.instructions.md
📚 Learning: 2025-08-25T10:09:05.899Z
Learnt from: CR
PR: dsccommunity/SqlServerDsc#0
File: .github/instructions/dsc-community-style-guidelines-powershell.instructions.md:0-0
Timestamp: 2025-08-25T10:09:05.899Z
Learning: Applies to **/*.{ps1,psm1} : .NOTES only when critical (constraints, side effects, security, version compatibility, breaking behavior), ≤2 short sentences

Applied to files:

  • .github/instructions/dsc-community-style-guidelines-powershell.instructions.md
📚 Learning: 2025-08-25T10:09:05.899Z
Learnt from: CR
PR: dsccommunity/SqlServerDsc#0
File: .github/instructions/dsc-community-style-guidelines-powershell.instructions.md:0-0
Timestamp: 2025-08-25T10:09:05.899Z
Learning: Applies to **/*.{ps1,psm1,psd1} : Hashtables multi-line: each property on a separate indented line

Applied to files:

  • .github/instructions/dsc-community-style-guidelines-powershell.instructions.md
📚 Learning: 2025-08-25T10:09:05.899Z
Learnt from: CR
PR: dsccommunity/SqlServerDsc#0
File: .github/instructions/dsc-community-style-guidelines-powershell.instructions.md:0-0
Timestamp: 2025-08-25T10:09:05.899Z
Learning: Applies to **/*.{ps1,psm1,psd1} : Hashtables empty literal uses @{}

Applied to files:

  • .github/instructions/dsc-community-style-guidelines-powershell.instructions.md
📚 Learning: 2025-08-25T10:09:05.899Z
Learnt from: CR
PR: dsccommunity/SqlServerDsc#0
File: .github/instructions/dsc-community-style-guidelines-powershell.instructions.md:0-0
Timestamp: 2025-08-25T10:09:05.899Z
Learning: Applies to **/*.{ps1,psm1,psd1} : Multi-line comments use <# #> with brackets on their own lines and indented text

Applied to files:

  • .github/instructions/dsc-community-style-guidelines-powershell.instructions.md
📚 Learning: 2025-08-25T10:09:05.899Z
Learnt from: CR
PR: dsccommunity/SqlServerDsc#0
File: .github/instructions/dsc-community-style-guidelines-powershell.instructions.md:0-0
Timestamp: 2025-08-25T10:09:05.899Z
Learning: Applies to **/*.{ps1,psm1,psd1} : Single-line comments use '# Comment' style: capitalized, on own line

Applied to files:

  • .github/instructions/dsc-community-style-guidelines-powershell.instructions.md
📚 Learning: 2025-08-25T10:09:05.899Z
Learnt from: CR
PR: dsccommunity/SqlServerDsc#0
File: .github/instructions/dsc-community-style-guidelines-powershell.instructions.md:0-0
Timestamp: 2025-08-25T10:09:05.899Z
Learning: Applies to **/*.{ps1,psm1,psd1} : Hashtable properties use PascalCase

Applied to files:

  • .github/instructions/dsc-community-style-guidelines-powershell.instructions.md
📚 Learning: 2025-08-25T10:09:05.899Z
Learnt from: CR
PR: dsccommunity/SqlServerDsc#0
File: .github/instructions/dsc-community-style-guidelines-powershell.instructions.md:0-0
Timestamp: 2025-08-25T10:09:05.899Z
Learning: Applies to **/*.{ps1,psm1,psd1} : Arrays multi-line: each element on its own indented line

Applied to files:

  • .github/instructions/dsc-community-style-guidelines-powershell.instructions.md
📚 Learning: 2025-08-25T10:09:05.899Z
Learnt from: CR
PR: dsccommunity/SqlServerDsc#0
File: .github/instructions/dsc-community-style-guidelines-powershell.instructions.md:0-0
Timestamp: 2025-08-25T10:09:05.899Z
Learning: Applies to **/*.{ps1,psm1} : For state-changing functions, set SupportsShouldProcess

Applied to files:

  • .github/instructions/dsc-community-style-guidelines-powershell.instructions.md
📚 Learning: 2025-08-25T10:09:05.899Z
Learnt from: CR
PR: dsccommunity/SqlServerDsc#0
File: .github/instructions/dsc-community-style-guidelines-powershell.instructions.md:0-0
Timestamp: 2025-08-25T10:09:05.899Z
Learning: Applies to **/*.{ps1,psm1} : Avoid Write-Output; use 'return' instead

Applied to files:

  • .github/instructions/dsc-community-style-guidelines-powershell.instructions.md
📚 Learning: 2025-08-25T10:09:05.899Z
Learnt from: CR
PR: dsccommunity/SqlServerDsc#0
File: .github/instructions/dsc-community-style-guidelines-powershell.instructions.md:0-0
Timestamp: 2025-08-25T10:09:05.899Z
Learning: Applies to **/*.{ps1,psm1} : Avoid Write-Host; prefer Write-Verbose/Write-Information, etc.

Applied to files:

  • .github/instructions/dsc-community-style-guidelines-powershell.instructions.md
📚 Learning: 2025-08-25T10:09:05.899Z
Learnt from: CR
PR: dsccommunity/SqlServerDsc#0
File: .github/instructions/dsc-community-style-guidelines-powershell.instructions.md:0-0
Timestamp: 2025-08-25T10:09:05.899Z
Learning: Applies to **/*.{ps1,psm1} : Use Write-Error for non-terminating errors with relevant category

Applied to files:

  • .github/instructions/dsc-community-style-guidelines-powershell.instructions.md
📚 Learning: 2025-08-25T10:09:05.899Z
Learnt from: CR
PR: dsccommunity/SqlServerDsc#0
File: .github/instructions/dsc-community-style-guidelines-powershell.instructions.md:0-0
Timestamp: 2025-08-25T10:09:05.899Z
Learning: Applies to **/*.{ps1,psm1} : Use $PSCmdlet.ThrowTerminatingError() for terminating errors with relevant category

Applied to files:

  • .github/instructions/dsc-community-style-guidelines-powershell.instructions.md
📚 Learning: 2025-08-16T13:15:17.108Z
Learnt from: johlju
PR: dsccommunity/SqlServerDsc#2134
File: source/Public/Get-SqlDscLogin.ps1:27-38
Timestamp: 2025-08-16T13:15:17.108Z
Learning: For PowerShell comment-based help .OUTPUTS sections: Each distinct return type should have its own .OUTPUTS entry with a description of when that type is returned, even if the underlying implementation uses array casting. This follows official PowerShell documentation standards where you list each return type on its own line under .OUTPUTS with clear descriptions of the conditions for each type.

Applied to files:

  • .github/instructions/dsc-community-style-guidelines-powershell.instructions.md
📚 Learning: 2025-08-16T13:15:17.108Z
Learnt from: johlju
PR: dsccommunity/SqlServerDsc#2134
File: source/Public/Get-SqlDscLogin.ps1:27-38
Timestamp: 2025-08-16T13:15:17.108Z
Learning: For PowerShell comment-based help in .OUTPUTS sections: Each distinct type that can be returned should have its own .OUTPUTS entry, even if the implementation technically always returns an array. This follows official PowerShell documentation standards and helps users understand what to expect in different usage scenarios.

Applied to files:

  • .github/instructions/dsc-community-style-guidelines-powershell.instructions.md
📚 Learning: 2025-08-25T10:09:05.899Z
Learnt from: CR
PR: dsccommunity/SqlServerDsc#0
File: .github/instructions/dsc-community-style-guidelines-powershell.instructions.md:0-0
Timestamp: 2025-08-25T10:09:05.899Z
Learning: Applies to **/*.{ps1,psm1} : Include a Force parameter for functions that support ShouldContinue or use ShouldProcess

Applied to files:

  • .github/instructions/dsc-community-style-guidelines-powershell.instructions.md
🧬 Code graph analysis (1)
tests/Integration/Resources/DSC_SqlAgentAlert.config.ps1 (1)
tests/Unit/Stubs/SMO.cs (4)
  • Alert (1604-1646)
  • Microsoft (1499-1649)
  • AlertCollection (1561-1595)
  • Remove (1583-1583)
🪛 LanguageTool
.github/instructions/dsc-community-style-guidelines-powershell.instructions.md

[grammar] ~52-~52: There might be a mistake here.
Context: ...htables - Empty: @{} - Each property on separate line with proper indentation -...

(QB_NEW_EN)

🪛 markdownlint-cli2 (0.17.2)
.github/instructions/dsc-community-style-guidelines-powershell.instructions.md

87-87: Line length
Expected: 80; Actual: 96

(MD013, line-length)


89-89: Line length
Expected: 80; Actual: 114

(MD013, line-length)


90-90: Line length
Expected: 80; Actual: 146

(MD013, line-length)


91-91: Line length
Expected: 80; Actual: 114

(MD013, line-length)

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
  • GitHub Check: dsccommunity.SqlServerDsc (Build Package Module)
  • GitHub Check: PSScriptAnalyzer
  • GitHub Check: PSScriptAnalyzer
🔇 Additional comments (1)
.github/instructions/dsc-community-style-guidelines-integration-tests.instructions.md (1)

48-50: Rename to $script:moduleName looks good; import statement updated accordingly.
No functional/regression concerns in this snippet.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

♻️ Duplicate comments (2)
source/Classes/020.SqlAgentAlert.ps1 (2)

296-309: When switching between Severity and MessageId, clear the other one

Avoid ending up with both set. Clear the non-selected field during update.

-                if ($properties.ContainsKey('Severity') -and $alertObject.Severity -ne $properties.Severity)
-                {
-                    $setAlertParameters.Severity = $properties.Severity
-                    $needsUpdate = $true
-                }
-
-                if ($properties.ContainsKey('MessageId') -and $alertObject.MessageId -ne $properties.MessageId)
-                {
-                    $setAlertParameters.MessageId = $properties.MessageId
-                    $needsUpdate = $true
-                }
+                if ($properties.ContainsKey('Severity'))
+                {
+                    if ($alertObject.Severity -ne $properties.Severity)
+                    {
+                        $setAlertParameters.Severity = $properties.Severity
+                        $needsUpdate = $true
+                    }
+                    if ($alertObject.MessageId -ne 0)
+                    {
+                        $setAlertParameters.MessageId = 0
+                        $needsUpdate = $true
+                    }
+                }
+
+                if ($properties.ContainsKey('MessageId'))
+                {
+                    if ($alertObject.MessageId -ne $properties.MessageId)
+                    {
+                        $setAlertParameters.MessageId = $properties.MessageId
+                        $needsUpdate = $true
+                    }
+                    if ($alertObject.Severity -ne 0)
+                    {
+                        $setAlertParameters.Severity = 0
+                        $needsUpdate = $true
+                    }
+                }

170-181: Fix AssertProperties: use $this.Ensure; throw the exception; remove dead duplicate check

  • $properties.Ensure may be absent; use $this.Ensure.
  • New-InvalidArgumentException must be thrown.
  • The manual ContainsKey check is redundant with Assert-BoundParameter and currently unreachable.

Apply:

 hidden [void] AssertProperties([System.Collections.Hashtable] $properties)
 {
@@
-        Assert-BoundParameter @assertMutuallyExclusiveParams
+        Assert-BoundParameter @assertMutuallyExclusiveParams
@@
-        if ($properties.Ensure -eq 'Absent')
+        if ($this.Ensure -eq 'Absent')
         {
             # When Ensure is 'Absent', Severity and MessageId must not be set
             $assertAbsentParams = @{
                 BoundParameterList   = $properties
                 NotAllowedList       = @('Severity', 'MessageId')
                 IfEqualParameterList = @{
                     Ensure = 'Absent'
                 }
             }
 
             Assert-BoundParameter @assertAbsentParams
-
-            if ($properties.ContainsKey('Severity') -or $properties.ContainsKey('MessageId'))
-            {
-                $errorMessage = $this.localizedData.SqlAgentAlert_SeverityOrMessageIdNotAllowedWhenAbsent
-
-                New-InvalidArgumentException -ArgumentName 'Severity, MessageId' -Message $errorMessage
-            }
+            # Extra guard with localized error if needed elsewhere:
+            if ($properties.ContainsKey('Severity') -or $properties.ContainsKey('MessageId'))
+            {
+                $errorMessage = $this.localizedData.SqlAgentAlert_SeverityOrMessageIdNotAllowedWhenAbsent
+                throw (New-InvalidArgumentException -ArgumentName 'Severity, MessageId' -Message $errorMessage)
+            }
         }
 }

Also applies to: 195-214

🧹 Nitpick comments (5)
.github/instructions/dsc-community-style-guidelines-pester.instructions.md (4)

17-22: Fix markdownlint MD022/MD032 in “Naming” and clarify mock variable rule

Add a blank line after the heading and tighten the mock variable guidance with examples.

-## Naming
-- One `Describe` block per file matching the tested entity name
-- `Context` descriptions start with 'When'
-- `It` descriptions start with 'Should', must not contain 'when'
-- Mock variables prefix: 'mock'
+## Naming
+
+- One `Describe` block per file matching the tested entity name
+- `Context` descriptions start with 'When'
+- `It` descriptions start with 'Should'; do not include 'when'
+- Mock variable names start with 'mock' (e.g., `$mockServer`, `$mockSmo`)

Also apply the “blank line after heading” pattern to other sections to silence MD022/MD032 across the file.


26-26: Soften “1 Context per method” to avoid boilerplate

Make it a preference with an allowance to group trivial accessors.

- - Each class method = separate `Context` block
+ - Prefer one `Context` block per class method; group trivial accessors together when clearer

33-33: Wrap long bullet to satisfy MD013 (line length)

Break across two lines.

-- PascalCase: `Describe`, `Context`, `It`, `Should`, `BeforeAll`, `BeforeEach`, `AfterAll`, `AfterEach`
+- PascalCase: `Describe`, `Context`, `It`, `Should`,
+  `BeforeAll`, `BeforeEach`, `AfterAll`, `AfterEach`

41-41: Clarify Mock usage with InModuleScope

Add how to scope mocks instead of banning without guidance.

- - Never use `Mock` inside `InModuleScope`-block
+ - Do not call `Mock` inside an `InModuleScope` block; define mocks outside and
+   scope them via `-ModuleName` or `$PSDefaultParameterValues`.
source/Classes/020.SqlAgentAlert.ps1 (1)

10-14: Minor help text grammar fixes

Keep docs crisp; suggested edits:

-        The built-in parameter **PSDscRunAsCredential** can be used to run the resource
-        as another user. The resource will then authenticate to the _SQL Server_
-        instance as that user. It also possible to instead use impersonation by the
-        parameter **Credential**.
+        The built-in parameter **PSDscRunAsCredential** can run the resource
+        as another user. The resource will then authenticate to the _SQL Server_
+        instance as that user. It is also possible to use impersonation via the
+        **Credential** parameter.
@@
-        SQL Authentication and Group Managed Service Accounts is not supported as
-        impersonation credentials. Currently only Windows Integrated Security is
-        supported to use as credentials.
+        SQL Authentication and Group Managed Service Accounts are not supported as
+        impersonation credentials. Currently, only Windows Integrated Security is
+        supported.
@@
-        together with class-based resources that using advanced type like the parameter
-        **Reasons** have.
+        together with class-based resources that use advanced types like the
+        **Reasons** property.

Also applies to: 36-45, 26-33

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

💡 Knowledge Base configuration:

  • Jira integration is disabled
  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between b3a7de8 and 809953f.

📒 Files selected for processing (3)
  • .github/instructions/dsc-community-style-guidelines-pester.instructions.md (1 hunks)
  • source/Classes/020.SqlAgentAlert.ps1 (1 hunks)
  • tests/Unit/Classes/SqlAgentAlert.Tests.ps1 (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • tests/Unit/Classes/SqlAgentAlert.Tests.ps1
🧰 Additional context used
📓 Path-based instructions (7)
**/*.{ps1,psm1,psd1}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

Always follow PowerShell code style guidelines (./instructions/dsc-community-style-guidelines-powershell.instructions.md)

**/*.{ps1,psm1,psd1}: Use 4 spaces for indentation (no tabs)
One space around operators (e.g., $a = 1 + 2)
No spaces on empty lines
Try to limit lines to 120 characters
Use single quotes unless variable expansion is needed
Arrays single-line: @('one','two','three')
Arrays multi-line: each element on its own indented line
Hashtables empty literal uses @{}
Hashtables multi-line: each property on a separate indented line
Hashtable properties use PascalCase
Single-line comments use '# Comment' style: capitalized, on own line
Multi-line comments use <# #> with brackets on their own lines and indented text
End files with only one blank line
Use CR+LF line endings
Maximum of two consecutive newlines
Use UTF-8 encoding without BOM for all files

Files:

  • source/Classes/020.SqlAgentAlert.ps1
**/*.{ps1,psm1}

📄 CodeRabbit inference engine (.github/instructions/SqlServerDsc-guidelines.instructions.md)

**/*.{ps1,psm1}: Public PowerShell commands must follow the naming format: Verb-SqlDsc{Noun}
Prefer SMO over T-SQL for SQL Server interaction

**/*.{ps1,psm1}: Use descriptive names (3+ characters, no abbreviations)
Function names use PascalCase with Verb-Noun format using approved verbs
Parameter names use PascalCase
Variable names use camelCase
Keywords should be lower-case
Include scope qualifier for script/global/environment variables: $script:, $global:, $env:
One space between type and variable (e.g., [String] $name)
One space between keyword and parenthesis (e.g., if ($condition))
Newline before opening brace (except variable assignments)
One newline after opening brace
Two newlines after closing brace (one if followed by another brace or continuation)
Do not use the unary comma operator in return statements to force an array
Do not keep commented-out code
Always add comment-based help to all functions and scripts
Comment-based help must include SYNOPSIS, DESCRIPTION (40+ chars), PARAMETER, EXAMPLE sections before function/class
Comment-based help indentation: keywords at 4 spaces, text at 8 spaces
Include examples for all parameter sets and combinations in help
INPUTS: list each pipeline-accepted type (one per line) with a 1‑line description
OUTPUTS: list each return type (one per line) with a 1‑line description; must match [OutputType()] and actual returns
.NOTES only when critical (constraints, side effects, security, version compatibility, breaking behavior), ≤2 short sentences
Avoid aliases; use full command names
Avoid Write-Host; prefer Write-Verbose/Write-Information, etc.
Avoid Write-Output; use 'return' instead
Avoid ConvertTo-SecureString -AsPlainText in production code
Do not redefine reserved parameters (Verbose, Debug, etc.)
Include a Force parameter for functions that support ShouldContinue or use ShouldProcess
For state-changing functions, set SupportsShouldProcess
Use $PSCmdlet.ThrowTerminatingError() for terminating errors with relevant ...

Files:

  • source/Classes/020.SqlAgentAlert.ps1
source/[cC]lasses/*.ps1

📄 CodeRabbit inference engine (.github/instructions/dsc-community-style-guidelines-class-resource.instructions.md)

Place each DSC class-based resource in source/Classes/{ResourceName}.ps1

Files:

  • source/Classes/020.SqlAgentAlert.ps1
source/[cC]lasses/**/*.ps1

📄 CodeRabbit inference engine (.github/instructions/dsc-community-style-guidelines-class-resource.instructions.md)

source/[cC]lasses/**/*.ps1: Decorate the resource class with [DscResource(RunAsCredential = 'Optional')] (use 'Mandatory' if required)
Only classes with a [DscResource(...)] decoration are considered DSC resources to which these rules apply
Resource classes must inherit ResourceBase (from the DscResource.Base module)
Use $this.localizedData provided by ResourceBase (auto-populated from the localization file); do not manually populate it
Implement Get() that delegates to ([ResourceBase] $this).Get(), optionally post-processes, and returns the current state object
Implement Test() that delegates to ([ResourceBase] $this).Test(), optionally post-processes, and returns a [System.Boolean]
Implement Set() that delegates to ([ResourceBase] $this).Set(), with optional additional changes not handled by Modify()
Implement hidden [System.Collections.Hashtable] GetCurrentState([System.Collections.Hashtable] $properties) to return current state
Implement hidden [void] Modify([System.Collections.Hashtable] $properties) to set desired state only for non-compliant properties
Implement hidden [void] AssertProperties([System.Collections.Hashtable] $properties) to validate user-provided properties
Implement hidden [void] NormalizeProperties([System.Collections.Hashtable] $properties) to normalize user-provided properties

Files:

  • source/Classes/020.SqlAgentAlert.ps1

⚙️ CodeRabbit configuration file

source/[cC]lasses/**/*.ps1: # DSC Class-Based Resource Guidelines

Applies to: Classes with [DscResource(...)] decoration only.

Requirements

  • File: source/Classes/020.{ResourceName}.ps1
  • Decoration: [DscResource(RunAsCredential = 'Optional')] (replace with 'Mandatory' if required)
  • Inheritance: Must inherit ResourceBase (part of module DscResource.Base)
  • $this.localizedData hashtable auto-populated by ResourceBase from localization file

Required constructor

MyResourceName () : base ($PSScriptRoot)
{
    # Property names where state cannot be enforced, e.g Ensure
    $this.ExcludeDscProperties = @()
}

Required Method Pattern

[MyResourceName] Get()
{
    # Call base implementation to get current state
    $currentState = ([ResourceBase] $this).Get()

    # If needed, post-processing on current state that can not be handled by GetCurrentState()

    return $currentState
}

[System.Boolean] Test()
{
    # Call base implementation to test current state
    $inDesiredState = ([ResourceBase] $this).Test()

    # If needed, post-processing on test result that can not be handled by base Test()

    return $inDesiredState
}

[void] Set()
{
    # Call base implementation to set desired state
    ([ResourceBase] $this).Set()

    # If needed, additional state changes that can not be handled by Modify()
}

hidden [System.Collections.Hashtable] GetCurrentState([System.Collections.Hashtable] $properties)
{
    # Always return current state as hashtable, $properties contains key properties
}

hidden [void] Modify([System.Collections.Hashtable] $properties)
{
    # Always set desired state, $properties contain those that must change state
}

Optional Method Pattern

hidden [void] AssertProperties([System.Collections.Hashtable] $properties)
{
    # Validate user-provided properties, $properties contains user assigned values
}

hidden [void] NormalizeProperties([System.Collections.Hashtable] $pr...

Files:

  • source/Classes/020.SqlAgentAlert.ps1
source/**/*.ps1

📄 CodeRabbit inference engine (.github/instructions/dsc-community-style-guidelines-localization.instructions.md)

source/**/*.ps1: Localize all Write-Debug, Write-Verbose, Write-Error, Write-Warning, and $PSCmdlet.ThrowTerminatingError() messages
Do not hardcode user-facing strings; use localized string keys instead
Access localized strings via $script:localizedData, formatting with -f when needed

Localize all strings in source code using string keys

Files:

  • source/Classes/020.SqlAgentAlert.ps1

⚙️ CodeRabbit configuration file

source/**/*.ps1: # Localization Guidelines

Requirements

  • Localize all Write-Debug, Write-Verbose, Write-Error, Write-Warning and $PSCmdlet.ThrowTerminatingError() messages
  • Use localized string keys, not hardcoded strings
  • Assume $script:localizedData is available

String Files

  • Commands/functions: source/en-US/SqlServerDsc.strings.psd1
  • Class resources: source/en-US/{ResourceClassName}.strings.psd1

Key Naming Patterns

  • Format: Verb_FunctionName_Action (underscore separators), e.g. Get_SqlDscDatabase_ConnectingToDatabase

String Format

ConvertFrom-StringData @'
    KeyName = Message with {0} placeholder. (PREFIX0001)
'@

String IDs

  • Format: (PREFIX####)
  • PREFIX: First letter of each word in class or function name (SqlSetup → SS, Get-SqlDscDatabase → GSDD)
  • Number: Sequential from 0001

Usage

Write-Verbose -Message ($script:localizedData.KeyName -f $value1)

Files:

  • source/Classes/020.SqlAgentAlert.ps1
**

⚙️ CodeRabbit configuration file

**: # DSC Community Guidelines

Terminology

  • Command: Public command
  • Function: Private function
  • Resource: DSC class-based resource

Build & Test Workflow

  • Run project scripts in PowerShell from repository root
  • Build after source changes: .\build.ps1 -Tasks build
  • Test workflow: Build → Invoke-Pester -Path @('<test paths>') -Output Detailed
  • New session required after class changes

File Organization

  • Public commands: source/Public/{CommandName}.ps1
  • Private functions: source/Private/{FunctionName}.ps1
  • Unit tests: tests/Unit/{Classes|Public|Private}/{Name}.Tests.ps1
  • Integration tests: tests/Integration/Commands/{CommandName}.Integration.Tests.ps1

Requirements

  • Follow guidelines over existing code patterns
  • Always update CHANGELOG.md Unreleased section
  • Localize all strings using string keys; remove any orphaned string keys
  • Check DscResource.Common before creating private functions
  • Separate reusable logic into private functions
  • Add unit tests for all commands/functions/resources
  • Add integration tests for all public commands and resources

Files:

  • source/Classes/020.SqlAgentAlert.ps1
**/*.ps?(m|d)1

⚙️ CodeRabbit configuration file

**/*.ps?(m|d)1: # PowerShell Guidelines

Naming

  • Use descriptive names (3+ characters, no abbreviations)
  • Functions: PascalCase with Verb-Noun format using approved verbs
  • Parameters: PascalCase
  • Variables: camelCase
  • Keywords: lower-case
  • Classes: PascalCase
  • Include scope for script/global/environment variables: $script:, $global:, $env:

File naming

  • Class files: ###.ClassName.ps1 format (e.g. 001.SqlReason.ps1, 004.StartupParameters.ps1)

Formatting

Indentation & Spacing

  • Use 4 spaces (no tabs)
  • One space around operators: $a = 1 + 2
  • One space between type and variable: [String] $name
  • One space between keyword and parenthesis: if ($condition)
  • No spaces on empty lines
  • Try to limit lines to 120 characters

Braces

  • Newline before opening brace (except variable assignments)
  • One newline after opening brace
  • Two newlines after closing brace (one if followed by another brace or continuation)

Quotes

  • Use single quotes unless variable expansion is needed: 'text' vs "text $variable"

Arrays

  • Single line: @('one', 'two', 'three')
  • Multi-line: each element on separate line with proper indentation
  • Do not use the unary comma operator (,) in return statements to force
    an array

Hashtables

  • Empty: @{}
  • Multi-line: each property on separate line with proper indentation
  • Properties: Use PascalCase

Comments

  • Single line: # Comment (capitalized, on own line)
  • Multi-line: <# Comment #> format (opening and closing brackets on own line), and indent text
  • No commented-out code

Comment-based help

  • Always add comment-based help to all functions and scripts
  • Comment-based help: SYNOPSIS, DESCRIPTION (40+ chars), PARAMETER, EXAMPLE sections before function/class
  • Comment-based help indentation: keywords 4 spaces, text 8 spaces
  • Include examples for all parameter sets and combinations
  • INPUTS: List each pipeline‑accepted type (one per line) with a 1‑line description.
  • ...

Files:

  • source/Classes/020.SqlAgentAlert.ps1
🧠 Learnings (18)
📚 Learning: 2025-08-25T10:04:53.158Z
Learnt from: CR
PR: dsccommunity/SqlServerDsc#0
File: .github/instructions/SqlServerDsc-guidelines.instructions.md:0-0
Timestamp: 2025-08-25T10:04:53.158Z
Learning: Applies to **/DSCResources/**.{ps1,psm1} : Database Engine DSC resources must inherit the SqlResourceBase base class

Applied to files:

  • source/Classes/020.SqlAgentAlert.ps1
📚 Learning: 2025-08-25T10:05:30.603Z
Learnt from: CR
PR: dsccommunity/SqlServerDsc#0
File: .github/instructions/dsc-community-style-guidelines-class-resource.instructions.md:0-0
Timestamp: 2025-08-25T10:05:30.603Z
Learning: Applies to source/[cC]lasses/**/*.ps1 : Resource classes must inherit ResourceBase (from the DscResource.Base module)

Applied to files:

  • source/Classes/020.SqlAgentAlert.ps1
📚 Learning: 2025-08-25T10:04:53.158Z
Learnt from: CR
PR: dsccommunity/SqlServerDsc#0
File: .github/instructions/SqlServerDsc-guidelines.instructions.md:0-0
Timestamp: 2025-08-25T10:04:53.158Z
Learning: Applies to **/DSCResources/**.{ps1,psm1} : Resources inheriting SqlResourceBase should use its provided members: InstanceName, ServerName, Credential, Reasons, and GetServerObject()

Applied to files:

  • source/Classes/020.SqlAgentAlert.ps1
📚 Learning: 2025-08-25T10:05:30.603Z
Learnt from: CR
PR: dsccommunity/SqlServerDsc#0
File: .github/instructions/dsc-community-style-guidelines-class-resource.instructions.md:0-0
Timestamp: 2025-08-25T10:05:30.603Z
Learning: Applies to source/[cC]lasses/**/*.ps1 : Implement hidden [void] AssertProperties([System.Collections.Hashtable] $properties) to validate user-provided properties

Applied to files:

  • source/Classes/020.SqlAgentAlert.ps1
📚 Learning: 2025-08-25T10:05:30.603Z
Learnt from: CR
PR: dsccommunity/SqlServerDsc#0
File: .github/instructions/dsc-community-style-guidelines-class-resource.instructions.md:0-0
Timestamp: 2025-08-25T10:05:30.603Z
Learning: Applies to source/[cC]lasses/**/*.ps1 : Implement hidden [void] Modify([System.Collections.Hashtable] $properties) to set desired state only for non-compliant properties

Applied to files:

  • source/Classes/020.SqlAgentAlert.ps1
📚 Learning: 2025-08-25T10:09:27.870Z
Learnt from: CR
PR: dsccommunity/SqlServerDsc#0
File: .github/instructions/dsc-community-style-guidelines-unit-tests.instructions.md:0-0
Timestamp: 2025-08-25T10:09:27.870Z
Learning: Applies to tests/{Unit,uUnit}/**/*.[Tt]ests.ps1 : Test parameter properties explicitly; e.g., assert that a parameter is Mandatory using (Get-Command).Parameters['Name'].Attributes.Mandatory | Should -BeTrue

Applied to files:

  • source/Classes/020.SqlAgentAlert.ps1
📚 Learning: 2025-08-25T10:07:49.137Z
Learnt from: CR
PR: dsccommunity/SqlServerDsc#0
File: .github/instructions/dsc-community-style-guidelines-pester.instructions.md:0-0
Timestamp: 2025-08-25T10:07:49.137Z
Learning: Applies to **/*.[Tt]ests.ps1 : Use PascalCase for Pester keywords: Describe, Context, It, Should, BeforeAll, BeforeEach, AfterAll, AfterEach

Applied to files:

  • .github/instructions/dsc-community-style-guidelines-pester.instructions.md
📚 Learning: 2025-08-25T10:04:22.244Z
Learnt from: CR
PR: dsccommunity/SqlServerDsc#0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-08-25T10:04:22.244Z
Learning: Applies to **/*.{ps1,psm1,psd1} : Always follow PowerShell code style guidelines (./instructions/dsc-community-style-guidelines-powershell.instructions.md)

Applied to files:

  • .github/instructions/dsc-community-style-guidelines-pester.instructions.md
📚 Learning: 2025-08-25T10:07:49.137Z
Learnt from: CR
PR: dsccommunity/SqlServerDsc#0
File: .github/instructions/dsc-community-style-guidelines-pester.instructions.md:0-0
Timestamp: 2025-08-25T10:07:49.137Z
Learning: Applies to **/*.[Tt]ests.ps1 : Use Pester v5 syntax only

Applied to files:

  • .github/instructions/dsc-community-style-guidelines-pester.instructions.md
📚 Learning: 2025-08-25T10:07:49.137Z
Learnt from: CR
PR: dsccommunity/SqlServerDsc#0
File: .github/instructions/dsc-community-style-guidelines-pester.instructions.md:0-0
Timestamp: 2025-08-25T10:07:49.137Z
Learning: Applies to **/*.[Tt]ests.ps1 : Use exactly one Describe block per test file, named to match the tested entity

Applied to files:

  • .github/instructions/dsc-community-style-guidelines-pester.instructions.md
📚 Learning: 2025-08-25T10:09:05.899Z
Learnt from: CR
PR: dsccommunity/SqlServerDsc#0
File: .github/instructions/dsc-community-style-guidelines-powershell.instructions.md:0-0
Timestamp: 2025-08-25T10:09:05.899Z
Learning: Applies to **/*.{ps1,psm1} : .NOTES only when critical (constraints, side effects, security, version compatibility, breaking behavior), ≤2 short sentences

Applied to files:

  • .github/instructions/dsc-community-style-guidelines-pester.instructions.md
📚 Learning: 2025-08-25T10:07:49.137Z
Learnt from: CR
PR: dsccommunity/SqlServerDsc#0
File: .github/instructions/dsc-community-style-guidelines-pester.instructions.md:0-0
Timestamp: 2025-08-25T10:07:49.137Z
Learning: Applies to **/*.[Tt]ests.ps1 : Place all test code only inside Describe blocks

Applied to files:

  • .github/instructions/dsc-community-style-guidelines-pester.instructions.md
📚 Learning: 2025-08-25T10:07:49.137Z
Learnt from: CR
PR: dsccommunity/SqlServerDsc#0
File: .github/instructions/dsc-community-style-guidelines-pester.instructions.md:0-0
Timestamp: 2025-08-25T10:07:49.137Z
Learning: Applies to **/*.[Tt]ests.ps1 : Each scenario should be a separate Context block

Applied to files:

  • .github/instructions/dsc-community-style-guidelines-pester.instructions.md
📚 Learning: 2025-08-25T10:07:49.137Z
Learnt from: CR
PR: dsccommunity/SqlServerDsc#0
File: .github/instructions/dsc-community-style-guidelines-pester.instructions.md:0-0
Timestamp: 2025-08-25T10:07:49.137Z
Learning: Applies to **/*.[Tt]ests.ps1 : Use nested Context blocks for complex scenarios

Applied to files:

  • .github/instructions/dsc-community-style-guidelines-pester.instructions.md
📚 Learning: 2025-08-25T10:10:02.089Z
Learnt from: CR
PR: dsccommunity/SqlServerDsc#0
File: .github/instructions/dsc-community-style-guidelines.instructions.md:0-0
Timestamp: 2025-08-25T10:10:02.089Z
Learning: Applies to tests/Unit/{Classes,Public,Private}/*.Tests.ps1 : Place unit tests in tests/Unit/{Classes|Public|Private}/{Name}.Tests.ps1

Applied to files:

  • .github/instructions/dsc-community-style-guidelines-pester.instructions.md
📚 Learning: 2025-08-25T10:07:49.137Z
Learnt from: CR
PR: dsccommunity/SqlServerDsc#0
File: .github/instructions/dsc-community-style-guidelines-pester.instructions.md:0-0
Timestamp: 2025-08-25T10:07:49.137Z
Learning: Applies to tests/Unit/Public/*.Tests.ps1 : Place unit tests for public commands in tests/Unit/Public/{Name}.Tests.ps1

Applied to files:

  • .github/instructions/dsc-community-style-guidelines-pester.instructions.md
📚 Learning: 2025-08-25T10:07:49.137Z
Learnt from: CR
PR: dsccommunity/SqlServerDsc#0
File: .github/instructions/dsc-community-style-guidelines-pester.instructions.md:0-0
Timestamp: 2025-08-25T10:07:49.137Z
Learning: Applies to **/*.[Tt]ests.ps1 : Start It descriptions with 'Should'

Applied to files:

  • .github/instructions/dsc-community-style-guidelines-pester.instructions.md
📚 Learning: 2025-08-25T10:07:49.137Z
Learnt from: CR
PR: dsccommunity/SqlServerDsc#0
File: .github/instructions/dsc-community-style-guidelines-pester.instructions.md:0-0
Timestamp: 2025-08-25T10:07:49.137Z
Learning: Applies to tests/Unit/Classes/*.Tests.ps1 : Place unit tests for class resources in tests/Unit/Classes/{Name}.Tests.ps1

Applied to files:

  • .github/instructions/dsc-community-style-guidelines-pester.instructions.md
🧬 Code graph analysis (1)
source/Classes/020.SqlAgentAlert.ps1 (1)
tests/Unit/Stubs/SMO.cs (3)
  • Alert (1604-1646)
  • Microsoft (1499-1649)
  • AlertCollection (1561-1595)
🪛 LanguageTool
.github/instructions/dsc-community-style-guidelines-pester.instructions.md

[grammar] ~17-~17: There might be a mistake here.
Context: ...y parameters to avoid prompts ## Naming - One Describe block per file matching t...

(QB_NEW_EN)


[grammar] ~23-~23: There might be a mistake here.
Context: ...les prefix: 'mock' ## Structure & Scope - Public commands: Never use `InModuleScop...

(QB_NEW_EN)


[grammar] ~25-~25: There might be a mistake here.
Context: ...e functions/class resources: Always use InModuleScope - Each class method = separate Context b...

(QB_NEW_EN)


[grammar] ~29-~29: There might be a mistake here.
Context: ...reAll (BeforeEachonly when required) - Setup/teardown inBeforeAll,BeforeEac...

(QB_NEW_EN)


[grammar] ~30-~30: There might be a mistake here.
Context: ...only when required) - Setup/teardown in BeforeAll,BeforeEach/AfterAll,AfterEach clos...

(QB_NEW_EN)


[grammar] ~32-~32: There might be a mistake here.
Context: ...terEachclose to usage ## Syntax Rules - PascalCase:Describe, Context, It`,...

(QB_NEW_EN)


[grammar] ~33-~33: There might be a mistake here.
Context: ... BeforeAll, BeforeEach, AfterAll, AfterEach - Prefer -BeTrue/-BeFalse over `-Be $t...

(QB_NEW_EN)


[grammar] ~34-~34: There might be a mistake here.
Context: ...r -BeTrue/-BeFalse over -Be $true/-Be $false - Never use Assert-MockCalled, use `Shou...

(QB_NEW_EN)


[grammar] ~39-~39: There might be a mistake here.
Context: ...Mock:ModuleName, Should:ModuleName, InModuleScope:ModuleName - Omit -ModuleName parameter on Pester c...

(QB_NEW_EN)

🪛 markdownlint-cli2 (0.17.2)
.github/instructions/dsc-community-style-guidelines-pester.instructions.md

17-17: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below

(MD022, blanks-around-headings)


18-18: Lists should be surrounded by blank lines

(MD032, blanks-around-lists)


23-23: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below

(MD022, blanks-around-headings)


24-24: Lists should be surrounded by blank lines

(MD032, blanks-around-lists)


32-32: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below

(MD022, blanks-around-headings)


33-33: Line length
Expected: 80; Actual: 103

(MD013, line-length)


33-33: Lists should be surrounded by blank lines

(MD032, blanks-around-lists)

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
  • GitHub Check: dsccommunity.SqlServerDsc (Build Package Module)
  • GitHub Check: PSScriptAnalyzer
🔇 Additional comments (2)
source/Classes/020.SqlAgentAlert.ps1 (2)

115-117: Good: Correct DSC decoration and base class

[DscResource(RunAsCredential = 'Optional')] and inheritance from SqlResourceBase look correct.


170-181: Confirm DscResource.Common supports -AtLeastOneList

Ensure your RequiredModules pin a version that includes Assert-BoundParameter -AtLeastOneList; otherwise this will no-op or fail.

Please confirm the minimum DscResource.Common version that implements -AtLeastOneList is required by the module manifest (SqlServerDsc.psd1). If uncertain, I can draft a follow-up PR to bump and gate this.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

♻️ Duplicate comments (1)
source/Classes/020.SqlAgentAlert.ps1 (1)

299-311: Maintain invariant when switching between Severity and MessageId

When changing selector (Severity ↔ MessageId), clear the non-selected property to 0 to avoid ending up with both set.

-                if ($properties.ContainsKey('Severity') -and $alertObject.Severity -ne $properties.Severity)
-                {
-                    $setAlertParameters.Severity = $properties.Severity
-                    $needsUpdate = $true
-                }
-
-                if ($properties.ContainsKey('MessageId') -and $alertObject.MessageId -ne $properties.MessageId)
-                {
-                    $setAlertParameters.MessageId = $properties.MessageId
-                    $needsUpdate = $true
-                }
+                if ($properties.ContainsKey('Severity'))
+                {
+                    if ($alertObject.Severity -ne $properties.Severity)
+                    {
+                        $setAlertParameters.Severity = $properties.Severity
+                        $needsUpdate = $true
+                    }
+                    if ($alertObject.MessageId -ne 0)
+                    {
+                        $setAlertParameters.MessageId = 0
+                        $needsUpdate = $true
+                    }
+                }
+
+                if ($properties.ContainsKey('MessageId'))
+                {
+                    if ($alertObject.MessageId -ne $properties.MessageId)
+                    {
+                        $setAlertParameters.MessageId = $properties.MessageId
+                        $needsUpdate = $true
+                    }
+                    if ($alertObject.Severity -ne 0)
+                    {
+                        $setAlertParameters.Severity = 0
+                        $needsUpdate = $true
+                    }
+                }
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

💡 Knowledge Base configuration:

  • Jira integration is disabled
  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 809953f and cd6e952.

📒 Files selected for processing (1)
  • source/Classes/020.SqlAgentAlert.ps1 (1 hunks)
🧰 Additional context used
📓 Path-based instructions (7)
**/*.{ps1,psm1,psd1}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

Always follow PowerShell code style guidelines (./instructions/dsc-community-style-guidelines-powershell.instructions.md)

**/*.{ps1,psm1,psd1}: Use 4 spaces for indentation (no tabs)
One space around operators (e.g., $a = 1 + 2)
No spaces on empty lines
Try to limit lines to 120 characters
Use single quotes unless variable expansion is needed
Arrays single-line: @('one','two','three')
Arrays multi-line: each element on its own indented line
Hashtables empty literal uses @{}
Hashtables multi-line: each property on a separate indented line
Hashtable properties use PascalCase
Single-line comments use '# Comment' style: capitalized, on own line
Multi-line comments use <# #> with brackets on their own lines and indented text
End files with only one blank line
Use CR+LF line endings
Maximum of two consecutive newlines
Use UTF-8 encoding without BOM for all files

Files:

  • source/Classes/020.SqlAgentAlert.ps1
**/*.{ps1,psm1}

📄 CodeRabbit inference engine (.github/instructions/SqlServerDsc-guidelines.instructions.md)

**/*.{ps1,psm1}: Public PowerShell commands must follow the naming format: Verb-SqlDsc{Noun}
Prefer SMO over T-SQL for SQL Server interaction

**/*.{ps1,psm1}: Use descriptive names (3+ characters, no abbreviations)
Function names use PascalCase with Verb-Noun format using approved verbs
Parameter names use PascalCase
Variable names use camelCase
Keywords should be lower-case
Include scope qualifier for script/global/environment variables: $script:, $global:, $env:
One space between type and variable (e.g., [String] $name)
One space between keyword and parenthesis (e.g., if ($condition))
Newline before opening brace (except variable assignments)
One newline after opening brace
Two newlines after closing brace (one if followed by another brace or continuation)
Do not use the unary comma operator in return statements to force an array
Do not keep commented-out code
Always add comment-based help to all functions and scripts
Comment-based help must include SYNOPSIS, DESCRIPTION (40+ chars), PARAMETER, EXAMPLE sections before function/class
Comment-based help indentation: keywords at 4 spaces, text at 8 spaces
Include examples for all parameter sets and combinations in help
INPUTS: list each pipeline-accepted type (one per line) with a 1‑line description
OUTPUTS: list each return type (one per line) with a 1‑line description; must match [OutputType()] and actual returns
.NOTES only when critical (constraints, side effects, security, version compatibility, breaking behavior), ≤2 short sentences
Avoid aliases; use full command names
Avoid Write-Host; prefer Write-Verbose/Write-Information, etc.
Avoid Write-Output; use 'return' instead
Avoid ConvertTo-SecureString -AsPlainText in production code
Do not redefine reserved parameters (Verbose, Debug, etc.)
Include a Force parameter for functions that support ShouldContinue or use ShouldProcess
For state-changing functions, set SupportsShouldProcess
Use $PSCmdlet.ThrowTerminatingError() for terminating errors with relevant ...

Files:

  • source/Classes/020.SqlAgentAlert.ps1
source/[cC]lasses/*.ps1

📄 CodeRabbit inference engine (.github/instructions/dsc-community-style-guidelines-class-resource.instructions.md)

Place each DSC class-based resource in source/Classes/{ResourceName}.ps1

Files:

  • source/Classes/020.SqlAgentAlert.ps1
source/[cC]lasses/**/*.ps1

📄 CodeRabbit inference engine (.github/instructions/dsc-community-style-guidelines-class-resource.instructions.md)

source/[cC]lasses/**/*.ps1: Decorate the resource class with [DscResource(RunAsCredential = 'Optional')] (use 'Mandatory' if required)
Only classes with a [DscResource(...)] decoration are considered DSC resources to which these rules apply
Resource classes must inherit ResourceBase (from the DscResource.Base module)
Use $this.localizedData provided by ResourceBase (auto-populated from the localization file); do not manually populate it
Implement Get() that delegates to ([ResourceBase] $this).Get(), optionally post-processes, and returns the current state object
Implement Test() that delegates to ([ResourceBase] $this).Test(), optionally post-processes, and returns a [System.Boolean]
Implement Set() that delegates to ([ResourceBase] $this).Set(), with optional additional changes not handled by Modify()
Implement hidden [System.Collections.Hashtable] GetCurrentState([System.Collections.Hashtable] $properties) to return current state
Implement hidden [void] Modify([System.Collections.Hashtable] $properties) to set desired state only for non-compliant properties
Implement hidden [void] AssertProperties([System.Collections.Hashtable] $properties) to validate user-provided properties
Implement hidden [void] NormalizeProperties([System.Collections.Hashtable] $properties) to normalize user-provided properties

Files:

  • source/Classes/020.SqlAgentAlert.ps1

⚙️ CodeRabbit configuration file

source/[cC]lasses/**/*.ps1: # DSC Class-Based Resource Guidelines

Applies to: Classes with [DscResource(...)] decoration only.

Requirements

  • File: source/Classes/020.{ResourceName}.ps1
  • Decoration: [DscResource(RunAsCredential = 'Optional')] (replace with 'Mandatory' if required)
  • Inheritance: Must inherit ResourceBase (part of module DscResource.Base)
  • $this.localizedData hashtable auto-populated by ResourceBase from localization file

Required constructor

MyResourceName () : base ($PSScriptRoot)
{
    # Property names where state cannot be enforced, e.g Ensure
    $this.ExcludeDscProperties = @()
}

Required Method Pattern

[MyResourceName] Get()
{
    # Call base implementation to get current state
    $currentState = ([ResourceBase] $this).Get()

    # If needed, post-processing on current state that can not be handled by GetCurrentState()

    return $currentState
}

[System.Boolean] Test()
{
    # Call base implementation to test current state
    $inDesiredState = ([ResourceBase] $this).Test()

    # If needed, post-processing on test result that can not be handled by base Test()

    return $inDesiredState
}

[void] Set()
{
    # Call base implementation to set desired state
    ([ResourceBase] $this).Set()

    # If needed, additional state changes that can not be handled by Modify()
}

hidden [System.Collections.Hashtable] GetCurrentState([System.Collections.Hashtable] $properties)
{
    # Always return current state as hashtable, $properties contains key properties
}

hidden [void] Modify([System.Collections.Hashtable] $properties)
{
    # Always set desired state, $properties contain those that must change state
}

Optional Method Pattern

hidden [void] AssertProperties([System.Collections.Hashtable] $properties)
{
    # Validate user-provided properties, $properties contains user assigned values
}

hidden [void] NormalizeProperties([System.Collections.Hashtable] $pr...

Files:

  • source/Classes/020.SqlAgentAlert.ps1
source/**/*.ps1

📄 CodeRabbit inference engine (.github/instructions/dsc-community-style-guidelines-localization.instructions.md)

source/**/*.ps1: Localize all Write-Debug, Write-Verbose, Write-Error, Write-Warning, and $PSCmdlet.ThrowTerminatingError() messages
Do not hardcode user-facing strings; use localized string keys instead
Access localized strings via $script:localizedData, formatting with -f when needed

Localize all strings in source code using string keys

Files:

  • source/Classes/020.SqlAgentAlert.ps1

⚙️ CodeRabbit configuration file

source/**/*.ps1: # Localization Guidelines

Requirements

  • Localize all Write-Debug, Write-Verbose, Write-Error, Write-Warning and $PSCmdlet.ThrowTerminatingError() messages
  • Use localized string keys, not hardcoded strings
  • Assume $script:localizedData is available

String Files

  • Commands/functions: source/en-US/SqlServerDsc.strings.psd1
  • Class resources: source/en-US/{ResourceClassName}.strings.psd1

Key Naming Patterns

  • Format: Verb_FunctionName_Action (underscore separators), e.g. Get_SqlDscDatabase_ConnectingToDatabase

String Format

ConvertFrom-StringData @'
    KeyName = Message with {0} placeholder. (PREFIX0001)
'@

String IDs

  • Format: (PREFIX####)
  • PREFIX: First letter of each word in class or function name (SqlSetup → SS, Get-SqlDscDatabase → GSDD)
  • Number: Sequential from 0001

Usage

Write-Verbose -Message ($script:localizedData.KeyName -f $value1)

Files:

  • source/Classes/020.SqlAgentAlert.ps1
**

⚙️ CodeRabbit configuration file

**: # DSC Community Guidelines

Terminology

  • Command: Public command
  • Function: Private function
  • Resource: DSC class-based resource

Build & Test Workflow

  • Run project scripts in PowerShell from repository root
  • Build after source changes: .\build.ps1 -Tasks build
  • Test workflow: Build → Invoke-Pester -Path @('<test paths>') -Output Detailed
  • New session required after class changes

File Organization

  • Public commands: source/Public/{CommandName}.ps1
  • Private functions: source/Private/{FunctionName}.ps1
  • Unit tests: tests/Unit/{Classes|Public|Private}/{Name}.Tests.ps1
  • Integration tests: tests/Integration/Commands/{CommandName}.Integration.Tests.ps1

Requirements

  • Follow guidelines over existing code patterns
  • Always update CHANGELOG.md Unreleased section
  • Localize all strings using string keys; remove any orphaned string keys
  • Check DscResource.Common before creating private functions
  • Separate reusable logic into private functions
  • Add unit tests for all commands/functions/resources
  • Add integration tests for all public commands and resources

Files:

  • source/Classes/020.SqlAgentAlert.ps1
**/*.ps?(m|d)1

⚙️ CodeRabbit configuration file

**/*.ps?(m|d)1: # PowerShell Guidelines

Naming

  • Use descriptive names (3+ characters, no abbreviations)
  • Functions: PascalCase with Verb-Noun format using approved verbs
  • Parameters: PascalCase
  • Variables: camelCase
  • Keywords: lower-case
  • Classes: PascalCase
  • Include scope for script/global/environment variables: $script:, $global:, $env:

File naming

  • Class files: ###.ClassName.ps1 format (e.g. 001.SqlReason.ps1, 004.StartupParameters.ps1)

Formatting

Indentation & Spacing

  • Use 4 spaces (no tabs)
  • One space around operators: $a = 1 + 2
  • One space between type and variable: [String] $name
  • One space between keyword and parenthesis: if ($condition)
  • No spaces on empty lines
  • Try to limit lines to 120 characters

Braces

  • Newline before opening brace (except variable assignments)
  • One newline after opening brace
  • Two newlines after closing brace (one if followed by another brace or continuation)

Quotes

  • Use single quotes unless variable expansion is needed: 'text' vs "text $variable"

Arrays

  • Single line: @('one', 'two', 'three')
  • Multi-line: each element on separate line with proper indentation
  • Do not use the unary comma operator (,) in return statements to force
    an array

Hashtables

  • Empty: @{}
  • Multi-line: each property on separate line with proper indentation
  • Properties: Use PascalCase

Comments

  • Single line: # Comment (capitalized, on own line)
  • Multi-line: <# Comment #> format (opening and closing brackets on own line), and indent text
  • No commented-out code

Comment-based help

  • Always add comment-based help to all functions and scripts
  • Comment-based help: SYNOPSIS, DESCRIPTION (40+ chars), PARAMETER, EXAMPLE sections before function/class
  • Comment-based help indentation: keywords 4 spaces, text 8 spaces
  • Include examples for all parameter sets and combinations
  • INPUTS: List each pipeline‑accepted type (one per line) with a 1‑line description.
  • ...

Files:

  • source/Classes/020.SqlAgentAlert.ps1
🧠 Learnings (6)
📚 Learning: 2025-08-25T10:04:53.158Z
Learnt from: CR
PR: dsccommunity/SqlServerDsc#0
File: .github/instructions/SqlServerDsc-guidelines.instructions.md:0-0
Timestamp: 2025-08-25T10:04:53.158Z
Learning: Applies to **/DSCResources/**.{ps1,psm1} : Database Engine DSC resources must inherit the SqlResourceBase base class

Applied to files:

  • source/Classes/020.SqlAgentAlert.ps1
📚 Learning: 2025-08-25T10:05:30.603Z
Learnt from: CR
PR: dsccommunity/SqlServerDsc#0
File: .github/instructions/dsc-community-style-guidelines-class-resource.instructions.md:0-0
Timestamp: 2025-08-25T10:05:30.603Z
Learning: Applies to source/[cC]lasses/**/*.ps1 : Implement hidden [void] AssertProperties([System.Collections.Hashtable] $properties) to validate user-provided properties

Applied to files:

  • source/Classes/020.SqlAgentAlert.ps1
📚 Learning: 2025-08-28T15:42:41.164Z
Learnt from: johlju
PR: dsccommunity/SqlServerDsc#2150
File: source/Classes/020.SqlAgentAlert.ps1:0-0
Timestamp: 2025-08-28T15:42:41.164Z
Learning: Assert-BoundParameter now supports AtLeastOneList parameter (resolved in commit 809953f367ee903969a43e44a5b78e902ef46948) which can be used alongside MutuallyExclusiveList to enforce "exactly one required" validation in DSC resources.

Applied to files:

  • source/Classes/020.SqlAgentAlert.ps1
📚 Learning: 2025-08-28T15:42:41.165Z
Learnt from: johlju
PR: dsccommunity/SqlServerDsc#2150
File: source/Classes/020.SqlAgentAlert.ps1:0-0
Timestamp: 2025-08-28T15:42:41.165Z
Learning: Assert-BoundParameter supports AtLeastOneList parameter which can be used with IfEqualParameterList to enforce "exactly one required" validation conditionally (e.g., when Ensure = 'Present') in DSC resources. This is used alongside MutuallyExclusiveList for comprehensive parameter validation.

Applied to files:

  • source/Classes/020.SqlAgentAlert.ps1
📚 Learning: 2025-08-25T10:05:30.603Z
Learnt from: CR
PR: dsccommunity/SqlServerDsc#0
File: .github/instructions/dsc-community-style-guidelines-class-resource.instructions.md:0-0
Timestamp: 2025-08-25T10:05:30.603Z
Learning: Applies to source/[cC]lasses/**/*.ps1 : Implement hidden [void] Modify([System.Collections.Hashtable] $properties) to set desired state only for non-compliant properties

Applied to files:

  • source/Classes/020.SqlAgentAlert.ps1
📚 Learning: 2025-08-25T10:09:27.870Z
Learnt from: CR
PR: dsccommunity/SqlServerDsc#0
File: .github/instructions/dsc-community-style-guidelines-unit-tests.instructions.md:0-0
Timestamp: 2025-08-25T10:09:27.870Z
Learning: Applies to tests/{Unit,uUnit}/**/*.[Tt]ests.ps1 : Test parameter properties explicitly; e.g., assert that a parameter is Mandatory using (Get-Command).Parameters['Name'].Attributes.Mandatory | Should -BeTrue

Applied to files:

  • source/Classes/020.SqlAgentAlert.ps1
🧬 Code graph analysis (1)
source/Classes/020.SqlAgentAlert.ps1 (1)
tests/Unit/Stubs/SMO.cs (2)
  • Alert (1604-1646)
  • Microsoft (1499-1649)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
  • GitHub Check: dsccommunity.SqlServerDsc (Build Package Module)
  • GitHub Check: PSScriptAnalyzer
🔇 Additional comments (1)
source/Classes/020.SqlAgentAlert.ps1 (1)

173-197: Ensure AtLeastOne/MutuallyExclusive validations run when Ensure isn’t explicitly bound
BoundParameterList only contains explicitly passed parameters, so conditional checks gated on Ensure = 'Present' won’t fire when Ensure defaults. Clone the $properties hashtable, set Ensure = $this.Ensure if missing, and pass that augmented table to both Assert-BoundParameter calls.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

♻️ Duplicate comments (3)
.github/instructions/SqlServerDsc-guidelines.instructions.md (1)

14-15: Don’t instruct always excluding base-provided properties; clarify ExcludeDscProperties usage and wrap lines.

Exclude only if a derived resource intentionally redeclares those names; otherwise omitting them avoids redundant guidance and schema confusion. Also fix MD013 line length.

-  - Add `InstanceName`, `ServerName`, and `Credential` to `$this.ExcludeDscProperties`
-  - `SqlResourceBase` provides: `InstanceName`, `ServerName`, `Credential`, `Reasons`, `GetServerObject()`
+  - Inherit `SqlResourceBase`. Do not redeclare `InstanceName`, `ServerName`,
+    or `Credential` as DSC properties; they are provided by the base class.
+    Only if a derived resource must introduce homonymous properties, add those
+    names to `$this.ExcludeDscProperties` to avoid schema duplication.
+  - `SqlResourceBase` provides: `InstanceName`, `ServerName`, `Credential`,
+    `Reasons`, and `GetServerObject()`.
.github/instructions/dsc-community-style-guidelines-class-resource.instructions.md (2)

15-15: Relax blanket “use Nullable” rule; recommend only where appropriate.

Avoid forcing nullable for required properties; keep it contextual.

-- value-type properties: Use `[Nullable[{FullTypeName}]]` (e.g., `[Nullable[System.Int32]]`)
+- Use nullable types for optional value-type properties when appropriate,
+  for example `[Nullable[System.Int32]]` or `[int?]`. Do not make required
+  properties nullable.

89-97: *Error handling guidance is contradictory; instruct to throw localized New-Exception objects and add example.

Align with module practices and fix MD022/MD032 formatting.

-## Error Handling
-- Use `try/catch` blocks to handle exceptions
-- Do not use `throw` for terminating errors, use `New-*Exception` commands:
+## Error handling
+
+- Use `try/catch` blocks to handle exceptions.
+- For terminating errors, throw a localized exception created with the
+  appropriate `New-*Exception` helper from DscResource.Common:
   - [`New‑InvalidDataException`](https://github.com/dsccommunity/DscResource.Common/wiki/New%E2%80%91InvalidDataException)
   - [`New-ArgumentException`](https://github.com/dsccommunity/DscResource.Common/wiki/New%E2%80%91ArgumentException)
   - [`New-InvalidOperationException`](https://github.com/dsccommunity/DscResource.Common/wiki/New%E2%80%91InvalidOperationException)
   - [`New-ObjectNotFoundException`](https://github.com/dsccommunity/DscResource.Common/wiki/New%E2%80%91ObjectNotFoundException)
   - [`New-InvalidResultException`](https://github.com/dsccommunity/DscResource.Common/wiki/New%E2%80%91InvalidResultException)
   - [`New-NotImplementedException`](https://github.com/dsccommunity/DscResource.Common/wiki/New%E2%80%91NotImplementedException)
+
+Example:
+
+```powershell
+catch
+{
+    $msg = $this.localizedData.MyResource_Action_Failed -f $this.Name, $_.Exception.Message
+    throw (New-InvalidOperationException -Message $msg -ErrorRecord $_)
+}
+```
🧹 Nitpick comments (3)
.github/instructions/SqlServerDsc-guidelines.instructions.md (1)

39-42: Fix markdown formatting (MD032/MD013) and minor grammar.

Add blank lines around the list and wrap long lines; tweak phrasing.

-## Unit tests
-- When unit test tests classes or commands that contain SMO types, e.g. `[Microsoft.SqlServer.Management.Smo.*]`
-  - Ensure they are properly stubbed in SMO.cs
-  - Load SMO stub types from SMO.cs in unit test files, e.g. `Add-Type -Path "$PSScriptRoot/../Stubs/SMO.cs"`
-  - After changing SMO stub types, run tests in a new PowerShell session for changes to take effect.
+## Unit tests
+
+- When a unit test targets classes or commands that contain SMO types
+  (for example, `[Microsoft.SqlServer.Management.Smo.*]`):
+  - Ensure they are properly stubbed in `SMO.cs`.
+  - Load SMO stub types in test files, for example:
+    `Add-Type -Path "$PSScriptRoot/../Stubs/SMO.cs"`.
+  - After changing SMO stub types, run tests in a new PowerShell session
+    for the changes to take effect.
+
.github/instructions/dsc-community-style-guidelines-class-resource.instructions.md (2)

20-24: Constructor snippet: clarify ExcludeDscProperties usage and SqlServerDsc override.

Comment implies adding names but the array is empty; also note that SqlServerDsc resources inheriting SqlResourceBase should call base() without $PSScriptRoot.

-MyResourceName () : base ($PSScriptRoot)
+MyResourceName () : base ($PSScriptRoot)
 {
-    # Property names where state cannot be enforced, e.g. IsSingleInstance, Force
-    $this.ExcludeDscProperties = @()
+    # If applicable, list property names where state cannot be enforced,
+    # e.g. 'IsSingleInstance' or 'Force'. Otherwise leave empty.
+    $this.ExcludeDscProperties = @()
 }
+
+# Note: For SqlServerDsc resources inheriting SqlResourceBase, use:
+# MyResourceName() : base () { }

Would you like me to update the general guidance to auto-detect base class and show both constructor variants?


82-88: Fix list formatting and line length in “Required comment-based help”.

Surround lists with blank lines and wrap long lines.

-## Required comment-based help
-
-Add to .DESCRIPTION section:
-- `## Requirements`: List minimum requirements
-- `## Known issues`: Critical issues + pattern: `All issues are not listed here, see [all open issues](https://github.com/{owner}/{repo}/issues?q=is%3Aissue+is%3Aopen+in%3Atitle+{ResourceName}).`
+## Required comment-based help
+
+Add to the .DESCRIPTION section:
+
+- `## Requirements`: list minimum requirements.
+- `## Known issues`: critical issues and the note:
+  “All issues are not listed here; see all open issues
+  (https://github.com/{owner}/{repo}/issues?q=is%3Aissue+is%3Aopen+in%3Atitle+{ResourceName}).”
+
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

💡 Knowledge Base configuration:

  • Jira integration is disabled
  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between cd6e952 and 51175ed.

📒 Files selected for processing (3)
  • .github/instructions/SqlServerDsc-guidelines.instructions.md (2 hunks)
  • .github/instructions/dsc-community-style-guidelines-class-resource.instructions.md (2 hunks)
  • source/Classes/020.SqlAgentAlert.ps1 (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • source/Classes/020.SqlAgentAlert.ps1
🧰 Additional context used
🧠 Learnings (31)
📓 Common learnings
Learnt from: CR
PR: dsccommunity/SqlServerDsc#0
File: .github/instructions/SqlServerDsc-guidelines.instructions.md:0-0
Timestamp: 2025-08-25T10:04:53.158Z
Learning: Applies to **/DSCResources/**.{ps1,psm1} : Database Engine DSC resources must inherit the SqlResourceBase base class
📚 Learning: 2025-08-25T10:04:22.244Z
Learnt from: CR
PR: dsccommunity/SqlServerDsc#0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-08-25T10:04:22.244Z
Learning: Follow SqlServerDsc project specific guidelines (./instructions/SqlServerDsc-guidelines.instructions.md)

Applied to files:

  • .github/instructions/SqlServerDsc-guidelines.instructions.md
📚 Learning: 2025-08-25T10:04:22.244Z
Learnt from: CR
PR: dsccommunity/SqlServerDsc#0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-08-25T10:04:22.244Z
Learning: SqlServerDsc-specific guidelines override general project guidelines

Applied to files:

  • .github/instructions/SqlServerDsc-guidelines.instructions.md
📚 Learning: 2025-08-25T10:04:53.158Z
Learnt from: CR
PR: dsccommunity/SqlServerDsc#0
File: .github/instructions/SqlServerDsc-guidelines.instructions.md:0-0
Timestamp: 2025-08-25T10:04:53.158Z
Learning: Applies to **/DSCResources/**.{ps1,psm1} : Database Engine DSC resources must inherit the SqlResourceBase base class

Applied to files:

  • .github/instructions/SqlServerDsc-guidelines.instructions.md
  • .github/instructions/dsc-community-style-guidelines-class-resource.instructions.md
📚 Learning: 2025-08-28T17:12:44.212Z
Learnt from: johlju
PR: dsccommunity/SqlServerDsc#2150
File: source/Classes/020.SqlAgentAlert.ps1:141-150
Timestamp: 2025-08-28T17:12:44.212Z
Learning: For SqlServerDsc resources that inherit SqlResourceBase, the constructor pattern should be `MyResourceName() : base () { }` without the $PSScriptRoot parameter, as specified in the SqlServerDsc-specific guidelines which override the general DSC community guidelines.

Applied to files:

  • .github/instructions/SqlServerDsc-guidelines.instructions.md
  • .github/instructions/dsc-community-style-guidelines-class-resource.instructions.md
📚 Learning: 2025-08-17T10:13:30.079Z
Learnt from: johlju
PR: dsccommunity/SqlServerDsc#2136
File: source/Public/Remove-SqlDscLogin.ps1:104-108
Timestamp: 2025-08-17T10:13:30.079Z
Learning: In SqlServerDsc unit tests, SMO object stubs (like Login objects) should have properly mocked Parent properties with correct Server stub types and valid InstanceName values, rather than handling null Parent scenarios in production code.

Applied to files:

  • .github/instructions/SqlServerDsc-guidelines.instructions.md
📚 Learning: 2025-08-25T10:04:53.158Z
Learnt from: CR
PR: dsccommunity/SqlServerDsc#0
File: .github/instructions/SqlServerDsc-guidelines.instructions.md:0-0
Timestamp: 2025-08-25T10:04:53.158Z
Learning: Applies to **/*.{ps1,psm1} : Prefer SMO over T-SQL for SQL Server interaction

Applied to files:

  • .github/instructions/SqlServerDsc-guidelines.instructions.md
📚 Learning: 2025-08-25T10:05:30.603Z
Learnt from: CR
PR: dsccommunity/SqlServerDsc#0
File: .github/instructions/dsc-community-style-guidelines-class-resource.instructions.md:0-0
Timestamp: 2025-08-25T10:05:30.603Z
Learning: Applies to source/[cC]lasses/**/*.ps1 : Resource classes must inherit ResourceBase (from the DscResource.Base module)

Applied to files:

  • .github/instructions/SqlServerDsc-guidelines.instructions.md
  • .github/instructions/dsc-community-style-guidelines-class-resource.instructions.md
📚 Learning: 2025-08-25T10:04:53.158Z
Learnt from: CR
PR: dsccommunity/SqlServerDsc#0
File: .github/instructions/SqlServerDsc-guidelines.instructions.md:0-0
Timestamp: 2025-08-25T10:04:53.158Z
Learning: Applies to tests/Unit/**/*.Tests.ps1 : In unit tests, use SMO stub types defined in SMO.cs

Applied to files:

  • .github/instructions/SqlServerDsc-guidelines.instructions.md
📚 Learning: 2025-08-25T10:04:53.158Z
Learnt from: CR
PR: dsccommunity/SqlServerDsc#0
File: .github/instructions/SqlServerDsc-guidelines.instructions.md:0-0
Timestamp: 2025-08-25T10:04:53.158Z
Learning: Applies to tests/Unit/**/*.Tests.ps1 : In unit tests, do not mock SMO types directly

Applied to files:

  • .github/instructions/SqlServerDsc-guidelines.instructions.md
📚 Learning: 2025-08-25T10:04:53.158Z
Learnt from: CR
PR: dsccommunity/SqlServerDsc#0
File: .github/instructions/SqlServerDsc-guidelines.instructions.md:0-0
Timestamp: 2025-08-25T10:04:53.158Z
Learning: After changing SMO.cs, run tests in a new PowerShell session

Applied to files:

  • .github/instructions/SqlServerDsc-guidelines.instructions.md
📚 Learning: 2025-08-25T10:04:53.158Z
Learnt from: CR
PR: dsccommunity/SqlServerDsc#0
File: .github/instructions/SqlServerDsc-guidelines.instructions.md:0-0
Timestamp: 2025-08-25T10:04:53.158Z
Learning: Applies to azure-pipelines.yml : Choose the appropriate integration test group number in azure-pipelines.yml based on required dependencies

Applied to files:

  • .github/instructions/SqlServerDsc-guidelines.instructions.md
📚 Learning: 2025-08-25T10:07:49.137Z
Learnt from: CR
PR: dsccommunity/SqlServerDsc#0
File: .github/instructions/dsc-community-style-guidelines-pester.instructions.md:0-0
Timestamp: 2025-08-25T10:07:49.137Z
Learning: Applies to **/*.[Tt]ests.ps1 : Define mocks in BeforeAll (use BeforeEach for mocking only when required)

Applied to files:

  • .github/instructions/SqlServerDsc-guidelines.instructions.md
📚 Learning: 2025-08-25T10:09:27.870Z
Learnt from: CR
PR: dsccommunity/SqlServerDsc#0
File: .github/instructions/dsc-community-style-guidelines-unit-tests.instructions.md:0-0
Timestamp: 2025-08-25T10:09:27.870Z
Learning: After modifying classes, always run tests in a new PowerShell session to pick up changes

Applied to files:

  • .github/instructions/SqlServerDsc-guidelines.instructions.md
📚 Learning: 2025-08-25T10:05:48.627Z
Learnt from: CR
PR: dsccommunity/SqlServerDsc#0
File: .github/instructions/dsc-community-style-guidelines-integration-tests.instructions.md:0-0
Timestamp: 2025-08-25T10:05:48.627Z
Learning: Applies to tests/[iI]ntegration/**/*.[iI]ntegration.[tT]ests.ps1 : Do not use mocking in integration tests; execute against a real environment

Applied to files:

  • .github/instructions/SqlServerDsc-guidelines.instructions.md
📚 Learning: 2025-08-25T10:04:53.158Z
Learnt from: CR
PR: dsccommunity/SqlServerDsc#0
File: .github/instructions/SqlServerDsc-guidelines.instructions.md:0-0
Timestamp: 2025-08-25T10:04:53.158Z
Learning: Applies to tests/Unit/**/*.Tests.ps1 : Unit tests must set $env:SqlServerDscCI = $true in BeforeAll and remove it in AfterAll

Applied to files:

  • .github/instructions/SqlServerDsc-guidelines.instructions.md
📚 Learning: 2025-08-25T10:07:49.137Z
Learnt from: CR
PR: dsccommunity/SqlServerDsc#0
File: .github/instructions/dsc-community-style-guidelines-pester.instructions.md:0-0
Timestamp: 2025-08-25T10:07:49.137Z
Learning: Applies to **/*.[Tt]ests.ps1 : Keep variable and mock scope as close as possible to the usage context

Applied to files:

  • .github/instructions/SqlServerDsc-guidelines.instructions.md
📚 Learning: 2025-08-25T10:04:22.244Z
Learnt from: CR
PR: dsccommunity/SqlServerDsc#0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-08-25T10:04:22.244Z
Learning: Follow class-based resources guidelines (./instructions/dsc-community-style-guidelines-class-resource.instructions.md)

Applied to files:

  • .github/instructions/dsc-community-style-guidelines-class-resource.instructions.md
📚 Learning: 2025-08-25T10:09:05.899Z
Learnt from: CR
PR: dsccommunity/SqlServerDsc#0
File: .github/instructions/dsc-community-style-guidelines-powershell.instructions.md:0-0
Timestamp: 2025-08-25T10:09:05.899Z
Learning: Applies to **/*.{ps1,psm1} : .NOTES only when critical (constraints, side effects, security, version compatibility, breaking behavior), ≤2 short sentences

Applied to files:

  • .github/instructions/dsc-community-style-guidelines-class-resource.instructions.md
📚 Learning: 2025-08-25T10:07:22.349Z
Learnt from: CR
PR: dsccommunity/SqlServerDsc#0
File: .github/instructions/dsc-community-style-guidelines-mof-resources.instructions.md:0-0
Timestamp: 2025-08-25T10:07:22.349Z
Learning: Applies to source/DSCResources/**/*.psm1 : When raising terminating errors, throw localized exceptions created via the appropriate DscResource.Common New-*Exception cmdlets (e.g., New-InvalidDataException, New-ArgumentException, New-InvalidOperationException, New-ObjectNotFoundException, New-InvalidResultException, New-NotImplementedException)

Applied to files:

  • .github/instructions/dsc-community-style-guidelines-class-resource.instructions.md
📚 Learning: 2025-08-25T10:07:22.349Z
Learnt from: CR
PR: dsccommunity/SqlServerDsc#0
File: .github/instructions/dsc-community-style-guidelines-mof-resources.instructions.md:0-0
Timestamp: 2025-08-25T10:07:22.349Z
Learning: Applies to source/DSCResources/**/*.psm1 : Do not use throw for terminating errors; handle errors via try/catch

Applied to files:

  • .github/instructions/dsc-community-style-guidelines-class-resource.instructions.md
📚 Learning: 2025-08-17T10:48:15.384Z
Learnt from: johlju
PR: dsccommunity/SqlServerDsc#2136
File: source/suffix.ps1:24-24
Timestamp: 2025-08-17T10:48:15.384Z
Learning: In source/suffix.ps1, the Write-Verbose message in the catch block for Import-SqlDscPreferredModule does not need localization because the exception message from Import-SqlDscPreferredModule is already localized by that command, making it an edge case exception to the localization guidelines.

Applied to files:

  • .github/instructions/dsc-community-style-guidelines-class-resource.instructions.md
📚 Learning: 2025-08-25T10:05:30.603Z
Learnt from: CR
PR: dsccommunity/SqlServerDsc#0
File: .github/instructions/dsc-community-style-guidelines-class-resource.instructions.md:0-0
Timestamp: 2025-08-25T10:05:30.603Z
Learning: Applies to source/[cC]lasses/**/*.ps1 : Decorate the resource class with [DscResource(RunAsCredential = 'Optional')] (use 'Mandatory' if required)

Applied to files:

  • .github/instructions/dsc-community-style-guidelines-class-resource.instructions.md
📚 Learning: 2025-08-25T10:05:30.603Z
Learnt from: CR
PR: dsccommunity/SqlServerDsc#0
File: .github/instructions/dsc-community-style-guidelines-class-resource.instructions.md:0-0
Timestamp: 2025-08-25T10:05:30.603Z
Learning: Applies to source/[cC]lasses/**/*.ps1 : Use $this.localizedData provided by ResourceBase (auto-populated from the localization file); do not manually populate it

Applied to files:

  • .github/instructions/dsc-community-style-guidelines-class-resource.instructions.md
📚 Learning: 2025-08-28T17:10:34.743Z
Learnt from: johlju
PR: dsccommunity/SqlServerDsc#2150
File: source/Classes/020.SqlAgentAlert.ps1:198-217
Timestamp: 2025-08-28T17:10:34.743Z
Learning: DSC properties with default values (e.g., `$Ensure = 'Present'`) are always present in the properties hashtable passed to validation methods, even when not explicitly specified by the user.

Applied to files:

  • .github/instructions/dsc-community-style-guidelines-class-resource.instructions.md
📚 Learning: 2025-08-25T10:04:22.244Z
Learnt from: CR
PR: dsccommunity/SqlServerDsc#0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-08-25T10:04:22.244Z
Learning: New DSC resources should always be created as class-based resources

Applied to files:

  • .github/instructions/dsc-community-style-guidelines-class-resource.instructions.md
📚 Learning: 2025-08-25T10:07:22.349Z
Learnt from: CR
PR: dsccommunity/SqlServerDsc#0
File: .github/instructions/dsc-community-style-guidelines-mof-resources.instructions.md:0-0
Timestamp: 2025-08-25T10:07:22.349Z
Learning: Applies to source/DSCResources/**/*.psm1 : Each MOF-based DSC resource module must define the functions Get-TargetResource, Set-TargetResource, and Test-TargetResource

Applied to files:

  • .github/instructions/dsc-community-style-guidelines-class-resource.instructions.md
📚 Learning: 2025-08-25T10:05:30.603Z
Learnt from: CR
PR: dsccommunity/SqlServerDsc#0
File: .github/instructions/dsc-community-style-guidelines-class-resource.instructions.md:0-0
Timestamp: 2025-08-25T10:05:30.603Z
Learning: Applies to source/[cC]lasses/**/*.ps1 : Only classes with a [DscResource(...)] decoration are considered DSC resources to which these rules apply

Applied to files:

  • .github/instructions/dsc-community-style-guidelines-class-resource.instructions.md
📚 Learning: 2025-08-25T10:05:30.603Z
Learnt from: CR
PR: dsccommunity/SqlServerDsc#0
File: .github/instructions/dsc-community-style-guidelines-class-resource.instructions.md:0-0
Timestamp: 2025-08-25T10:05:30.603Z
Learning: Applies to source/[cC]lasses/**/*.ps1 : Implement hidden [void] NormalizeProperties([System.Collections.Hashtable] $properties) to normalize user-provided properties

Applied to files:

  • .github/instructions/dsc-community-style-guidelines-class-resource.instructions.md
📚 Learning: 2025-08-25T10:09:05.899Z
Learnt from: CR
PR: dsccommunity/SqlServerDsc#0
File: .github/instructions/dsc-community-style-guidelines-powershell.instructions.md:0-0
Timestamp: 2025-08-25T10:09:05.899Z
Learning: Applies to **/*.{ps1,psm1} : Comment-based help must include SYNOPSIS, DESCRIPTION (40+ chars), PARAMETER, EXAMPLE sections before function/class

Applied to files:

  • .github/instructions/dsc-community-style-guidelines-class-resource.instructions.md
📚 Learning: 2025-08-25T10:05:30.603Z
Learnt from: CR
PR: dsccommunity/SqlServerDsc#0
File: .github/instructions/dsc-community-style-guidelines-class-resource.instructions.md:0-0
Timestamp: 2025-08-25T10:05:30.603Z
Learning: Applies to source/[cC]lasses/**/*.ps1 : Implement hidden [void] Modify([System.Collections.Hashtable] $properties) to set desired state only for non-compliant properties

Applied to files:

  • .github/instructions/dsc-community-style-guidelines-class-resource.instructions.md
🧬 Code graph analysis (1)
.github/instructions/SqlServerDsc-guidelines.instructions.md (1)
tests/Unit/Stubs/SMO.cs (9)
  • Microsoft (12-1048)
  • Microsoft (1086-1497)
  • Server (278-373)
  • Database (558-617)
  • Service (1149-1181)
  • Login (379-532)
  • SmoException (664-671)
  • ManagedComputer (1475-1494)
  • SqlServerManagementException (651-658)
🪛 markdownlint-cli2 (0.17.2)
.github/instructions/SqlServerDsc-guidelines.instructions.md

15-15: Line length
Expected: 80; Actual: 106

(MD013, line-length)


39-39: Lists should be surrounded by blank lines

(MD032, blanks-around-lists)


42-42: Line length
Expected: 80; Actual: 100

(MD013, line-length)

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

86-86: Lists should be surrounded by blank lines

(MD032, blanks-around-lists)


87-87: Line length
Expected: 80; Actual: 195

(MD013, line-length)


89-89: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below

(MD022, blanks-around-headings)


90-90: Lists should be surrounded by blank lines

(MD032, blanks-around-lists)

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

[grammar] ~42-~42: There might be a mistake here.
Context: ...hell session for changes to take effect.

(QB_NEW_EN)

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

[grammar] ~85-~85: There might be a mistake here.
Context: ...based help Add to .DESCRIPTION section: - ## Requirements: List minimum requirements - `## Known ...

(QB_NEW_EN)


[grammar] ~86-~86: There might be a mistake here.
Context: ...Requirements: List minimum requirements - ## Known issues: Critical issues + pattern: All issues...

(QB_NEW_EN)


[grammar] ~89-~89: There might be a mistake here.
Context: ...tle+{ResourceName}). ## Error Handling - Usetry/catch` blocks to handle excepti...

(QB_NEW_EN)

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
  • GitHub Check: dsccommunity.SqlServerDsc (Build Package Module)
  • GitHub Check: PSScriptAnalyzer
🔇 Additional comments (1)
.github/instructions/SqlServerDsc-guidelines.instructions.md (1)

16-16: Constructor guidance LGTM (no $PSScriptRoot).

This matches the SqlServerDsc-specific pattern for SqlResourceBase-derived resources.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

♻️ Duplicate comments (1)
source/Classes/020.SqlAgentAlert.ps1 (1)

288-301: When switching selector, clear the other selector (prevent both being set)

Ensure only one of Severity/MessageId remains on updates.

-                if ($properties.ContainsKey('Severity') -and $alertObject.Severity -ne $properties.Severity)
-                {
-                    $setAlertParameters.Severity = $properties.Severity
-                    $needsUpdate = $true
-                }
-
-                if ($properties.ContainsKey('MessageId') -and $alertObject.MessageId -ne $properties.MessageId)
-                {
-                    $setAlertParameters.MessageId = $properties.MessageId
-                    $needsUpdate = $true
-                }
+                # If Severity is desired, set it and clear MessageId
+                if ($properties.ContainsKey('Severity'))
+                {
+                    if ($alertObject.Severity -ne $properties.Severity)
+                    {
+                        $setAlertParameters.Severity = $properties.Severity
+                        $needsUpdate = $true
+                    }
+                    if ($alertObject.MessageId -ne 0)
+                    {
+                        $setAlertParameters.MessageId = 0
+                        $needsUpdate = $true
+                    }
+                }
+
+                # If MessageId is desired, set it and clear Severity
+                if ($properties.ContainsKey('MessageId'))
+                {
+                    if ($alertObject.MessageId -ne $properties.MessageId)
+                    {
+                        $setAlertParameters.MessageId = $properties.MessageId
+                        $needsUpdate = $true
+                    }
+                    if ($alertObject.Severity -ne 0)
+                    {
+                        $setAlertParameters.Severity = 0
+                        $needsUpdate = $true
+                    }
+                }
🧹 Nitpick comments (2)
source/Classes/020.SqlAgentAlert.ps1 (2)

143-149: Don’t overwrite base excludes; add Ensure to excludes

Avoid clobbering base defaults and ensure Ensure isn’t enforced.

-        $this.ExcludeDscProperties = @(
-            'InstanceName',
-            'ServerName',
-            'Credential'
-            'Name'
-        )
+        $this.ExcludeDscProperties += @(
+            'InstanceName'
+            'ServerName'
+            'Credential'
+            'Name'
+            'Ensure'
+        )

122-124: Validate key Name is not null/empty

Add standard guard on Key property.

     [DscProperty(Key)]
+    [ValidateNotNullOrEmpty()]
     [System.String]
     $Name
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

💡 Knowledge Base configuration:

  • Jira integration is disabled
  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 51175ed and 3354094.

📒 Files selected for processing (2)
  • source/Classes/020.SqlAgentAlert.ps1 (1 hunks)
  • source/en-US/SqlAgentAlert.strings.psd1 (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • source/en-US/SqlAgentAlert.strings.psd1
🧰 Additional context used
📓 Path-based instructions (7)
**/*.{ps1,psm1,psd1}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

Always follow PowerShell code style guidelines (./instructions/dsc-community-style-guidelines-powershell.instructions.md)

**/*.{ps1,psm1,psd1}: Use 4 spaces for indentation (no tabs)
One space around operators (e.g., $a = 1 + 2)
No spaces on empty lines
Try to limit lines to 120 characters
Use single quotes unless variable expansion is needed
Arrays single-line: @('one','two','three')
Arrays multi-line: each element on its own indented line
Hashtables empty literal uses @{}
Hashtables multi-line: each property on a separate indented line
Hashtable properties use PascalCase
Single-line comments use '# Comment' style: capitalized, on own line
Multi-line comments use <# #> with brackets on their own lines and indented text
End files with only one blank line
Use CR+LF line endings
Maximum of two consecutive newlines
Use UTF-8 encoding without BOM for all files

Files:

  • source/Classes/020.SqlAgentAlert.ps1
**/*.{ps1,psm1}

📄 CodeRabbit inference engine (.github/instructions/SqlServerDsc-guidelines.instructions.md)

**/*.{ps1,psm1}: Public PowerShell commands must follow the naming format: Verb-SqlDsc{Noun}
Prefer SMO over T-SQL for SQL Server interaction

**/*.{ps1,psm1}: Use descriptive names (3+ characters, no abbreviations)
Function names use PascalCase with Verb-Noun format using approved verbs
Parameter names use PascalCase
Variable names use camelCase
Keywords should be lower-case
Include scope qualifier for script/global/environment variables: $script:, $global:, $env:
One space between type and variable (e.g., [String] $name)
One space between keyword and parenthesis (e.g., if ($condition))
Newline before opening brace (except variable assignments)
One newline after opening brace
Two newlines after closing brace (one if followed by another brace or continuation)
Do not use the unary comma operator in return statements to force an array
Do not keep commented-out code
Always add comment-based help to all functions and scripts
Comment-based help must include SYNOPSIS, DESCRIPTION (40+ chars), PARAMETER, EXAMPLE sections before function/class
Comment-based help indentation: keywords at 4 spaces, text at 8 spaces
Include examples for all parameter sets and combinations in help
INPUTS: list each pipeline-accepted type (one per line) with a 1‑line description
OUTPUTS: list each return type (one per line) with a 1‑line description; must match [OutputType()] and actual returns
.NOTES only when critical (constraints, side effects, security, version compatibility, breaking behavior), ≤2 short sentences
Avoid aliases; use full command names
Avoid Write-Host; prefer Write-Verbose/Write-Information, etc.
Avoid Write-Output; use 'return' instead
Avoid ConvertTo-SecureString -AsPlainText in production code
Do not redefine reserved parameters (Verbose, Debug, etc.)
Include a Force parameter for functions that support ShouldContinue or use ShouldProcess
For state-changing functions, set SupportsShouldProcess
Use $PSCmdlet.ThrowTerminatingError() for terminating errors with relevant ...

Files:

  • source/Classes/020.SqlAgentAlert.ps1
source/[cC]lasses/*.ps1

📄 CodeRabbit inference engine (.github/instructions/dsc-community-style-guidelines-class-resource.instructions.md)

Place each DSC class-based resource in source/Classes/{ResourceName}.ps1

Files:

  • source/Classes/020.SqlAgentAlert.ps1
source/[cC]lasses/**/*.ps1

📄 CodeRabbit inference engine (.github/instructions/dsc-community-style-guidelines-class-resource.instructions.md)

source/[cC]lasses/**/*.ps1: Decorate the resource class with [DscResource(RunAsCredential = 'Optional')] (use 'Mandatory' if required)
Only classes with a [DscResource(...)] decoration are considered DSC resources to which these rules apply
Resource classes must inherit ResourceBase (from the DscResource.Base module)
Use $this.localizedData provided by ResourceBase (auto-populated from the localization file); do not manually populate it
Implement Get() that delegates to ([ResourceBase] $this).Get(), optionally post-processes, and returns the current state object
Implement Test() that delegates to ([ResourceBase] $this).Test(), optionally post-processes, and returns a [System.Boolean]
Implement Set() that delegates to ([ResourceBase] $this).Set(), with optional additional changes not handled by Modify()
Implement hidden [System.Collections.Hashtable] GetCurrentState([System.Collections.Hashtable] $properties) to return current state
Implement hidden [void] Modify([System.Collections.Hashtable] $properties) to set desired state only for non-compliant properties
Implement hidden [void] AssertProperties([System.Collections.Hashtable] $properties) to validate user-provided properties
Implement hidden [void] NormalizeProperties([System.Collections.Hashtable] $properties) to normalize user-provided properties

Files:

  • source/Classes/020.SqlAgentAlert.ps1

⚙️ CodeRabbit configuration file

source/[cC]lasses/**/*.ps1: # DSC Class-Based Resource Guidelines

Applies to: Classes with [DscResource(...)] decoration only.

Requirements

  • File: source/Classes/020.{ResourceName}.ps1
  • Decoration: [DscResource(RunAsCredential = 'Optional')] (replace with 'Mandatory' if required)
  • Inheritance: Must inherit ResourceBase (part of module DscResource.Base)
  • $this.localizedData hashtable auto-populated by ResourceBase from localization file

Required constructor

MyResourceName () : base ($PSScriptRoot)
{
    # Property names where state cannot be enforced, e.g Ensure
    $this.ExcludeDscProperties = @()
}

Required Method Pattern

[MyResourceName] Get()
{
    # Call base implementation to get current state
    $currentState = ([ResourceBase] $this).Get()

    # If needed, post-processing on current state that can not be handled by GetCurrentState()

    return $currentState
}

[System.Boolean] Test()
{
    # Call base implementation to test current state
    $inDesiredState = ([ResourceBase] $this).Test()

    # If needed, post-processing on test result that can not be handled by base Test()

    return $inDesiredState
}

[void] Set()
{
    # Call base implementation to set desired state
    ([ResourceBase] $this).Set()

    # If needed, additional state changes that can not be handled by Modify()
}

hidden [System.Collections.Hashtable] GetCurrentState([System.Collections.Hashtable] $properties)
{
    # Always return current state as hashtable, $properties contains key properties
}

hidden [void] Modify([System.Collections.Hashtable] $properties)
{
    # Always set desired state, $properties contain those that must change state
}

Optional Method Pattern

hidden [void] AssertProperties([System.Collections.Hashtable] $properties)
{
    # Validate user-provided properties, $properties contains user assigned values
}

hidden [void] NormalizeProperties([System.Collections.Hashtable] $pr...

Files:

  • source/Classes/020.SqlAgentAlert.ps1
source/**/*.ps1

📄 CodeRabbit inference engine (.github/instructions/dsc-community-style-guidelines-localization.instructions.md)

source/**/*.ps1: Localize all Write-Debug, Write-Verbose, Write-Error, Write-Warning, and $PSCmdlet.ThrowTerminatingError() messages
Do not hardcode user-facing strings; use localized string keys instead
Access localized strings via $script:localizedData, formatting with -f when needed

Localize all strings in source code using string keys

Files:

  • source/Classes/020.SqlAgentAlert.ps1

⚙️ CodeRabbit configuration file

source/**/*.ps1: # Localization Guidelines

Requirements

  • Localize all Write-Debug, Write-Verbose, Write-Error, Write-Warning and $PSCmdlet.ThrowTerminatingError() messages
  • Use localized string keys, not hardcoded strings
  • Assume $script:localizedData is available

String Files

  • Commands/functions: source/en-US/SqlServerDsc.strings.psd1
  • Class resources: source/en-US/{ResourceClassName}.strings.psd1

Key Naming Patterns

  • Format: Verb_FunctionName_Action (underscore separators), e.g. Get_SqlDscDatabase_ConnectingToDatabase

String Format

ConvertFrom-StringData @'
    KeyName = Message with {0} placeholder. (PREFIX0001)
'@

String IDs

  • Format: (PREFIX####)
  • PREFIX: First letter of each word in class or function name (SqlSetup → SS, Get-SqlDscDatabase → GSDD)
  • Number: Sequential from 0001

Usage

Write-Verbose -Message ($script:localizedData.KeyName -f $value1)

Files:

  • source/Classes/020.SqlAgentAlert.ps1
**

⚙️ CodeRabbit configuration file

**: # DSC Community Guidelines

Terminology

  • Command: Public command
  • Function: Private function
  • Resource: DSC class-based resource

Build & Test Workflow

  • Run project scripts in PowerShell from repository root
  • Build after source changes: .\build.ps1 -Tasks build
  • Test workflow: Build → Invoke-Pester -Path @('<test paths>') -Output Detailed
  • New session required after class changes

File Organization

  • Public commands: source/Public/{CommandName}.ps1
  • Private functions: source/Private/{FunctionName}.ps1
  • Unit tests: tests/Unit/{Classes|Public|Private}/{Name}.Tests.ps1
  • Integration tests: tests/Integration/Commands/{CommandName}.Integration.Tests.ps1

Requirements

  • Follow guidelines over existing code patterns
  • Always update CHANGELOG.md Unreleased section
  • Localize all strings using string keys; remove any orphaned string keys
  • Check DscResource.Common before creating private functions
  • Separate reusable logic into private functions
  • Add unit tests for all commands/functions/resources
  • Add integration tests for all public commands and resources

Files:

  • source/Classes/020.SqlAgentAlert.ps1
**/*.ps?(m|d)1

⚙️ CodeRabbit configuration file

**/*.ps?(m|d)1: # PowerShell Guidelines

Naming

  • Use descriptive names (3+ characters, no abbreviations)
  • Functions: PascalCase with Verb-Noun format using approved verbs
  • Parameters: PascalCase
  • Variables: camelCase
  • Keywords: lower-case
  • Classes: PascalCase
  • Include scope for script/global/environment variables: $script:, $global:, $env:

File naming

  • Class files: ###.ClassName.ps1 format (e.g. 001.SqlReason.ps1, 004.StartupParameters.ps1)

Formatting

Indentation & Spacing

  • Use 4 spaces (no tabs)
  • One space around operators: $a = 1 + 2
  • One space between type and variable: [String] $name
  • One space between keyword and parenthesis: if ($condition)
  • No spaces on empty lines
  • Try to limit lines to 120 characters

Braces

  • Newline before opening brace (except variable assignments)
  • One newline after opening brace
  • Two newlines after closing brace (one if followed by another brace or continuation)

Quotes

  • Use single quotes unless variable expansion is needed: 'text' vs "text $variable"

Arrays

  • Single line: @('one', 'two', 'three')
  • Multi-line: each element on separate line with proper indentation
  • Do not use the unary comma operator (,) in return statements to force
    an array

Hashtables

  • Empty: @{}
  • Multi-line: each property on separate line with proper indentation
  • Properties: Use PascalCase

Comments

  • Single line: # Comment (capitalized, on own line)
  • Multi-line: <# Comment #> format (opening and closing brackets on own line), and indent text
  • No commented-out code

Comment-based help

  • Always add comment-based help to all functions and scripts
  • Comment-based help: SYNOPSIS, DESCRIPTION (40+ chars), PARAMETER, EXAMPLE sections before function/class
  • Comment-based help indentation: keywords 4 spaces, text 8 spaces
  • Include examples for all parameter sets and combinations
  • INPUTS: List each pipeline‑accepted type (one per line) with a 1‑line description.
  • ...

Files:

  • source/Classes/020.SqlAgentAlert.ps1
🧠 Learnings (14)
📓 Common learnings
Learnt from: CR
PR: dsccommunity/SqlServerDsc#0
File: .github/instructions/SqlServerDsc-guidelines.instructions.md:0-0
Timestamp: 2025-08-25T10:04:53.158Z
Learning: Applies to **/DSCResources/**.{ps1,psm1} : Database Engine DSC resources must inherit the SqlResourceBase base class
📚 Learning: 2025-08-25T10:04:53.158Z
Learnt from: CR
PR: dsccommunity/SqlServerDsc#0
File: .github/instructions/SqlServerDsc-guidelines.instructions.md:0-0
Timestamp: 2025-08-25T10:04:53.158Z
Learning: Applies to **/DSCResources/**.{ps1,psm1} : Database Engine DSC resources must inherit the SqlResourceBase base class

Applied to files:

  • source/Classes/020.SqlAgentAlert.ps1
📚 Learning: 2025-08-25T10:05:30.603Z
Learnt from: CR
PR: dsccommunity/SqlServerDsc#0
File: .github/instructions/dsc-community-style-guidelines-class-resource.instructions.md:0-0
Timestamp: 2025-08-25T10:05:30.603Z
Learning: Applies to source/[cC]lasses/**/*.ps1 : Implement hidden [void] AssertProperties([System.Collections.Hashtable] $properties) to validate user-provided properties

Applied to files:

  • source/Classes/020.SqlAgentAlert.ps1
📚 Learning: 2025-08-28T15:42:41.195Z
Learnt from: johlju
PR: dsccommunity/SqlServerDsc#2150
File: source/Classes/020.SqlAgentAlert.ps1:0-0
Timestamp: 2025-08-28T15:42:41.195Z
Learning: Assert-BoundParameter now supports AtLeastOneList parameter (resolved in commit 809953f367ee903969a43e44a5b78e902ef46948) which can be used alongside MutuallyExclusiveList to enforce "exactly one required" validation in DSC resources.

Applied to files:

  • source/Classes/020.SqlAgentAlert.ps1
📚 Learning: 2025-08-28T15:42:41.195Z
Learnt from: johlju
PR: dsccommunity/SqlServerDsc#2150
File: source/Classes/020.SqlAgentAlert.ps1:0-0
Timestamp: 2025-08-28T15:42:41.195Z
Learning: Assert-BoundParameter supports AtLeastOneList parameter which can be used with IfEqualParameterList to enforce "exactly one required" validation conditionally (e.g., when Ensure = 'Present') in DSC resources. This is used alongside MutuallyExclusiveList for comprehensive parameter validation.

Applied to files:

  • source/Classes/020.SqlAgentAlert.ps1
📚 Learning: 2025-08-28T17:10:34.743Z
Learnt from: johlju
PR: dsccommunity/SqlServerDsc#2150
File: source/Classes/020.SqlAgentAlert.ps1:198-217
Timestamp: 2025-08-28T17:10:34.743Z
Learning: DSC properties with default values (e.g., `$Ensure = 'Present'`) are always present in the properties hashtable passed to validation methods, even when not explicitly specified by the user.

Applied to files:

  • source/Classes/020.SqlAgentAlert.ps1
📚 Learning: 2025-08-25T10:05:30.603Z
Learnt from: CR
PR: dsccommunity/SqlServerDsc#0
File: .github/instructions/dsc-community-style-guidelines-class-resource.instructions.md:0-0
Timestamp: 2025-08-25T10:05:30.603Z
Learning: Applies to source/[cC]lasses/**/*.ps1 : Implement hidden [void] Modify([System.Collections.Hashtable] $properties) to set desired state only for non-compliant properties

Applied to files:

  • source/Classes/020.SqlAgentAlert.ps1
📚 Learning: 2025-08-25T10:09:27.870Z
Learnt from: CR
PR: dsccommunity/SqlServerDsc#0
File: .github/instructions/dsc-community-style-guidelines-unit-tests.instructions.md:0-0
Timestamp: 2025-08-25T10:09:27.870Z
Learning: Applies to tests/{Unit,uUnit}/**/*.[Tt]ests.ps1 : Test parameter properties explicitly; e.g., assert that a parameter is Mandatory using (Get-Command).Parameters['Name'].Attributes.Mandatory | Should -BeTrue

Applied to files:

  • source/Classes/020.SqlAgentAlert.ps1
📚 Learning: 2025-08-28T17:12:44.212Z
Learnt from: johlju
PR: dsccommunity/SqlServerDsc#2150
File: source/Classes/020.SqlAgentAlert.ps1:141-150
Timestamp: 2025-08-28T17:12:44.212Z
Learning: For SqlServerDsc resources that inherit SqlResourceBase, the constructor pattern should be `MyResourceName() : base () { }` without the $PSScriptRoot parameter, as specified in the SqlServerDsc-specific guidelines which override the general DSC community guidelines.

Applied to files:

  • source/Classes/020.SqlAgentAlert.ps1
📚 Learning: 2025-08-25T10:05:30.603Z
Learnt from: CR
PR: dsccommunity/SqlServerDsc#0
File: .github/instructions/dsc-community-style-guidelines-class-resource.instructions.md:0-0
Timestamp: 2025-08-25T10:05:30.603Z
Learning: Applies to source/[cC]lasses/**/*.ps1 : Resource classes must inherit ResourceBase (from the DscResource.Base module)

Applied to files:

  • source/Classes/020.SqlAgentAlert.ps1
📚 Learning: 2025-08-25T10:05:30.603Z
Learnt from: CR
PR: dsccommunity/SqlServerDsc#0
File: .github/instructions/dsc-community-style-guidelines-class-resource.instructions.md:0-0
Timestamp: 2025-08-25T10:05:30.603Z
Learning: Applies to source/[cC]lasses/**/*.ps1 : Use $this.localizedData provided by ResourceBase (auto-populated from the localization file); do not manually populate it

Applied to files:

  • source/Classes/020.SqlAgentAlert.ps1
📚 Learning: 2025-08-25T10:04:22.244Z
Learnt from: CR
PR: dsccommunity/SqlServerDsc#0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-08-25T10:04:22.244Z
Learning: Follow SqlServerDsc project specific guidelines (./instructions/SqlServerDsc-guidelines.instructions.md)

Applied to files:

  • source/Classes/020.SqlAgentAlert.ps1
📚 Learning: 2025-08-25T10:04:22.244Z
Learnt from: CR
PR: dsccommunity/SqlServerDsc#0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-08-25T10:04:22.244Z
Learning: SqlServerDsc-specific guidelines override general project guidelines

Applied to files:

  • source/Classes/020.SqlAgentAlert.ps1
📚 Learning: 2025-08-25T10:04:22.244Z
Learnt from: CR
PR: dsccommunity/SqlServerDsc#0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-08-25T10:04:22.244Z
Learning: Follow class-based resources guidelines (./instructions/dsc-community-style-guidelines-class-resource.instructions.md)

Applied to files:

  • source/Classes/020.SqlAgentAlert.ps1
🧬 Code graph analysis (1)
source/Classes/020.SqlAgentAlert.ps1 (1)
tests/Unit/Stubs/SMO.cs (2)
  • Alert (1604-1646)
  • Microsoft (1499-1649)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
  • GitHub Check: dsccommunity.SqlServerDsc (Build Package Module)
  • GitHub Check: PSScriptAnalyzer
🔇 Additional comments (1)
source/Classes/020.SqlAgentAlert.ps1 (1)

249-318: Tests already cover selector-switch and Absent validation: Set-SqlDscAgentAlert.Tests.ps1 includes “Should set MessageId to 0 when updating Severity…” and “Should set Severity to 0 when updating MessageId…”, and the SqlAgentAlert class tests assert DRC0053 when Severity or MessageId are bound with Ensure='Absent'. Ignore this suggestion.

Likely an incorrect or invalid review comment.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (1)
.github/instructions/dsc-community-style-guidelines-changelog.instructions.md (1)

12-13: Tighten wording for clarity and grammar.

Minor language cleanups to match existing guidance and reduce ambiguity.

- - No empty lines between list items in same section
- - Do not add item if there are already an existing item for the same change
+ - No empty lines between list items within the same section
+ - Do not add an item if an existing item already covers the same change
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

💡 Knowledge Base configuration:

  • Jira integration is disabled
  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 3354094 and 0a2fba5.

📒 Files selected for processing (2)
  • .github/instructions/dsc-community-style-guidelines-changelog.instructions.md (1 hunks)
  • source/Classes/020.SqlAgentAlert.ps1 (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • source/Classes/020.SqlAgentAlert.ps1
🧰 Additional context used
🧠 Learnings (9)
📓 Common learnings
Learnt from: CR
PR: dsccommunity/SqlServerDsc#0
File: .github/instructions/SqlServerDsc-guidelines.instructions.md:0-0
Timestamp: 2025-08-25T10:04:53.158Z
Learning: Applies to **/DSCResources/**.{ps1,psm1} : Database Engine DSC resources must inherit the SqlResourceBase base class
📚 Learning: 2025-08-25T10:04:22.244Z
Learnt from: CR
PR: dsccommunity/SqlServerDsc#0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-08-25T10:04:22.244Z
Learning: Applies to CHANGELOG.md : Always update CHANGELOG.md (./instructions/dsc-community-style-guidelines-changelog.instructions.md)

Applied to files:

  • .github/instructions/dsc-community-style-guidelines-changelog.instructions.md
📚 Learning: 2025-08-25T10:05:03.836Z
Learnt from: CR
PR: dsccommunity/SqlServerDsc#0
File: .github/instructions/dsc-community-style-guidelines-changelog.instructions.md:0-0
Timestamp: 2025-08-25T10:05:03.836Z
Learning: Applies to CHANGELOG.md : Reference issues using the format [#<issue_number>](https://github.com/<owner>/<repo>/issues/<issue_number>)

Applied to files:

  • .github/instructions/dsc-community-style-guidelines-changelog.instructions.md
📚 Learning: 2025-08-25T10:05:03.836Z
Learnt from: CR
PR: dsccommunity/SqlServerDsc#0
File: .github/instructions/dsc-community-style-guidelines-changelog.instructions.md:0-0
Timestamp: 2025-08-25T10:05:03.836Z
Learning: Applies to CHANGELOG.md : Describe notable changes briefly; limit to ≤2 items per change type

Applied to files:

  • .github/instructions/dsc-community-style-guidelines-changelog.instructions.md
📚 Learning: 2025-08-25T10:05:03.836Z
Learnt from: CR
PR: dsccommunity/SqlServerDsc#0
File: .github/instructions/dsc-community-style-guidelines-changelog.instructions.md:0-0
Timestamp: 2025-08-25T10:05:03.836Z
Learning: Applies to CHANGELOG.md : Use Keep a Changelog format in CHANGELOG.md

Applied to files:

  • .github/instructions/dsc-community-style-guidelines-changelog.instructions.md
📚 Learning: 2025-08-25T10:04:22.244Z
Learnt from: CR
PR: dsccommunity/SqlServerDsc#0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-08-25T10:04:22.244Z
Learning: Follow project-level guidelines (./instructions/dsc-community-style-guidelines.instructions.md)

Applied to files:

  • .github/instructions/dsc-community-style-guidelines-changelog.instructions.md
📚 Learning: 2025-08-25T10:10:02.089Z
Learnt from: CR
PR: dsccommunity/SqlServerDsc#0
File: .github/instructions/dsc-community-style-guidelines.instructions.md:0-0
Timestamp: 2025-08-25T10:10:02.089Z
Learning: Applies to CHANGELOG.md : Always update the Unreleased section in CHANGELOG.md

Applied to files:

  • .github/instructions/dsc-community-style-guidelines-changelog.instructions.md
📚 Learning: 2025-08-25T10:05:03.836Z
Learnt from: CR
PR: dsccommunity/SqlServerDsc#0
File: .github/instructions/dsc-community-style-guidelines-changelog.instructions.md:0-0
Timestamp: 2025-08-25T10:05:03.836Z
Learning: Applies to CHANGELOG.md : No empty lines between list items within the same section

Applied to files:

  • .github/instructions/dsc-community-style-guidelines-changelog.instructions.md
📚 Learning: 2025-08-25T10:05:03.836Z
Learnt from: CR
PR: dsccommunity/SqlServerDsc#0
File: .github/instructions/dsc-community-style-guidelines-changelog.instructions.md:0-0
Timestamp: 2025-08-25T10:05:03.836Z
Learning: Applies to CHANGELOG.md : Do not add an item if an existing item already covers the same change

Applied to files:

  • .github/instructions/dsc-community-style-guidelines-changelog.instructions.md
🪛 LanguageTool
.github/instructions/dsc-community-style-guidelines-changelog.instructions.md

[grammar] ~11-~11: There might be a mistake here.
Context: ...tems per change type - Reference issues using format [issue #<issue_number>](https://...

(QB_NEW_EN)

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
  • GitHub Check: dsccommunity.SqlServerDsc (Build Package Module)
  • GitHub Check: PSScriptAnalyzer

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (5)
.github/instructions/dsc-community-style-guidelines.instructions.md (1)

16-16: Fix Invoke-Pester example: invalid array placeholder and missing article.

Use a valid PowerShell array literal and the correct article to avoid copy/paste errors.

-- Always run tests in new PowerShell session: `Invoke-Pester -Path @({test paths}) -Output Detailed`
+- Always run tests in a new PowerShell session: `Invoke-Pester -Path @('<test paths>') -Output Detailed`

Would you like me to align similar examples across other instruction files?

.github/copilot-instructions.md (2)

6-9: Satisfy markdownlint and fix the test-path example.

Add a blank line after the heading (MD022/MD032), use the correct article, and replace the non-PowerShell placeholder.

 ## Build & Test Workflow
- - Run in PowerShell, from repository root
- - Build before running tests: `.\build.ps1 -Tasks build`
- - Always run tests in new PowerShell session: `Invoke-Pester -Path @({test paths}) -Output Detailed`
+
+ - Run in PowerShell, from repository root
+ - Build before running tests: `.\build.ps1 -Tasks build`
+ - Always run tests in a new PowerShell session: `Invoke-Pester -Path @('<test paths>') -Output Detailed`

13-13: Grammar nit.

Add “the” for correctness.

-The guidelines always take priority over existing code patterns in project.
+The guidelines always take priority over existing code patterns in the project.
tests/Unit/Classes/SqlAgentAlert.Tests.ps1 (2)

1-2: Remove redundant suppression attribute.

Two identical suppressions for PSUseDeclaredVarsMoreThanAssignments; keep a single one with justification.

-[System.Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseDeclaredVarsMoreThanAssignments', '')]
 [System.Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseDeclaredVarsMoreThanAssignments', '', Justification = 'Suppressing this rule because Script Analyzer does not understand Pester syntax.')]

55-124: Optional: Verify base-class inheritance (per project learning).

Add a quick assertion that the class inherits the expected base (SqlResourceBase), strengthening contract checks.

         It 'Should be the correct type' {
             InModuleScope -ScriptBlock {
                 $instance = [SqlAgentAlert]::new()
                 $instance.GetType().Name | Should -Be 'SqlAgentAlert'
             }
         }
+
+        It 'Should inherit from SqlResourceBase' {
+            InModuleScope -ScriptBlock {
+                [SqlAgentAlert].BaseType.Name | Should -Be 'SqlResourceBase'
+            }
+        }
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

💡 Knowledge Base configuration:

  • Jira integration is disabled
  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 0a2fba5 and 87fec7e.

📒 Files selected for processing (3)
  • .github/copilot-instructions.md (1 hunks)
  • .github/instructions/dsc-community-style-guidelines.instructions.md (1 hunks)
  • tests/Unit/Classes/SqlAgentAlert.Tests.ps1 (1 hunks)
🧰 Additional context used
📓 Path-based instructions (10)
**/*.{ps1,psm1,psd1}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

Always follow PowerShell code style guidelines (./instructions/dsc-community-style-guidelines-powershell.instructions.md)

**/*.{ps1,psm1,psd1}: Use 4 spaces for indentation (no tabs)
One space around operators (e.g., $a = 1 + 2)
No spaces on empty lines
Try to limit lines to 120 characters
Use single quotes unless variable expansion is needed
Arrays single-line: @('one','two','three')
Arrays multi-line: each element on its own indented line
Hashtables empty literal uses @{}
Hashtables multi-line: each property on a separate indented line
Hashtable properties use PascalCase
Single-line comments use '# Comment' style: capitalized, on own line
Multi-line comments use <# #> with brackets on their own lines and indented text
End files with only one blank line
Use CR+LF line endings
Maximum of two consecutive newlines
Use UTF-8 encoding without BOM for all files

Files:

  • tests/Unit/Classes/SqlAgentAlert.Tests.ps1
**/*.{ps1,psm1}

📄 CodeRabbit inference engine (.github/instructions/SqlServerDsc-guidelines.instructions.md)

**/*.{ps1,psm1}: Public PowerShell commands must follow the naming format: Verb-SqlDsc{Noun}
Prefer SMO over T-SQL for SQL Server interaction

**/*.{ps1,psm1}: Use descriptive names (3+ characters, no abbreviations)
Function names use PascalCase with Verb-Noun format using approved verbs
Parameter names use PascalCase
Variable names use camelCase
Keywords should be lower-case
Include scope qualifier for script/global/environment variables: $script:, $global:, $env:
One space between type and variable (e.g., [String] $name)
One space between keyword and parenthesis (e.g., if ($condition))
Newline before opening brace (except variable assignments)
One newline after opening brace
Two newlines after closing brace (one if followed by another brace or continuation)
Do not use the unary comma operator in return statements to force an array
Do not keep commented-out code
Always add comment-based help to all functions and scripts
Comment-based help must include SYNOPSIS, DESCRIPTION (40+ chars), PARAMETER, EXAMPLE sections before function/class
Comment-based help indentation: keywords at 4 spaces, text at 8 spaces
Include examples for all parameter sets and combinations in help
INPUTS: list each pipeline-accepted type (one per line) with a 1‑line description
OUTPUTS: list each return type (one per line) with a 1‑line description; must match [OutputType()] and actual returns
.NOTES only when critical (constraints, side effects, security, version compatibility, breaking behavior), ≤2 short sentences
Avoid aliases; use full command names
Avoid Write-Host; prefer Write-Verbose/Write-Information, etc.
Avoid Write-Output; use 'return' instead
Avoid ConvertTo-SecureString -AsPlainText in production code
Do not redefine reserved parameters (Verbose, Debug, etc.)
Include a Force parameter for functions that support ShouldContinue or use ShouldProcess
For state-changing functions, set SupportsShouldProcess
Use $PSCmdlet.ThrowTerminatingError() for terminating errors with relevant ...

Files:

  • tests/Unit/Classes/SqlAgentAlert.Tests.ps1
tests/Unit/**/*.Tests.ps1

📄 CodeRabbit inference engine (.github/instructions/SqlServerDsc-guidelines.instructions.md)

tests/Unit/**/*.Tests.ps1: In unit tests, use SMO stub types defined in SMO.cs
In unit tests, do not mock SMO types directly
Unit tests must set $env:SqlServerDscCI = $true in BeforeAll and remove it in AfterAll

Files:

  • tests/Unit/Classes/SqlAgentAlert.Tests.ps1
**/*.[Tt]ests.ps1

📄 CodeRabbit inference engine (.github/instructions/dsc-community-style-guidelines-pester.instructions.md)

**/*.[Tt]ests.ps1: Use Pester v5 syntax only
Use exactly one Describe block per test file, named to match the tested entity
Place all test code only inside Describe blocks
Place assertions only inside It blocks
Do not test Write-Verbose, Write-Debug, or parameter binding behavior
Always pass all mandatory parameters in tests to avoid prompts
Each scenario should be a separate Context block
Use nested Context blocks for complex scenarios
Define mocks in BeforeAll (use BeforeEach for mocking only when required)
Place setup/teardown in the nearest appropriate BeforeAll/BeforeEach/AfterAll/AfterEach to where it is used
Use PascalCase for Pester keywords: Describe, Context, It, Should, BeforeAll, BeforeEach, AfterAll, AfterEach
Start It descriptions with 'Should'
Start Context descriptions with 'When'
Prefix mock variables with 'mock'
Prefer -BeTrue and -BeFalse over -Be $true and -Be $false
Do not use 'Should -Not -Throw'; invoke commands directly instead
For data-driven tests, define variables in a separate BeforeDiscovery for -ForEach close to usage
Use -ForEach only on Context and It blocks
Keep variable and mock scope as close as possible to the usage context
Assign unused return objects to $null
Invoke the tested entity from within It blocks only
Keep results and assertions within the same It block
Use BeforeEach and AfterEach sparingly
Avoid try/catch/finally for cleanup; use AfterAll or AfterEach instead

Files:

  • tests/Unit/Classes/SqlAgentAlert.Tests.ps1

⚙️ CodeRabbit configuration file

**/*.[Tt]ests.ps1: # Tests Guidelines

Core Requirements

  • All public commands, private functions and classes must have unit tests
  • All public commands and class-based resources must have integration tests
  • Use Pester v5 syntax only
  • One Describe block per file matching the tested entity name
  • Test code only inside Describe blocks
  • Assertions only in It blocks
  • Never test verbose messages, debug messages or parameter binding behavior
  • Pass all mandatory parameters to avoid prompts

Structure & Scope

  • Public commands: Never use InModuleScope (unless retrieving localized strings)
  • Private functions/class resources: Always use InModuleScope
  • Each scenario = separate Context block
  • Use nested Context blocks for complex scenarios
  • Mocking in BeforeAll (BeforeEach only when required)
  • Setup/teardown in BeforeAll,BeforeEach/AfterAll,AfterEach close to usage

Syntax Rules

  • PascalCase: Describe, Context, It, Should, BeforeAll, BeforeEach, AfterAll, AfterEach
  • Context descriptions start with 'When'
  • It descriptions start with 'Should', must not contain 'when'
  • Mock variables prefix: 'mock'
  • Prefer -BeTrue/-BeFalse over -Be $true/-Be $false
  • No Should -Not -Throw - invoke commands directly
  • Never add an empty -MockWith block
  • Omit -MockWith when returning $null
  • Set $PSDefaultParameterValues for Mock:ModuleName, Should:ModuleName, InModuleScope:ModuleName
  • Omit -ModuleName parameter on Pester commands

File Organization

  • Class resources: tests/Unit/Classes/{Name}.Tests.ps1
  • Public commands: tests/Unit/Public/{Name}.Tests.ps1
  • Private functions: tests/Unit/Private/{Name}.Tests.ps1

Data-Driven Tests

  • Define variables in separate BeforeDiscovery for -ForEach (close to usage)
  • -ForEach allowed on Context and It blocks
  • Keep scope close to usage context

Best Practices

  • Inside It blocks, assign unused return objects to $null (unless part of ...

Files:

  • tests/Unit/Classes/SqlAgentAlert.Tests.ps1
tests/Unit/{Private,Classes}/**/*.Tests.ps1

📄 CodeRabbit inference engine (.github/instructions/dsc-community-style-guidelines-pester.instructions.md)

For private functions and class resource tests, always use InModuleScope

Files:

  • tests/Unit/Classes/SqlAgentAlert.Tests.ps1
tests/Unit/Classes/*.Tests.ps1

📄 CodeRabbit inference engine (.github/instructions/dsc-community-style-guidelines-pester.instructions.md)

Place unit tests for class resources in tests/Unit/Classes/{Name}.Tests.ps1

Add unit tests for all resources (class-based)

Files:

  • tests/Unit/Classes/SqlAgentAlert.Tests.ps1
tests/{Unit,uUnit}/**/*.[Tt]ests.ps1

📄 CodeRabbit inference engine (.github/instructions/dsc-community-style-guidelines-unit-tests.instructions.md)

tests/{Unit,uUnit}/**/*.[Tt]ests.ps1: In Pester unit tests, access localized strings using InModuleScope -ScriptBlock { $script:localizedData.Key }
When mocking file operations in tests, use the $TestDrive variable for file paths
All public commands must include parameter set validation tests
Include the exact provided setup block (SuppressMessage attributes, BeforeDiscovery, BeforeAll, AfterAll) before each Describe in unit tests
For commands with a single parameter set, include a parameter set validation test using the provided It block template
For commands with multiple parameter sets, validate each set by supplying multiple hashtables to -ForEach in the parameter set validation test
Test parameter properties explicitly; e.g., assert that a parameter is Mandatory using (Get-Command).Parameters['Name'].Attributes.Mandatory | Should -BeTrue

Files:

  • tests/Unit/Classes/SqlAgentAlert.Tests.ps1
tests/Unit/{Classes,Public,Private}/*.Tests.ps1

📄 CodeRabbit inference engine (.github/instructions/dsc-community-style-guidelines.instructions.md)

Place unit tests in tests/Unit/{Classes|Public|Private}/{Name}.Tests.ps1

Files:

  • tests/Unit/Classes/SqlAgentAlert.Tests.ps1
**

⚙️ CodeRabbit configuration file

**: # DSC Community Guidelines

Terminology

  • Command: Public command
  • Function: Private function
  • Resource: DSC class-based resource

Build & Test Workflow

  • Run project scripts in PowerShell from repository root
  • Build after source changes: .\build.ps1 -Tasks build
  • Test workflow: Build → Invoke-Pester -Path @('<test paths>') -Output Detailed
  • New session required after class changes

File Organization

  • Public commands: source/Public/{CommandName}.ps1
  • Private functions: source/Private/{FunctionName}.ps1
  • Unit tests: tests/Unit/{Classes|Public|Private}/{Name}.Tests.ps1
  • Integration tests: tests/Integration/Commands/{CommandName}.Integration.Tests.ps1

Requirements

  • Follow guidelines over existing code patterns
  • Always update CHANGELOG.md Unreleased section
  • Localize all strings using string keys; remove any orphaned string keys
  • Check DscResource.Common before creating private functions
  • Separate reusable logic into private functions
  • Add unit tests for all commands/functions/resources
  • Add integration tests for all public commands and resources

Files:

  • tests/Unit/Classes/SqlAgentAlert.Tests.ps1
**/*.ps?(m|d)1

⚙️ CodeRabbit configuration file

**/*.ps?(m|d)1: # PowerShell Guidelines

Naming

  • Use descriptive names (3+ characters, no abbreviations)
  • Functions: PascalCase with Verb-Noun format using approved verbs
  • Parameters: PascalCase
  • Variables: camelCase
  • Keywords: lower-case
  • Classes: PascalCase
  • Include scope for script/global/environment variables: $script:, $global:, $env:

File naming

  • Class files: ###.ClassName.ps1 format (e.g. 001.SqlReason.ps1, 004.StartupParameters.ps1)

Formatting

Indentation & Spacing

  • Use 4 spaces (no tabs)
  • One space around operators: $a = 1 + 2
  • One space between type and variable: [String] $name
  • One space between keyword and parenthesis: if ($condition)
  • No spaces on empty lines
  • Try to limit lines to 120 characters

Braces

  • Newline before opening brace (except variable assignments)
  • One newline after opening brace
  • Two newlines after closing brace (one if followed by another brace or continuation)

Quotes

  • Use single quotes unless variable expansion is needed: 'text' vs "text $variable"

Arrays

  • Single line: @('one', 'two', 'three')
  • Multi-line: each element on separate line with proper indentation
  • Do not use the unary comma operator (,) in return statements to force
    an array

Hashtables

  • Empty: @{}
  • Multi-line: each property on separate line with proper indentation
  • Properties: Use PascalCase

Comments

  • Single line: # Comment (capitalized, on own line)
  • Multi-line: <# Comment #> format (opening and closing brackets on own line), and indent text
  • No commented-out code

Comment-based help

  • Always add comment-based help to all functions and scripts
  • Comment-based help: SYNOPSIS, DESCRIPTION (40+ chars), PARAMETER, EXAMPLE sections before function/class
  • Comment-based help indentation: keywords 4 spaces, text 8 spaces
  • Include examples for all parameter sets and combinations
  • INPUTS: List each pipeline‑accepted type (one per line) with a 1‑line description.
  • ...

Files:

  • tests/Unit/Classes/SqlAgentAlert.Tests.ps1
🧠 Learnings (32)
📓 Common learnings
Learnt from: CR
PR: dsccommunity/SqlServerDsc#0
File: .github/instructions/SqlServerDsc-guidelines.instructions.md:0-0
Timestamp: 2025-08-25T10:04:53.158Z
Learning: Applies to **/DSCResources/**.{ps1,psm1} : Database Engine DSC resources must inherit the SqlResourceBase base class
📚 Learning: 2025-08-25T10:10:02.089Z
Learnt from: CR
PR: dsccommunity/SqlServerDsc#0
File: .github/instructions/dsc-community-style-guidelines.instructions.md:0-0
Timestamp: 2025-08-25T10:10:02.089Z
Learning: Applies to tests/Unit/Classes/*.Tests.ps1 : Add unit tests for all resources (class-based)

Applied to files:

  • tests/Unit/Classes/SqlAgentAlert.Tests.ps1
  • .github/instructions/dsc-community-style-guidelines.instructions.md
📚 Learning: 2025-08-25T10:04:53.158Z
Learnt from: CR
PR: dsccommunity/SqlServerDsc#0
File: .github/instructions/SqlServerDsc-guidelines.instructions.md:0-0
Timestamp: 2025-08-25T10:04:53.158Z
Learning: Applies to tests/Unit/**/*.Tests.ps1 : Unit tests must set $env:SqlServerDscCI = $true in BeforeAll and remove it in AfterAll

Applied to files:

  • tests/Unit/Classes/SqlAgentAlert.Tests.ps1
📚 Learning: 2025-08-25T10:07:49.137Z
Learnt from: CR
PR: dsccommunity/SqlServerDsc#0
File: .github/instructions/dsc-community-style-guidelines-pester.instructions.md:0-0
Timestamp: 2025-08-25T10:07:49.137Z
Learning: Applies to tests/Unit/Classes/*.Tests.ps1 : Place unit tests for class resources in tests/Unit/Classes/{Name}.Tests.ps1

Applied to files:

  • tests/Unit/Classes/SqlAgentAlert.Tests.ps1
  • .github/instructions/dsc-community-style-guidelines.instructions.md
📚 Learning: 2025-08-25T10:10:02.089Z
Learnt from: CR
PR: dsccommunity/SqlServerDsc#0
File: .github/instructions/dsc-community-style-guidelines.instructions.md:0-0
Timestamp: 2025-08-25T10:10:02.089Z
Learning: Applies to tests/Unit/Public/*.Tests.ps1 : Add unit tests for all public commands

Applied to files:

  • tests/Unit/Classes/SqlAgentAlert.Tests.ps1
  • .github/instructions/dsc-community-style-guidelines.instructions.md
📚 Learning: 2025-08-25T10:04:53.158Z
Learnt from: CR
PR: dsccommunity/SqlServerDsc#0
File: .github/instructions/SqlServerDsc-guidelines.instructions.md:0-0
Timestamp: 2025-08-25T10:04:53.158Z
Learning: Applies to tests/Unit/**/*.Tests.ps1 : In unit tests, use SMO stub types defined in SMO.cs

Applied to files:

  • tests/Unit/Classes/SqlAgentAlert.Tests.ps1
📚 Learning: 2025-08-18T13:50:53.789Z
Learnt from: johlju
PR: dsccommunity/SqlServerDsc#2132
File: tests/Unit/Public/New-SqlDscLogin.Tests.ps1:0-0
Timestamp: 2025-08-18T13:50:53.789Z
Learning: In SqlServerDsc unit tests, SMO stub objects can be used to verify method calls like Create() on Login objects by adding mock verifications with Should -Invoke, providing more robust testing than just checking for no exceptions.

Applied to files:

  • tests/Unit/Classes/SqlAgentAlert.Tests.ps1
📚 Learning: 2025-08-25T10:09:27.870Z
Learnt from: CR
PR: dsccommunity/SqlServerDsc#0
File: .github/instructions/dsc-community-style-guidelines-unit-tests.instructions.md:0-0
Timestamp: 2025-08-25T10:09:27.870Z
Learning: Applies to tests/{Unit,uUnit}/**/*.[Tt]ests.ps1 : Test parameter properties explicitly; e.g., assert that a parameter is Mandatory using (Get-Command).Parameters['Name'].Attributes.Mandatory | Should -BeTrue

Applied to files:

  • tests/Unit/Classes/SqlAgentAlert.Tests.ps1
📚 Learning: 2025-08-28T17:10:34.765Z
Learnt from: johlju
PR: dsccommunity/SqlServerDsc#2150
File: source/Classes/020.SqlAgentAlert.ps1:198-217
Timestamp: 2025-08-28T17:10:34.765Z
Learning: DSC properties with default values (e.g., `$Ensure = 'Present'`) are always present in the properties hashtable passed to validation methods, even when not explicitly specified by the user.

Applied to files:

  • tests/Unit/Classes/SqlAgentAlert.Tests.ps1
📚 Learning: 2025-08-16T13:22:15.230Z
Learnt from: johlju
PR: dsccommunity/SqlServerDsc#2134
File: tests/Unit/Public/Get-SqlDscLogin.Tests.ps1:78-93
Timestamp: 2025-08-16T13:22:15.230Z
Learning: In PowerShell unit tests for parameter validation in SqlServerDsc, accessing parameter attributes directly like `$cmd.Parameters['ParameterName'].Attributes.Mandatory` works correctly because PowerShell automatically iterates through the array and returns the property values. Additional filtering to ParameterAttribute is not necessary when the parameter structure is known and controlled.

Applied to files:

  • tests/Unit/Classes/SqlAgentAlert.Tests.ps1
📚 Learning: 2025-08-25T10:05:48.627Z
Learnt from: CR
PR: dsccommunity/SqlServerDsc#0
File: .github/instructions/dsc-community-style-guidelines-integration-tests.instructions.md:0-0
Timestamp: 2025-08-25T10:05:48.627Z
Learning: Applies to tests/[iI]ntegration/**/*.[iI]ntegration.[tT]ests.ps1 : Avoid using ExpectedMessage with Should -Throw assertions in Pester

Applied to files:

  • tests/Unit/Classes/SqlAgentAlert.Tests.ps1
📚 Learning: 2025-08-25T10:09:27.870Z
Learnt from: CR
PR: dsccommunity/SqlServerDsc#0
File: .github/instructions/dsc-community-style-guidelines-unit-tests.instructions.md:0-0
Timestamp: 2025-08-25T10:09:27.870Z
Learning: Applies to tests/{Unit,uUnit}/**/*.[Tt]ests.ps1 : For commands with a single parameter set, include a parameter set validation test using the provided It block template

Applied to files:

  • tests/Unit/Classes/SqlAgentAlert.Tests.ps1
📚 Learning: 2025-08-25T10:05:30.603Z
Learnt from: CR
PR: dsccommunity/SqlServerDsc#0
File: .github/instructions/dsc-community-style-guidelines-class-resource.instructions.md:0-0
Timestamp: 2025-08-25T10:05:30.603Z
Learning: Applies to source/[cC]lasses/**/*.ps1 : Implement hidden [void] AssertProperties([System.Collections.Hashtable] $properties) to validate user-provided properties

Applied to files:

  • tests/Unit/Classes/SqlAgentAlert.Tests.ps1
📚 Learning: 2025-08-25T10:07:49.137Z
Learnt from: CR
PR: dsccommunity/SqlServerDsc#0
File: .github/instructions/dsc-community-style-guidelines-pester.instructions.md:0-0
Timestamp: 2025-08-25T10:07:49.137Z
Learning: Applies to **/*.[Tt]ests.ps1 : Place assertions only inside It blocks

Applied to files:

  • tests/Unit/Classes/SqlAgentAlert.Tests.ps1
📚 Learning: 2025-08-17T10:15:48.194Z
Learnt from: johlju
PR: dsccommunity/SqlServerDsc#2136
File: tests/Unit/Public/Remove-SqlDscLogin.Tests.ps1:36-39
Timestamp: 2025-08-17T10:15:48.194Z
Learning: Public command unit tests guideline: Never use InModuleScope unless accessing localized strings from $script:localizedData. PSDefaultParameterValues for InModuleScope should be kept in public command tests to support localized string retrieval when necessary.

Applied to files:

  • tests/Unit/Classes/SqlAgentAlert.Tests.ps1
📚 Learning: 2025-08-28T15:42:41.195Z
Learnt from: johlju
PR: dsccommunity/SqlServerDsc#2150
File: source/Classes/020.SqlAgentAlert.ps1:0-0
Timestamp: 2025-08-28T15:42:41.195Z
Learning: Assert-BoundParameter supports AtLeastOneList parameter which can be used with IfEqualParameterList to enforce "exactly one required" validation conditionally (e.g., when Ensure = 'Present') in DSC resources. This is used alongside MutuallyExclusiveList for comprehensive parameter validation.

Applied to files:

  • tests/Unit/Classes/SqlAgentAlert.Tests.ps1
📚 Learning: 2025-08-25T10:07:49.137Z
Learnt from: CR
PR: dsccommunity/SqlServerDsc#0
File: .github/instructions/dsc-community-style-guidelines-pester.instructions.md:0-0
Timestamp: 2025-08-25T10:07:49.137Z
Learning: Applies to **/*.[Tt]ests.ps1 : Keep results and assertions within the same It block

Applied to files:

  • tests/Unit/Classes/SqlAgentAlert.Tests.ps1
📚 Learning: 2025-08-25T10:04:22.244Z
Learnt from: CR
PR: dsccommunity/SqlServerDsc#0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-08-25T10:04:22.244Z
Learning: Applies to CHANGELOG.md : Always update CHANGELOG.md (./instructions/dsc-community-style-guidelines-changelog.instructions.md)

Applied to files:

  • .github/instructions/dsc-community-style-guidelines.instructions.md
📚 Learning: 2025-08-25T10:04:22.244Z
Learnt from: CR
PR: dsccommunity/SqlServerDsc#0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-08-25T10:04:22.244Z
Learning: Follow project-level guidelines (./instructions/dsc-community-style-guidelines.instructions.md)

Applied to files:

  • .github/instructions/dsc-community-style-guidelines.instructions.md
📚 Learning: 2025-08-25T10:04:22.244Z
Learnt from: CR
PR: dsccommunity/SqlServerDsc#0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-08-25T10:04:22.244Z
Learning: Applies to **/*.{ps1,psm1,psd1} : Always follow PowerShell code style guidelines (./instructions/dsc-community-style-guidelines-powershell.instructions.md)

Applied to files:

  • .github/instructions/dsc-community-style-guidelines.instructions.md
  • .github/copilot-instructions.md
📚 Learning: 2025-08-25T10:04:22.244Z
Learnt from: CR
PR: dsccommunity/SqlServerDsc#0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-08-25T10:04:22.244Z
Learning: Always add Integration testing according to (./instructions/dsc-community-style-guidelines-integration-tests.instructions.md)

Applied to files:

  • .github/instructions/dsc-community-style-guidelines.instructions.md
📚 Learning: 2025-08-25T10:09:05.899Z
Learnt from: CR
PR: dsccommunity/SqlServerDsc#0
File: .github/instructions/dsc-community-style-guidelines-powershell.instructions.md:0-0
Timestamp: 2025-08-25T10:09:05.899Z
Learning: Applies to **/*.{ps1,psm1} : .NOTES only when critical (constraints, side effects, security, version compatibility, breaking behavior), ≤2 short sentences

Applied to files:

  • .github/instructions/dsc-community-style-guidelines.instructions.md
📚 Learning: 2025-08-25T10:04:22.244Z
Learnt from: CR
PR: dsccommunity/SqlServerDsc#0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-08-25T10:04:22.244Z
Learning: Always add Unit testing according to (./instructions/dsc-community-style-guidelines-unit-tests.instructions.md)

Applied to files:

  • .github/instructions/dsc-community-style-guidelines.instructions.md
📚 Learning: 2025-08-25T10:10:02.089Z
Learnt from: CR
PR: dsccommunity/SqlServerDsc#0
File: .github/instructions/dsc-community-style-guidelines.instructions.md:0-0
Timestamp: 2025-08-25T10:10:02.089Z
Learning: Test workflow: Build, then run Invoke-Pester with specified test paths and Detailed output

Applied to files:

  • .github/instructions/dsc-community-style-guidelines.instructions.md
📚 Learning: 2025-08-25T10:09:27.870Z
Learnt from: CR
PR: dsccommunity/SqlServerDsc#0
File: .github/instructions/dsc-community-style-guidelines-unit-tests.instructions.md:0-0
Timestamp: 2025-08-25T10:09:27.870Z
Learning: After modifying classes, always run tests in a new PowerShell session to pick up changes

Applied to files:

  • .github/instructions/dsc-community-style-guidelines.instructions.md
📚 Learning: 2025-08-25T10:10:02.089Z
Learnt from: CR
PR: dsccommunity/SqlServerDsc#0
File: .github/instructions/dsc-community-style-guidelines.instructions.md:0-0
Timestamp: 2025-08-25T10:10:02.089Z
Learning: Run project scripts in PowerShell from the repository root

Applied to files:

  • .github/instructions/dsc-community-style-guidelines.instructions.md
📚 Learning: 2025-08-25T10:05:30.603Z
Learnt from: CR
PR: dsccommunity/SqlServerDsc#0
File: .github/instructions/dsc-community-style-guidelines-class-resource.instructions.md:0-0
Timestamp: 2025-08-25T10:05:30.603Z
Learning: Applies to source/[cC]lasses/*.ps1 : Place each DSC class-based resource in source/Classes/{ResourceName}.ps1

Applied to files:

  • .github/instructions/dsc-community-style-guidelines.instructions.md
📚 Learning: 2025-08-25T10:05:30.603Z
Learnt from: CR
PR: dsccommunity/SqlServerDsc#0
File: .github/instructions/dsc-community-style-guidelines-class-resource.instructions.md:0-0
Timestamp: 2025-08-25T10:05:30.603Z
Learning: Applies to source/[cC]lasses/**/*.ps1 : Resource classes must inherit ResourceBase (from the DscResource.Base module)

Applied to files:

  • .github/instructions/dsc-community-style-guidelines.instructions.md
📚 Learning: 2025-08-25T10:05:30.603Z
Learnt from: CR
PR: dsccommunity/SqlServerDsc#0
File: .github/instructions/dsc-community-style-guidelines-class-resource.instructions.md:0-0
Timestamp: 2025-08-25T10:05:30.603Z
Learning: Applies to source/[cC]lasses/**/*.ps1 : Only classes with a [DscResource(...)] decoration are considered DSC resources to which these rules apply

Applied to files:

  • .github/instructions/dsc-community-style-guidelines.instructions.md
📚 Learning: 2025-08-25T10:10:02.089Z
Learnt from: CR
PR: dsccommunity/SqlServerDsc#0
File: .github/instructions/dsc-community-style-guidelines.instructions.md:0-0
Timestamp: 2025-08-25T10:10:02.089Z
Learning: Build after source changes using .\build.ps1 -Tasks build

Applied to files:

  • .github/instructions/dsc-community-style-guidelines.instructions.md
📚 Learning: 2025-08-25T10:04:22.244Z
Learnt from: CR
PR: dsccommunity/SqlServerDsc#0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-08-25T10:04:22.244Z
Learning: Follow SqlServerDsc project specific guidelines (./instructions/SqlServerDsc-guidelines.instructions.md)

Applied to files:

  • .github/copilot-instructions.md
📚 Learning: 2025-08-25T10:04:22.244Z
Learnt from: CR
PR: dsccommunity/SqlServerDsc#0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-08-25T10:04:22.244Z
Learning: SqlServerDsc-specific guidelines override general project guidelines

Applied to files:

  • .github/copilot-instructions.md
🧬 Code graph analysis (1)
tests/Unit/Classes/SqlAgentAlert.Tests.ps1 (1)
tests/Unit/Stubs/SMO.cs (5)
  • Microsoft (1499-1649)
  • Alert (1604-1646)
  • JobServer (1536-1556)
  • AlertCollection (1561-1595)
  • Microsoft (12-1048)
🪛 LanguageTool
.github/instructions/dsc-community-style-guidelines.instructions.md

[grammar] ~15-~15: There might be a mistake here.
Context: ...tory root - Build before running tests: .\build.ps1 -Tasks build - Always run tests in new PowerShell sessi...

(QB_NEW_EN)


[grammar] ~16-~16: There might be a mistake here.
Context: ...ld.ps1 -Tasks build- Always run tests in new PowerShell session:Invoke-Pester ...

(QB_NEW_EN)

.github/copilot-instructions.md

[grammar] ~3-~3: There might be a mistake here.
Context: ...the project. Each instruction file below targets specific file glob patterns and ...

(QB_NEW_EN)


[grammar] ~6-~6: There might be a mistake here.
Context: ...and use cases. ## Build & Test Workflow - Run in PowerShell, from repository root ...

(QB_NEW_EN)


[grammar] ~8-~8: There might be a mistake here.
Context: ...tory root - Build before running tests: .\build.ps1 -Tasks build - Always run tests in new PowerShell sessi...

(QB_NEW_EN)


[grammar] ~9-~9: There might be a mistake here.
Context: ...ld.ps1 -Tasks build- Always run tests in new PowerShell session:Invoke-Pester ...

(QB_NEW_EN)

🪛 markdownlint-cli2 (0.17.2)
.github/copilot-instructions.md

8-8: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below

(MD022, blanks-around-headings)


9-9: Lists should be surrounded by blank lines

(MD032, blanks-around-lists)

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
  • GitHub Check: dsccommunity.SqlServerDsc (Build Package Module)
  • GitHub Check: PSScriptAnalyzer
  • GitHub Check: PSScriptAnalyzer
🔇 Additional comments (1)
tests/Unit/Classes/SqlAgentAlert.Tests.ps1 (1)

192-239: Good functional coverage for Test() scenarios.

Positive/negative paths are validated with clear expectations; mocks and assertions are scoped correctly.

@johlju johlju merged commit 2c7ba54 into dsccommunity:main Aug 29, 2025
43 checks passed
@johlju johlju deleted the f/refactor-sqlagentalert-resource branch August 29, 2025 17:19
@coderabbitai coderabbitai bot mentioned this pull request Aug 29, 2025
9 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet