SqlPermission: Refactor to use new server permission commands#2360
SqlPermission: Refactor to use new server permission commands#2360johlju merged 4 commits intodsccommunity:mainfrom
Conversation
WalkthroughSqlPermission was refactored to resolve principals as Login or ServerRole and to replace the deprecated Set-SqlDscServerPermission with object-based cmdlets (Grant-/Deny-/Revoke-SqlDscServerPermission and Get-SqlDscLogin/Get-SqlDscRole); tests, changelog, and a resource string were updated. Changes
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes
Possibly related PRs
Pre-merge checks✅ Passed checks (5 passed)
📜 Recent review detailsConfiguration used: CodeRabbit UI Review profile: CHILL Plan: Pro 📒 Files selected for processing (2)
🧰 Additional context used📓 Path-based instructions (14)**/*.ps1📄 CodeRabbit inference engine (.github/instructions/SqlServerDsc-guidelines.instructions.md)
Files:
source/[cC]lasses/020.*.ps1📄 CodeRabbit inference engine (.github/instructions/dsc-community-style-guidelines-class-resource.instructions.md)
Files:
source/[cC]lasses/**/*.ps1📄 CodeRabbit inference engine (.github/instructions/dsc-community-style-guidelines-class-resource.instructions.md)
Files:
⚙️ CodeRabbit configuration file
Files:
source/**/*.ps1📄 CodeRabbit inference engine (.github/instructions/dsc-community-style-guidelines-localization.instructions.md)
Files:
⚙️ CodeRabbit configuration file
Files:
source/Classes/*.ps1📄 CodeRabbit inference engine (.github/instructions/dsc-community-style-guidelines.instructions.md)
Files:
**/*.{ps1,psm1,psd1}📄 CodeRabbit inference engine (.github/instructions/dsc-community-style-guidelines-powershell.instructions.md)
Files:
**/[0-9][0-9][0-9].*.ps1📄 CodeRabbit inference engine (.github/instructions/dsc-community-style-guidelines-powershell.instructions.md)
Files:
**/*.{ps1,psm1}📄 CodeRabbit inference engine (.github/instructions/dsc-community-style-guidelines-powershell.instructions.md)
Files:
**⚙️ CodeRabbit configuration file
Files:
{**/*.ps1,**/*.psm1,**/*.psd1}⚙️ CodeRabbit configuration file
Files:
**/*.[Tt]ests.ps1📄 CodeRabbit inference engine (.github/instructions/dsc-community-style-guidelines-pester.instructions.md)
Files:
⚙️ CodeRabbit configuration file
Files:
tests/Unit/Classes/*.[Tt]ests.ps1📄 CodeRabbit inference engine (.github/instructions/dsc-community-style-guidelines-pester.instructions.md)
Files:
tests/[Uu]nit/**/*.[Tt]ests.ps1📄 CodeRabbit inference engine (.github/instructions/dsc-community-style-guidelines-unit-tests.instructions.md)
Files:
⚙️ CodeRabbit configuration file
Files:
tests/Unit/**/*.Tests.ps1📄 CodeRabbit inference engine (.github/instructions/dsc-community-style-guidelines.instructions.md)
Files:
🧠 Learnings (29)📓 Common learnings📚 Learning: 2025-11-27T17:58:02.422ZApplied to files:
📚 Learning: 2025-08-17T10:13:30.079ZApplied to files:
📚 Learning: 2025-11-27T17:58:02.422ZApplied to files:
📚 Learning: 2025-11-27T17:58:02.422ZApplied to files:
📚 Learning: 2025-11-27T17:58:02.422ZApplied to files:
📚 Learning: 2025-11-27T17:58:02.422ZApplied to files:
📚 Learning: 2025-11-27T17:59:27.205ZApplied to files:
📚 Learning: 2025-11-27T17:59:27.205ZApplied to files:
📚 Learning: 2025-11-27T17:59:27.205ZApplied to files:
📚 Learning: 2025-11-27T17:59:27.205ZApplied to files:
📚 Learning: 2025-11-27T17:59:27.205ZApplied to files:
📚 Learning: 2025-11-27T17:59:27.205ZApplied to files:
📚 Learning: 2025-11-27T17:58:31.910ZApplied to files:
📚 Learning: 2025-11-27T17:59:27.205ZApplied to files:
📚 Learning: 2025-11-27T17:59:27.205ZApplied to files:
📚 Learning: 2025-11-27T17:59:27.205ZApplied to files:
📚 Learning: 2025-11-27T18:00:20.934ZApplied to files:
📚 Learning: 2025-11-27T18:00:20.934ZApplied to files:
📚 Learning: 2025-12-04T17:07:00.186ZApplied to files:
📚 Learning: 2025-11-27T17:59:27.205ZApplied to files:
📚 Learning: 2025-08-17T10:15:48.194ZApplied to files:
📚 Learning: 2025-10-12T12:10:48.625ZApplied to files:
📚 Learning: 2025-11-27T18:00:20.934ZApplied to files:
📚 Learning: 2025-08-16T13:22:15.230ZApplied to files:
📚 Learning: 2025-11-27T18:00:35.078ZApplied to files:
📚 Learning: 2025-11-27T17:58:31.910ZApplied to files:
📚 Learning: 2025-11-27T17:59:27.205ZApplied to files:
📚 Learning: 2025-11-27T17:59:27.205ZApplied to files:
⏰ 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)
🔇 Additional comments (13)
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. Comment |
There was a problem hiding this comment.
Actionable comments posted: 0
🧹 Nitpick comments (3)
tests/Unit/Classes/SqlPermission.Tests.ps1 (2)
1183-1191: ParameterFilter assertions on Grant/Revoke look correct but Deny path is untestedThe
Should -InvokeParameterFilterblocks forGrant-SqlDscServerPermissionandRevoke-SqlDscServerPermissionaccurately validatePermissionandWithGrantusage for Grant/GrantWithGrant and revoke scenarios. However, there is currently noShould -Invokecoverage forDeny-SqlDscServerPermission, so the Deny branch inModify()is only indirectly exercised via failure tests.
Consider adding at least one scenario that drives a Deny state and asserts aShould -Invoke -CommandName Deny-SqlDscServerPermissionwith an appropriateParameterFilterso all three code paths (Grant, GrantWithGrant, Deny) are explicitly covered.Also applies to: 1387-1395, 1279-1297, 1485-1493
1150-1155: Optional: ensure SMO.Login stub matches instance name used by the resourceThe
Get-SqlDscLoginmocks construct aMicrosoft.SqlServer.Management.Smo.Loginwith a newServerparent but do not explicitly align the server stub’sInstanceNamewith'NamedInstance'. IfSqlPermission(now or in future) inspectsprincipalObject.Parent.InstanceName, a mismatch could cause subtle test/production divergence.
Optionally consider initializing the stub server’s instance name (via the SMO.cs stub facilities) to'NamedInstance'to mirror the resource configuration and follow the prior guidance about SMO stubs having correct parents/instance names.Also applies to: 1246-1251, 1354-1359, 1452-1457
source/Classes/020.SqlPermission.ps1 (1)
374-385: Principal resolution is consistent, but ServerRole branch is currently unreachableThe new
principalObjectresolution correctly:
- Uses
Get-SqlDscLoginfor logins.- Falls back to
Get-SqlDscRolefor server roles.However, because the preceding block calls
Test-SqlDscIsLoginand then unconditionally raises a terminatingNew-InvalidOperationExceptionwhen-not $isLogin, theGet-SqlDscRolebranch is currently unreachable in normal execution.If supporting server roles is not intended yet, this is harmless but effectively dead code. If server roles are meant to be supported with the new object-based commands, you may want to revisit the principal-existence check (e.g., distinguish “principal is a role” from “principal does not exist”) and add tests that exercise the
Get-SqlDscRolepath.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (3)
CHANGELOG.md(1 hunks)source/Classes/020.SqlPermission.ps1(3 hunks)tests/Unit/Classes/SqlPermission.Tests.ps1(10 hunks)
🧰 Additional context used
📓 Path-based instructions (16)
CHANGELOG.md
📄 CodeRabbit inference engine (.github/instructions/dsc-community-style-guidelines-changelog.instructions.md)
CHANGELOG.md: Always update the Unreleased section in CHANGELOG.md
Use Keep a Changelog format in CHANGELOG.md
Describe notable changes briefly in CHANGELOG.md, ≤2 items per change type
Reference issues using format issue #<issue_number> in CHANGELOG.md
No empty lines between list items in same section of CHANGELOG.md
Skip adding entry if same change already exists in Unreleased section of CHANGELOG.md
No duplicate sections or items in Unreleased section of CHANGELOG.mdAlways update CHANGELOG.md Unreleased section
Files:
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 #<issue_number>
- No empty lines between list items in same section
- Skip adding entry if same change already exists in Unreleased section
- No duplicate sections or items in Unreleased section
Files:
CHANGELOG.md
**/*.md
📄 CodeRabbit inference engine (.github/instructions/dsc-community-style-guidelines-markdown.instructions.md)
**/*.md: Wrap lines at word boundaries when over 80 characters (except tables/code blocks)
Use 2 spaces for indentation in Markdown files
Use '1.' for all items in ordered lists (1/1/1 numbering style)
DisableMD013rule by adding a comment for tables/code blocks exceeding 80 characters
Empty lines required before/after code blocks and headings (except before line 1)
Escape backslashes in file paths only (not in code blocks)
Code blocks must specify language identifiers
Format parameters using bold in Markdown documentation
Format values and literals usinginline codein Markdown documentation
Format resource/module/product names using italic in Markdown documentation
Format commands/files/paths usinginline codein Markdown documentation
Files:
CHANGELOG.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
MD013rule by adding a comment for tables/code blocks exceeding 80 characters- Empty lines required before/after code blocks and headings (except before line 1)
- Escape backslashes in file paths only (not in code blocks)
- 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
**
⚙️ CodeRabbit configuration file
**: # DSC Community GuidelinesTerminology
- Command: Public command
- Function: Private function
- Resource: DSC class-based resource
Build & Test Workflow Requirements
- Run PowerShell script files from repository root
- Setup build and test environment (once per
pwshsession):./build.ps1 -Tasks noop- Build project before running tests:
./build.ps1 -Tasks build- Always run tests in new
pwshsession:Invoke-Pester -Path @({test paths}) -Output DetailedFile Organization
- Public commands:
source/Public/{CommandName}.ps1- Private functions:
source/Private/{FunctionName}.ps1- Classes:
source/Classes/{DependencyGroupNumber}.{ClassName}.ps1- Enums:
source/Enum/{DependencyGroupNumber}.{EnumName}.ps1- Unit tests:
tests/Unit/{Classes|Public|Private}/{Name}.Tests.ps1- Integration tests:
tests/Integration/Commands/{CommandName}.Integration.Tests.ps1Requirements
- Follow instructions over existing code patterns
- Follow PowerShell style and test guideline instructions strictly
- 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
- DSC resources should always be created as class-based resources
- Add unit tests for all commands/functions/resources
- Add integration tests for all public commands and resources
Files:
CHANGELOG.mdsource/Classes/020.SqlPermission.ps1tests/Unit/Classes/SqlPermission.Tests.ps1
**/*.ps1
📄 CodeRabbit inference engine (.github/instructions/SqlServerDsc-guidelines.instructions.md)
**/*.ps1: Format public commands as{Verb}-SqlDsc{Noun}following PowerShell naming conventions
Format private functions as{Verb}-{Noun}following PowerShell naming conventions
Files:
source/Classes/020.SqlPermission.ps1tests/Unit/Classes/SqlPermission.Tests.ps1
source/[cC]lasses/020.*.ps1
📄 CodeRabbit inference engine (.github/instructions/dsc-community-style-guidelines-class-resource.instructions.md)
DSC class-based resources must use the file naming pattern
source/Classes/020.{ResourceName}.ps1
Files:
source/Classes/020.SqlPermission.ps1
source/[cC]lasses/**/*.ps1
📄 CodeRabbit inference engine (.github/instructions/dsc-community-style-guidelines-class-resource.instructions.md)
source/[cC]lasses/**/*.ps1: DSC class-based resources must be decorated with[DscResource(RunAsCredential = 'Optional')]or[DscResource(RunAsCredential = 'Mandatory')]based on requirements
DSC class-based resources must inherit fromResourceBaseclass from the DscResource.Base module
DSC class-based resources must use[Nullable[{FullTypeName}]]syntax for value-type properties (e.g.,[Nullable[System.Int32]])
DSC class-based resources must implement a required constructor with signatureResourceName () : base ($PSScriptRoot)and populate$this.ExcludeDscPropertiesarray
DSC class-based resources must implement required methods:Get(),Test(),Set(),GetCurrentState(), andModify()following the specified pattern
DSC class-based resources may optionally implement methods:AssertProperties()andNormalizeProperties()following the specified pattern
DSC class-based resources must include comment-based help with .DESCRIPTION section containing Requirements and Known issues sections with a link to all open issues on GitHub
DSC class-based resources must usetry/catchblocks for exception handling in classes
DSC class-based resources must useNew-*Exceptioncommands (such asNew-InvalidDataException,New-ArgumentException,New-InvalidOperationException,New-ObjectNotFoundException,New-InvalidResultException,New-NotImplementedException) instead ofthrowfor terminating errors in classes
Files:
source/Classes/020.SqlPermission.ps1
⚙️ CodeRabbit configuration file
source/[cC]lasses/**/*.ps1: # DSC Class-Based Resource GuidelinesApplies 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.localizedDatahashtable auto-populated byResourceBasefrom localization file- value-type properties: Use
[Nullable[{FullTypeName}]](e.g.,[Nullable[System.Int32]])Required constructor
MyResourceName () : base ($PSScriptRoot) { # Property names where state cannot be enforced, e.g. IsSingleInstance, Force $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, $p...
Files:
source/Classes/020.SqlPermission.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 in PowerShell scripts
Use localized string keys from $script:localizedData, not hardcoded strings, in diagnostic messages
Reference localized strings using the syntax: Write-Verbose -Message ($script:localizedData.KeyName -f $value1)Localize all strings using string keys; remove any orphaned string keys
Files:
source/Classes/020.SqlPermission.ps1
⚙️ CodeRabbit configuration file
source/**/*.ps1: # Localization GuidelinesRequirements
- Localize all Write-Debug, Write-Verbose, Write-Error, Write-Warning and $PSCmdlet.ThrowTerminatingError() messages
- Use localized string keys, not hardcoded strings
- Assume
$script:localizedDatais availableString Files
- Commands/functions:
source/en-US/{MyModuleName}.strings.psd1- Class resources:
source/en-US/{ResourceClassName}.strings.psd1Key Naming Patterns
- Format:
Verb_FunctionName_Action(underscore separators), e.g.Get_Database_ConnectingToDatabaseString 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.SqlPermission.ps1
source/Classes/*.ps1
📄 CodeRabbit inference engine (.github/instructions/dsc-community-style-guidelines.instructions.md)
source/Classes/*.ps1: Classes should be located insource/Classes/{DependencyGroupNumber}.{ClassName}.ps1
DSC resources should always be created as class-based resources
Files:
source/Classes/020.SqlPermission.ps1
**/*.{ps1,psm1,psd1}
📄 CodeRabbit inference engine (.github/instructions/dsc-community-style-guidelines-powershell.instructions.md)
**/*.{ps1,psm1,psd1}: Use descriptive names with 3+ characters and no abbreviations for functions, parameters, variables, keywords, and classes
Use PascalCase with Verb-Noun format for function names, using approved PowerShell verbs
Use PascalCase for parameter names
Use camelCase for variable names
Use lower-case for keywords
Use PascalCase for class names
Include scope for script/global/environment variables using$script:,$global:, or$env:prefixes
Use 4 spaces for indentation, not tabs
Use one space around operators (e.g.,$a = 1 + 2)
Use one space between type and variable (e.g.,[String] $name)
Use one space between keyword and parenthesis (e.g.,if ($condition))
Avoid spaces on empty lines
Limit lines to 120 characters
Place opening brace on a new line, except for variable assignments
Add one newline after opening brace
Add two newlines after closing brace (one if followed by another brace or continuation)
Use single quotes unless variable expansion is needed (e.g.,'text'vs"text $variable")
Use single-line array syntax for simple arrays:@('one', 'two', 'three')
Use multi-line array syntax with each element on a separate line with proper indentation
Do not use the unary comma operator (,) in return statements to force an array
Use empty hashtable syntax:@{}
Place each hashtable property on a separate line with proper indentation
Use PascalCase for hashtable properties
Use single-line comment format# Comment(capitalized, on own line)
Use multi-line comment format<# Comment #>with opening and closing brackets on own lines and indented text
Never include commented-out code
Always add comment-based help to all functions and scripts with SYNOPSIS, DESCRIPTION (40+ chars), PARAMETER, and EXAMPLE sections before function/class declaration
Use comment-based help indentation with keywords at 4 spaces and text at 8 spaces
Include examples in comment-based help for all parameter sets and combinations
In comment-based help INPUTS sec...
Files:
source/Classes/020.SqlPermission.ps1tests/Unit/Classes/SqlPermission.Tests.ps1
**/[0-9][0-9][0-9].*.ps1
📄 CodeRabbit inference engine (.github/instructions/dsc-community-style-guidelines-powershell.instructions.md)
Name class files using
###.ClassName.ps1format (e.g.,001.SqlReason.ps1,004.StartupParameters.ps1)
Files:
source/Classes/020.SqlPermission.ps1
**/*.{ps1,psm1}
📄 CodeRabbit inference engine (.github/instructions/dsc-community-style-guidelines-powershell.instructions.md)
Use
$PSCmdlet.ThrowTerminatingError()for terminating errors (except in classes), use relevant error category, and in try-catch include exception with localized message
Files:
source/Classes/020.SqlPermission.ps1tests/Unit/Classes/SqlPermission.Tests.ps1
{**/*.ps1,**/*.psm1,**/*.psd1}
⚙️ CodeRabbit configuration file
{**/*.ps1,**/*.psm1,**/*.psd1}: # PowerShell GuidelinesNaming
- 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.ps1format (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 arrayHashtables
- Empty:
@{}- 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 as inline code with a 1‑line description...
Files:
source/Classes/020.SqlPermission.ps1tests/Unit/Classes/SqlPermission.Tests.ps1
**/*.[Tt]ests.ps1
📄 CodeRabbit inference engine (.github/instructions/dsc-community-style-guidelines-pester.instructions.md)
**/*.[Tt]ests.ps1: 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
Test code only insideDescribeblocks
Assertions only inItblocks
Never test verbose messages, debug messages or parameter binding behavior
Pass all mandatory parameters to avoid prompts
InsideItblocks, assign unused return objects to$null(unless part of pipeline)
Tested entity must be called from within theItblocks
Keep results and assertions in sameItblock
Avoid try-catch-finally for cleanup, useAfterAllorAfterEach
Avoid unnecessary remove/recreate cycles
OneDescribeblock per file matching the tested entity name
Contextdescriptions start with 'When'
Itdescriptions start with 'Should', must not contain 'when'
Mock variables prefix: 'mock'
Public commands: Never useInModuleScope(unless retrieving localized strings or creating an object using an internal class)
Private functions/class resources: Always useInModuleScope
Each class method = separateContextblock
Each scenario = separateContextblock
Use nestedContextblocks for complex scenarios
Mocking inBeforeAll(BeforeEachonly when required)
Setup/teardown inBeforeAll,BeforeEach/AfterAll,AfterEachclose to usage
Spacing between blocks, arrange, act, and assert for readability
PascalCase:Describe,Context,It,Should,BeforeAll,BeforeEach,AfterAll,AfterEach
Use-BeTrue/-BeFalsenever-Be $true/-Be $false
Never useAssert-MockCalled, useShould -Invokeinstead
NoShould -Not -Throw- invoke commands directly
Never add an empty-MockWithblock
Omit-MockWithwhen returning$null
Set$PSDefaultParameterValuesforMock:ModuleName,Should:ModuleName,InModuleScope:ModuleName
Omit-ModuleNameparameter on Pester commands
Never useMockinsideInModuleScope-block
Never useparam()inside-MockWithscriptblock...
Files:
tests/Unit/Classes/SqlPermission.Tests.ps1
⚙️ CodeRabbit configuration file
**/*.[Tt]ests.ps1: # Tests GuidelinesCore 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
- Test code only inside
Describeblocks- Assertions only in
Itblocks- Never test verbose messages, debug messages or parameter binding behavior
- Pass all mandatory parameters to avoid prompts
Requirements
- Inside
Itblocks, assign unused return objects to$null(unless part of pipeline)- Tested entity must be called from within the
Itblocks- Keep results and assertions in same
Itblock- Avoid try-catch-finally for cleanup, use
AfterAllorAfterEach- Avoid unnecessary remove/recreate cycles
Naming
- One
Describeblock per file matching the tested entity nameContextdescriptions start with 'When'Itdescriptions start with 'Should', must not contain 'when'- Mock variables prefix: 'mock'
Structure & Scope
- Public commands: Never use
InModuleScope(unless retrieving localized strings or creating an object using an internal class)- Private functions/class resources: Always use
InModuleScope- Each class method = separate
Contextblock- Each scenario = separate
Contextblock- Use nested
Contextblocks for complex scenarios- Mocking in
BeforeAll(BeforeEachonly when required)- Setup/teardown in
BeforeAll,BeforeEach/AfterAll,AfterEachclose to usage- Spacing between blocks, arrange, act, and assert for readability
Syntax Rules
- PascalCase:
Describe,Context,It,Should,BeforeAll,BeforeEach,AfterAll,AfterEach- Use
-BeTrue/-BeFalsenever-Be $true/-Be $false- Never use
Assert-MockCalled, useShould -Invokeinstead- No
Should -Not -Throw- invoke commands directly- Never add an empty
-MockWithblock- Omit
-MockWithwhen returning$null- Set
$PSDefaultParameterValuesforMock:ModuleName,Should:ModuleName, `...
Files:
tests/Unit/Classes/SqlPermission.Tests.ps1
tests/Unit/Classes/*.[Tt]ests.ps1
📄 CodeRabbit inference engine (.github/instructions/dsc-community-style-guidelines-pester.instructions.md)
Class resources:
tests/Unit/Classes/{Name}.Tests.ps1
Files:
tests/Unit/Classes/SqlPermission.Tests.ps1
tests/[Uu]nit/**/*.[Tt]ests.ps1
📄 CodeRabbit inference engine (.github/instructions/dsc-community-style-guidelines-unit-tests.instructions.md)
tests/[Uu]nit/**/*.[Tt]ests.ps1: Test with localized strings usingInModuleScope -ScriptBlock { $script:localizedData.Key }
Mock files using the$TestDrivevariable (path to the test drive)
All public commands require parameter set validation tests
Use the exact setup block with BeforeDiscovery, BeforeAll, and AfterAll blocks including DscResource.Test module import and PSDefaultParameterValues configuration
Parameter set validation tests should use Get-Command with Where-Object filtering and Should assertions to verify ParameterSetName and ParameterListAsString
Parameter property tests should verify mandatory parameter attributes using Get-Command Parameters and Should -BeTrue assertions
Files:
tests/Unit/Classes/SqlPermission.Tests.ps1
⚙️ CodeRabbit configuration file
tests/[Uu]nit/**/*.[Tt]ests.ps1: # Unit Tests Guidelines
- Test with localized strings: Use
InModuleScope -ScriptBlock { $script:localizedData.Key }- Mock files: Use
$TestDrivevariable (path to the test drive)- All public commands require parameter set validation tests
- After modifying classes, always run tests in new session (for changes to take effect)
Test Setup Requirements
Use this exact setup block before
Describe:[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 noop" first.' } } BeforeAll { $script:moduleName = '{MyModuleName}' Import-Module -Name $script:moduleName -Force -ErrorAction 'Stop' $PSDefaultParameterValues['InModuleScope:ModuleName'] = $script:moduleName $PSDefaultParameterValues['Mock:ModuleName'] = $script:moduleName $PSDefaultParameterValues['Should:ModuleName'] = $script:moduleName } AfterAll { $PSDefaultParameterValues.Remove('InModuleScope:ModuleName') $PSDefaultParameterValues.Remove('Mock:ModuleNam...
Files:
tests/Unit/Classes/SqlPermission.Tests.ps1
tests/Unit/**/*.Tests.ps1
📄 CodeRabbit inference engine (.github/instructions/dsc-community-style-guidelines.instructions.md)
Unit tests should be located in
tests/Unit/{Classes|Public|Private}/{Name}.Tests.ps1
Files:
tests/Unit/Classes/SqlPermission.Tests.ps1
🧠 Learnings (30)
📓 Common learnings
Learnt from: johlju
Repo: dsccommunity/SqlServerDsc PR: 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.
📚 Learning: 2025-11-27T17:58:02.422Z
Learnt from: CR
Repo: dsccommunity/SqlServerDsc PR: 0
File: .github/instructions/SqlServerDsc-guidelines.instructions.md:0-0
Timestamp: 2025-11-27T17:58:02.422Z
Learning: Applies to **/*.ps1 : Format public commands as `{Verb}-SqlDsc{Noun}` following PowerShell naming conventions
Applied to files:
CHANGELOG.md
📚 Learning: 2025-11-22T17:36:09.703Z
Learnt from: johlju
Repo: dsccommunity/SqlServerDsc PR: 2343
File: source/Classes/004.DatabaseFileGroupSpec.ps1:5-34
Timestamp: 2025-11-22T17:36:09.703Z
Learning: The comment-based help requirements for ## Requirements and ## Known issues sections only apply to class-based DSC resources (classes decorated with [DscResource(...)]) in source/Classes/**/*.ps1, not to regular helper classes, DTO classes, or specification classes in the same directory.
Applied to files:
CHANGELOG.md
📚 Learning: 2025-10-03T15:27:24.417Z
Learnt from: Borgquite
Repo: dsccommunity/UpdateServicesDsc PR: 78
File: source/DSCResources/MSFT_UpdateServicesComputerTargetGroup/MSFT_UpdateServicesComputerTargetGroup.psm1:9-22
Timestamp: 2025-10-03T15:27:24.417Z
Learning: In the UpdateServicesDsc repository, MOF-based DSC resources follow a minimal comment-based help convention that includes only .SYNOPSIS and .PARAMETER sections. The .DESCRIPTION, .INPUTS, and .OUTPUTS sections are intentionally omitted, even though functions have [OutputType()] attributes. This is consistent across all existing DSC resources: MSFT_UpdateServicesServer, MSFT_UpdateServicesCleanup, and MSFT_UpdateServicesApprovalRule.
Applied to files:
CHANGELOG.md
📚 Learning: 2025-11-27T17:58:02.422Z
Learnt from: CR
Repo: dsccommunity/SqlServerDsc PR: 0
File: .github/instructions/SqlServerDsc-guidelines.instructions.md:0-0
Timestamp: 2025-11-27T17:58:02.422Z
Learning: Applies to **/tests/Integration/**/*.ps1 : Integration tests: use `Connect-SqlDscDatabaseEngine` for SQL Server DB session with correct CI credentials, and always follow with `Disconnect-SqlDscDatabaseEngine`
Applied to files:
tests/Unit/Classes/SqlPermission.Tests.ps1
📚 Learning: 2025-11-27T17:58:02.422Z
Learnt from: CR
Repo: dsccommunity/SqlServerDsc PR: 0
File: .github/instructions/SqlServerDsc-guidelines.instructions.md:0-0
Timestamp: 2025-11-27T17:58:02.422Z
Learning: Applies to **/tests/**/*.tests.ps1 : When unit tests test classes or commands containing SMO types like `[Microsoft.SqlServer.Management.Smo.*]`, ensure they are properly stubbed in SMO.cs
Applied to files:
tests/Unit/Classes/SqlPermission.Tests.ps1
📚 Learning: 2025-08-17T10:13:30.079Z
Learnt from: johlju
Repo: dsccommunity/SqlServerDsc PR: 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:
tests/Unit/Classes/SqlPermission.Tests.ps1
📚 Learning: 2025-11-27T17:58:02.422Z
Learnt from: CR
Repo: dsccommunity/SqlServerDsc PR: 0
File: .github/instructions/SqlServerDsc-guidelines.instructions.md:0-0
Timestamp: 2025-11-27T17:58:02.422Z
Learning: Applies to **/tests/**/*.tests.ps1 : Add `$env:SqlServerDscCI = $true` in `BeforeAll` block and remove in `AfterAll` block of unit tests
Applied to files:
tests/Unit/Classes/SqlPermission.Tests.ps1
📚 Learning: 2025-11-27T17:58:02.422Z
Learnt from: CR
Repo: dsccommunity/SqlServerDsc PR: 0
File: .github/instructions/SqlServerDsc-guidelines.instructions.md:0-0
Timestamp: 2025-11-27T17:58:02.422Z
Learning: Applies to **/tests/**/*.tests.ps1 : In unit tests: use SMO stub types from SMO.cs, never mock SMO types
Applied to files:
tests/Unit/Classes/SqlPermission.Tests.ps1
📚 Learning: 2025-11-27T17:59:27.205Z
Learnt from: CR
Repo: dsccommunity/SqlServerDsc PR: 0
File: .github/instructions/dsc-community-style-guidelines-pester.instructions.md:0-0
Timestamp: 2025-11-27T17:59:27.205Z
Learning: Applies to **/*.[Tt]ests.ps1 : Mock variables prefix: 'mock'
Applied to files:
tests/Unit/Classes/SqlPermission.Tests.ps1
📚 Learning: 2025-11-27T17:58:02.422Z
Learnt from: CR
Repo: dsccommunity/SqlServerDsc PR: 0
File: .github/instructions/SqlServerDsc-guidelines.instructions.md:0-0
Timestamp: 2025-11-27T17:58:02.422Z
Learning: After changing SMO stub types in SMO.cs, run tests in a new PowerShell session for changes to take effect
Applied to files:
tests/Unit/Classes/SqlPermission.Tests.ps1
📚 Learning: 2025-11-27T17:59:27.205Z
Learnt from: CR
Repo: dsccommunity/SqlServerDsc PR: 0
File: .github/instructions/dsc-community-style-guidelines-pester.instructions.md:0-0
Timestamp: 2025-11-27T17:59:27.205Z
Learning: Applies to tests/Unit/Public/*.[Tt]ests.ps1 : Public commands: `tests/Unit/Public/{Name}.Tests.ps1`
Applied to files:
tests/Unit/Classes/SqlPermission.Tests.ps1
📚 Learning: 2025-11-27T17:59:27.205Z
Learnt from: CR
Repo: dsccommunity/SqlServerDsc PR: 0
File: .github/instructions/dsc-community-style-guidelines-pester.instructions.md:0-0
Timestamp: 2025-11-27T17:59:27.205Z
Learning: Applies to **/*.[Tt]ests.ps1 : Mocking in `BeforeAll` (`BeforeEach` only when required)
Applied to files:
tests/Unit/Classes/SqlPermission.Tests.ps1
📚 Learning: 2025-11-27T17:59:27.205Z
Learnt from: CR
Repo: dsccommunity/SqlServerDsc PR: 0
File: .github/instructions/dsc-community-style-guidelines-pester.instructions.md:0-0
Timestamp: 2025-11-27T17:59:27.205Z
Learning: Applies to **/*.[Tt]ests.ps1 : Set `$PSDefaultParameterValues` for `Mock:ModuleName`, `Should:ModuleName`, `InModuleScope:ModuleName`
Applied to files:
tests/Unit/Classes/SqlPermission.Tests.ps1
📚 Learning: 2025-11-27T18:00:20.934Z
Learnt from: CR
Repo: dsccommunity/SqlServerDsc PR: 0
File: .github/instructions/dsc-community-style-guidelines-unit-tests.instructions.md:0-0
Timestamp: 2025-11-27T18:00:20.934Z
Learning: Applies to tests/[Uu]nit/**/*.[Tt]ests.ps1 : Parameter set validation tests should use Get-Command with Where-Object filtering and Should assertions to verify ParameterSetName and ParameterListAsString
Applied to files:
tests/Unit/Classes/SqlPermission.Tests.ps1
📚 Learning: 2025-11-27T17:59:27.205Z
Learnt from: CR
Repo: dsccommunity/SqlServerDsc PR: 0
File: .github/instructions/dsc-community-style-guidelines-pester.instructions.md:0-0
Timestamp: 2025-11-27T17:59:27.205Z
Learning: Applies to **/*.[Tt]ests.ps1 : Omit `-MockWith` when returning `$null`
Applied to files:
tests/Unit/Classes/SqlPermission.Tests.ps1
📚 Learning: 2025-11-27T17:59:27.205Z
Learnt from: CR
Repo: dsccommunity/SqlServerDsc PR: 0
File: .github/instructions/dsc-community-style-guidelines-pester.instructions.md:0-0
Timestamp: 2025-11-27T17:59:27.205Z
Learning: Applies to **/*.[Tt]ests.ps1 : Never use `Assert-MockCalled`, use `Should -Invoke` instead
Applied to files:
tests/Unit/Classes/SqlPermission.Tests.ps1
📚 Learning: 2025-11-27T17:59:27.205Z
Learnt from: CR
Repo: dsccommunity/SqlServerDsc PR: 0
File: .github/instructions/dsc-community-style-guidelines-pester.instructions.md:0-0
Timestamp: 2025-11-27T17:59:27.205Z
Learning: Applies to **/*.[Tt]ests.ps1 : Never use `param()` inside `-MockWith` scriptblocks, parameters are auto-bound
Applied to files:
tests/Unit/Classes/SqlPermission.Tests.ps1
📚 Learning: 2025-11-27T18:00:20.934Z
Learnt from: CR
Repo: dsccommunity/SqlServerDsc PR: 0
File: .github/instructions/dsc-community-style-guidelines-unit-tests.instructions.md:0-0
Timestamp: 2025-11-27T18:00:20.934Z
Learning: Applies to tests/[Uu]nit/**/*.[Tt]ests.ps1 : Parameter property tests should verify mandatory parameter attributes using Get-Command Parameters and Should -BeTrue assertions
Applied to files:
tests/Unit/Classes/SqlPermission.Tests.ps1
📚 Learning: 2025-11-27T18:00:35.078Z
Learnt from: CR
Repo: dsccommunity/SqlServerDsc PR: 0
File: .github/instructions/dsc-community-style-guidelines.instructions.md:0-0
Timestamp: 2025-11-27T18:00:35.078Z
Learning: Follow PowerShell style and test guideline instructions strictly
Applied to files:
tests/Unit/Classes/SqlPermission.Tests.ps1
📚 Learning: 2025-11-27T17:58:31.910Z
Learnt from: CR
Repo: dsccommunity/SqlServerDsc PR: 0
File: .github/instructions/dsc-community-style-guidelines-integration-tests.instructions.md:0-0
Timestamp: 2025-11-27T17:58:31.910Z
Learning: Applies to tests/Integration/**/*.Integration.Tests.ps1 : Call commands with `-Force` parameter where applicable to avoid prompting
Applied to files:
tests/Unit/Classes/SqlPermission.Tests.ps1
📚 Learning: 2025-11-27T17:59:27.205Z
Learnt from: CR
Repo: dsccommunity/SqlServerDsc PR: 0
File: .github/instructions/dsc-community-style-guidelines-pester.instructions.md:0-0
Timestamp: 2025-11-27T17:59:27.205Z
Learning: Applies to **/*.[Tt]ests.ps1 : No `Should -Not -Throw` - invoke commands directly
Applied to files:
tests/Unit/Classes/SqlPermission.Tests.ps1
📚 Learning: 2025-08-16T13:22:15.230Z
Learnt from: johlju
Repo: dsccommunity/SqlServerDsc PR: 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/SqlPermission.Tests.ps1
📚 Learning: 2025-11-27T18:00:20.934Z
Learnt from: CR
Repo: dsccommunity/SqlServerDsc PR: 0
File: .github/instructions/dsc-community-style-guidelines-unit-tests.instructions.md:0-0
Timestamp: 2025-11-27T18:00:20.934Z
Learning: Applies to tests/[Uu]nit/**/*.[Tt]ests.ps1 : All public commands require parameter set validation tests
Applied to files:
tests/Unit/Classes/SqlPermission.Tests.ps1
📚 Learning: 2025-12-04T17:07:00.169Z
Learnt from: CR
Repo: dsccommunity/SqlServerDsc PR: 0
File: .github/instructions/dsc-community-style-guidelines-powershell.instructions.md:0-0
Timestamp: 2025-12-04T17:07:00.169Z
Learning: Applies to **/*.{ps1,psm1,psd1} : Place ShouldProcess check immediately before each state-change operation
Applied to files:
tests/Unit/Classes/SqlPermission.Tests.ps1
📚 Learning: 2025-11-27T17:59:27.205Z
Learnt from: CR
Repo: dsccommunity/SqlServerDsc PR: 0
File: .github/instructions/dsc-community-style-guidelines-pester.instructions.md:0-0
Timestamp: 2025-11-27T17:59:27.205Z
Learning: Applies to **/*.[Tt]ests.ps1 : Each scenario = separate `Context` block
Applied to files:
tests/Unit/Classes/SqlPermission.Tests.ps1
📚 Learning: 2025-11-27T17:59:27.205Z
Learnt from: CR
Repo: dsccommunity/SqlServerDsc PR: 0
File: .github/instructions/dsc-community-style-guidelines-pester.instructions.md:0-0
Timestamp: 2025-11-27T17:59:27.205Z
Learning: Applies to **/*.[Tt]ests.ps1 : Use nested `Context` blocks for complex scenarios
Applied to files:
tests/Unit/Classes/SqlPermission.Tests.ps1
📚 Learning: 2025-08-17T10:15:48.194Z
Learnt from: johlju
Repo: dsccommunity/SqlServerDsc PR: 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/SqlPermission.Tests.ps1
📚 Learning: 2025-11-27T17:59:27.205Z
Learnt from: CR
Repo: dsccommunity/SqlServerDsc PR: 0
File: .github/instructions/dsc-community-style-guidelines-pester.instructions.md:0-0
Timestamp: 2025-11-27T17:59:27.205Z
Learning: Applies to **/*.[Tt]ests.ps1 : Never use `Mock` inside `InModuleScope`-block
Applied to files:
tests/Unit/Classes/SqlPermission.Tests.ps1
📚 Learning: 2025-11-27T17:59:27.205Z
Learnt from: CR
Repo: dsccommunity/SqlServerDsc PR: 0
File: .github/instructions/dsc-community-style-guidelines-pester.instructions.md:0-0
Timestamp: 2025-11-27T17:59:27.205Z
Learning: Applies to **/*.[Tt]ests.ps1 : Never add an empty `-MockWith` block
Applied to files:
tests/Unit/Classes/SqlPermission.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
🔇 Additional comments (5)
CHANGELOG.md (1)
24-29: Changelog entry reads well; confirm if Test-SqlDscServerPermission should be noted.Formatting, wrapping, and issue reference comply with the repository’s CHANGELOG style. If the resource also calls
Test-SqlDscServerPermissionduring its Test phase, consider adding it to the listed commands for completeness; otherwise, no change needed.tests/Unit/Classes/SqlPermission.Tests.ps1 (2)
1150-1159: Good use of Get-SqlDscLogin and new Grant/Deny/Revoke mocksThe new mocks for
Get-SqlDscLoginand theGrant-/Deny-/Revoke-SqlDscServerPermissioncommands are wired correctly and align with the new object-based API. They also respect the guideline of using SMO stubs rather than mocking SMO types directly, and keepMockcalls outsideInModuleScope.Also applies to: 1246-1255, 1354-1363, 1452-1461
1497-1565: Failure-path tests for Grant/Revoke are well structuredThe new contexts for command failures (
When Grant/Deny/Revoke commands fail to change permission) correctly:
- Mock each of
Grant-/Deny-/Revoke-SqlDscServerPermissionto throw.- Use localized messages (
FailedToSetPermission,FailedToRevokePermissionFromCurrentState) andGet-InvalidOperationRecordto create expected error records.- Assert with
Should -Throw -ExpectedMessageagainst the localized error, independent of the underlying exception text.This gives solid coverage of the new error-handling branches in
Modify().Also applies to: 1602-1669
source/Classes/020.SqlPermission.ps1 (2)
468-505: Revoke logic with Revoke-SqlDscServerPermission and WithGrant handling looks soundThe refactored revoke path:
- Aggregates permissions per state into
ServerPermissionobjects.- Converts each to a
Permissionarray and skips calls when the array is empty.- Adds
WithGrant = $trueonly forState -eq 'GrantWithGrant'.- Invokes
Revoke-SqlDscServerPermissionwith either-Login $principalObjector-ServerRole $principalObject, plusForce = $true.- Wraps each call in a
try/catchand surfaces a localizedFailedToRevokePermissionFromCurrentStateviaNew-InvalidOperationException.This matches the expected semantics of revoking extra grants/denies and gives clear, localized failure reporting.
520-577: Grant/Deny logic correctly maps states to new cmdlets and preserves error semanticsThe updated grant/deny section:
- Converts each
ServerPermission’sPermissionlist intopermissionsArray.- For
'Grant'and'GrantWithGrant', callsGrant-SqlDscServerPermissionwithPermission,Force = $true, andWithGrant = $trueonly forGrantWithGrant.- For
'Deny', callsDeny-SqlDscServerPermissionwithPermissionandForce = $true.- Always targets either
-Loginor-ServerRolebased onisLogin.- On any failure, wraps the underlying error into a localized
FailedToSetPermissionviaNew-InvalidOperationException.This preserves the previous behavior with
Set-SqlDscServerPermissionwhile aligning with the new object-based cmdlets and class error-handling guidelines. Unit tests added in the PR exercise the Grant/GrantWithGrant branches and the failure paths.
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #2360 +/- ##
====================================
Coverage 94% 94%
====================================
Files 166 166
Lines 9764 9778 +14
====================================
+ Hits 9205 9219 +14
Misses 559 559
🚀 New features to boost your workflow:
|
There was a problem hiding this comment.
Actionable comments posted: 0
🧹 Nitpick comments (1)
tests/Unit/Classes/SqlPermission.Tests.ps1 (1)
1252-1268: Consider addingTest-SqlDscIsRolemock for test robustness.While
Test-SqlDscIsLoginis mocked to return$true, the production code also callsTest-SqlDscIsRole(line 363 in the class). Without a mock, the real function is called which may introduce test fragility.Add a mock for
Test-SqlDscIsRolereturning$falseto make the test self-contained:Mock -CommandName Test-SqlDscIsLogin -MockWith { return $true } + +Mock -CommandName Test-SqlDscIsRole -MockWith { + return $false +}This pattern should be applied to all
Modify()test contexts where onlyTest-SqlDscIsLoginis mocked.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (3)
source/Classes/020.SqlPermission.ps1(4 hunks)source/en-US/SqlPermission.strings.psd1(1 hunks)tests/Unit/Classes/SqlPermission.Tests.ps1(12 hunks)
🧰 Additional context used
📓 Path-based instructions (16)
source/en-US/*.strings.psd1
📄 CodeRabbit inference engine (.github/instructions/dsc-community-style-guidelines-localization.instructions.md)
source/en-US/*.strings.psd1: Store command/function localized strings in source/en-US/{MyModuleName}.strings.psd1 files
Store class resource localized strings in source/en-US/{ResourceClassName}.strings.psd1 files
Use Key Naming Pattern format: Verb_FunctionName_Action with underscore separators (e.g., Get_Database_ConnectingToDatabase)
Format localized strings using ConvertFrom-StringData with placeholder syntax: KeyName = Message with {0} placeholder. (PREFIX0001)
Prefix string IDs with an acronym derived from the first letter of each word in the class or function name (e.g., SqlSetup → SS, Get-SqlDscDatabase → GSDD), followed by sequential numbers starting from 0001
Files:
source/en-US/SqlPermission.strings.psd1
**/*.{ps1,psm1,psd1}
📄 CodeRabbit inference engine (.github/instructions/dsc-community-style-guidelines-powershell.instructions.md)
**/*.{ps1,psm1,psd1}: Use descriptive names with 3+ characters and no abbreviations for functions, parameters, variables, keywords, and classes
Use PascalCase with Verb-Noun format for function names, using approved PowerShell verbs
Use PascalCase for parameter names
Use camelCase for variable names
Use lower-case for keywords
Use PascalCase for class names
Include scope for script/global/environment variables using$script:,$global:, or$env:prefixes
Use 4 spaces for indentation, not tabs
Use one space around operators (e.g.,$a = 1 + 2)
Use one space between type and variable (e.g.,[String] $name)
Use one space between keyword and parenthesis (e.g.,if ($condition))
Avoid spaces on empty lines
Limit lines to 120 characters
Place opening brace on a new line, except for variable assignments
Add one newline after opening brace
Add two newlines after closing brace (one if followed by another brace or continuation)
Use single quotes unless variable expansion is needed (e.g.,'text'vs"text $variable")
Use single-line array syntax for simple arrays:@('one', 'two', 'three')
Use multi-line array syntax with each element on a separate line with proper indentation
Do not use the unary comma operator (,) in return statements to force an array
Use empty hashtable syntax:@{}
Place each hashtable property on a separate line with proper indentation
Use PascalCase for hashtable properties
Use single-line comment format# Comment(capitalized, on own line)
Use multi-line comment format<# Comment #>with opening and closing brackets on own lines and indented text
Never include commented-out code
Always add comment-based help to all functions and scripts with SYNOPSIS, DESCRIPTION (40+ chars), PARAMETER, and EXAMPLE sections before function/class declaration
Use comment-based help indentation with keywords at 4 spaces and text at 8 spaces
Include examples in comment-based help for all parameter sets and combinations
In comment-based help INPUTS sec...
Files:
source/en-US/SqlPermission.strings.psd1source/Classes/020.SqlPermission.ps1tests/Unit/Classes/SqlPermission.Tests.ps1
**/*.psd1
📄 CodeRabbit inference engine (.github/instructions/dsc-community-style-guidelines-powershell.instructions.md)
Do not use
NestedModulesfor shared commands withoutRootModule
Files:
source/en-US/SqlPermission.strings.psd1
**
⚙️ CodeRabbit configuration file
**: # DSC Community GuidelinesTerminology
- Command: Public command
- Function: Private function
- Resource: DSC class-based resource
Build & Test Workflow Requirements
- Run PowerShell script files from repository root
- Setup build and test environment (once per
pwshsession):./build.ps1 -Tasks noop- Build project before running tests:
./build.ps1 -Tasks build- Always run tests in new
pwshsession:Invoke-Pester -Path @({test paths}) -Output DetailedFile Organization
- Public commands:
source/Public/{CommandName}.ps1- Private functions:
source/Private/{FunctionName}.ps1- Classes:
source/Classes/{DependencyGroupNumber}.{ClassName}.ps1- Enums:
source/Enum/{DependencyGroupNumber}.{EnumName}.ps1- Unit tests:
tests/Unit/{Classes|Public|Private}/{Name}.Tests.ps1- Integration tests:
tests/Integration/Commands/{CommandName}.Integration.Tests.ps1Requirements
- Follow instructions over existing code patterns
- Follow PowerShell style and test guideline instructions strictly
- 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
- DSC resources should always be created as class-based resources
- Add unit tests for all commands/functions/resources
- Add integration tests for all public commands and resources
Files:
source/en-US/SqlPermission.strings.psd1source/Classes/020.SqlPermission.ps1tests/Unit/Classes/SqlPermission.Tests.ps1
{**/*.ps1,**/*.psm1,**/*.psd1}
⚙️ CodeRabbit configuration file
{**/*.ps1,**/*.psm1,**/*.psd1}: # PowerShell GuidelinesNaming
- 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.ps1format (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 arrayHashtables
- Empty:
@{}- 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 as inline code with a 1‑line description...
Files:
source/en-US/SqlPermission.strings.psd1source/Classes/020.SqlPermission.ps1tests/Unit/Classes/SqlPermission.Tests.ps1
**/*.ps1
📄 CodeRabbit inference engine (.github/instructions/SqlServerDsc-guidelines.instructions.md)
**/*.ps1: Format public commands as{Verb}-SqlDsc{Noun}following PowerShell naming conventions
Format private functions as{Verb}-{Noun}following PowerShell naming conventions
Files:
source/Classes/020.SqlPermission.ps1tests/Unit/Classes/SqlPermission.Tests.ps1
source/[cC]lasses/020.*.ps1
📄 CodeRabbit inference engine (.github/instructions/dsc-community-style-guidelines-class-resource.instructions.md)
DSC class-based resources must use the file naming pattern
source/Classes/020.{ResourceName}.ps1
Files:
source/Classes/020.SqlPermission.ps1
source/[cC]lasses/**/*.ps1
📄 CodeRabbit inference engine (.github/instructions/dsc-community-style-guidelines-class-resource.instructions.md)
source/[cC]lasses/**/*.ps1: DSC class-based resources must be decorated with[DscResource(RunAsCredential = 'Optional')]or[DscResource(RunAsCredential = 'Mandatory')]based on requirements
DSC class-based resources must inherit fromResourceBaseclass from the DscResource.Base module
DSC class-based resources must use[Nullable[{FullTypeName}]]syntax for value-type properties (e.g.,[Nullable[System.Int32]])
DSC class-based resources must implement a required constructor with signatureResourceName () : base ($PSScriptRoot)and populate$this.ExcludeDscPropertiesarray
DSC class-based resources must implement required methods:Get(),Test(),Set(),GetCurrentState(), andModify()following the specified pattern
DSC class-based resources may optionally implement methods:AssertProperties()andNormalizeProperties()following the specified pattern
DSC class-based resources must include comment-based help with .DESCRIPTION section containing Requirements and Known issues sections with a link to all open issues on GitHub
DSC class-based resources must usetry/catchblocks for exception handling in classes
DSC class-based resources must useNew-*Exceptioncommands (such asNew-InvalidDataException,New-ArgumentException,New-InvalidOperationException,New-ObjectNotFoundException,New-InvalidResultException,New-NotImplementedException) instead ofthrowfor terminating errors in classes
Files:
source/Classes/020.SqlPermission.ps1
⚙️ CodeRabbit configuration file
source/[cC]lasses/**/*.ps1: # DSC Class-Based Resource GuidelinesApplies 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.localizedDatahashtable auto-populated byResourceBasefrom localization file- value-type properties: Use
[Nullable[{FullTypeName}]](e.g.,[Nullable[System.Int32]])Required constructor
MyResourceName () : base ($PSScriptRoot) { # Property names where state cannot be enforced, e.g. IsSingleInstance, Force $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, $p...
Files:
source/Classes/020.SqlPermission.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 in PowerShell scripts
Use localized string keys from $script:localizedData, not hardcoded strings, in diagnostic messages
Reference localized strings using the syntax: Write-Verbose -Message ($script:localizedData.KeyName -f $value1)Localize all strings using string keys; remove any orphaned string keys
Files:
source/Classes/020.SqlPermission.ps1
⚙️ CodeRabbit configuration file
source/**/*.ps1: # Localization GuidelinesRequirements
- Localize all Write-Debug, Write-Verbose, Write-Error, Write-Warning and $PSCmdlet.ThrowTerminatingError() messages
- Use localized string keys, not hardcoded strings
- Assume
$script:localizedDatais availableString Files
- Commands/functions:
source/en-US/{MyModuleName}.strings.psd1- Class resources:
source/en-US/{ResourceClassName}.strings.psd1Key Naming Patterns
- Format:
Verb_FunctionName_Action(underscore separators), e.g.Get_Database_ConnectingToDatabaseString 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.SqlPermission.ps1
source/Classes/*.ps1
📄 CodeRabbit inference engine (.github/instructions/dsc-community-style-guidelines.instructions.md)
source/Classes/*.ps1: Classes should be located insource/Classes/{DependencyGroupNumber}.{ClassName}.ps1
DSC resources should always be created as class-based resources
Files:
source/Classes/020.SqlPermission.ps1
**/[0-9][0-9][0-9].*.ps1
📄 CodeRabbit inference engine (.github/instructions/dsc-community-style-guidelines-powershell.instructions.md)
Name class files using
###.ClassName.ps1format (e.g.,001.SqlReason.ps1,004.StartupParameters.ps1)
Files:
source/Classes/020.SqlPermission.ps1
**/*.{ps1,psm1}
📄 CodeRabbit inference engine (.github/instructions/dsc-community-style-guidelines-powershell.instructions.md)
Use
$PSCmdlet.ThrowTerminatingError()for terminating errors (except in classes), use relevant error category, and in try-catch include exception with localized message
Files:
source/Classes/020.SqlPermission.ps1tests/Unit/Classes/SqlPermission.Tests.ps1
**/*.[Tt]ests.ps1
📄 CodeRabbit inference engine (.github/instructions/dsc-community-style-guidelines-pester.instructions.md)
**/*.[Tt]ests.ps1: 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
Test code only insideDescribeblocks
Assertions only inItblocks
Never test verbose messages, debug messages or parameter binding behavior
Pass all mandatory parameters to avoid prompts
InsideItblocks, assign unused return objects to$null(unless part of pipeline)
Tested entity must be called from within theItblocks
Keep results and assertions in sameItblock
Avoid try-catch-finally for cleanup, useAfterAllorAfterEach
Avoid unnecessary remove/recreate cycles
OneDescribeblock per file matching the tested entity name
Contextdescriptions start with 'When'
Itdescriptions start with 'Should', must not contain 'when'
Mock variables prefix: 'mock'
Public commands: Never useInModuleScope(unless retrieving localized strings or creating an object using an internal class)
Private functions/class resources: Always useInModuleScope
Each class method = separateContextblock
Each scenario = separateContextblock
Use nestedContextblocks for complex scenarios
Mocking inBeforeAll(BeforeEachonly when required)
Setup/teardown inBeforeAll,BeforeEach/AfterAll,AfterEachclose to usage
Spacing between blocks, arrange, act, and assert for readability
PascalCase:Describe,Context,It,Should,BeforeAll,BeforeEach,AfterAll,AfterEach
Use-BeTrue/-BeFalsenever-Be $true/-Be $false
Never useAssert-MockCalled, useShould -Invokeinstead
NoShould -Not -Throw- invoke commands directly
Never add an empty-MockWithblock
Omit-MockWithwhen returning$null
Set$PSDefaultParameterValuesforMock:ModuleName,Should:ModuleName,InModuleScope:ModuleName
Omit-ModuleNameparameter on Pester commands
Never useMockinsideInModuleScope-block
Never useparam()inside-MockWithscriptblock...
Files:
tests/Unit/Classes/SqlPermission.Tests.ps1
⚙️ CodeRabbit configuration file
**/*.[Tt]ests.ps1: # Tests GuidelinesCore 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
- Test code only inside
Describeblocks- Assertions only in
Itblocks- Never test verbose messages, debug messages or parameter binding behavior
- Pass all mandatory parameters to avoid prompts
Requirements
- Inside
Itblocks, assign unused return objects to$null(unless part of pipeline)- Tested entity must be called from within the
Itblocks- Keep results and assertions in same
Itblock- Avoid try-catch-finally for cleanup, use
AfterAllorAfterEach- Avoid unnecessary remove/recreate cycles
Naming
- One
Describeblock per file matching the tested entity nameContextdescriptions start with 'When'Itdescriptions start with 'Should', must not contain 'when'- Mock variables prefix: 'mock'
Structure & Scope
- Public commands: Never use
InModuleScope(unless retrieving localized strings or creating an object using an internal class)- Private functions/class resources: Always use
InModuleScope- Each class method = separate
Contextblock- Each scenario = separate
Contextblock- Use nested
Contextblocks for complex scenarios- Mocking in
BeforeAll(BeforeEachonly when required)- Setup/teardown in
BeforeAll,BeforeEach/AfterAll,AfterEachclose to usage- Spacing between blocks, arrange, act, and assert for readability
Syntax Rules
- PascalCase:
Describe,Context,It,Should,BeforeAll,BeforeEach,AfterAll,AfterEach- Use
-BeTrue/-BeFalsenever-Be $true/-Be $false- Never use
Assert-MockCalled, useShould -Invokeinstead- No
Should -Not -Throw- invoke commands directly- Never add an empty
-MockWithblock- Omit
-MockWithwhen returning$null- Set
$PSDefaultParameterValuesforMock:ModuleName,Should:ModuleName, `...
Files:
tests/Unit/Classes/SqlPermission.Tests.ps1
tests/Unit/Classes/*.[Tt]ests.ps1
📄 CodeRabbit inference engine (.github/instructions/dsc-community-style-guidelines-pester.instructions.md)
Class resources:
tests/Unit/Classes/{Name}.Tests.ps1
Files:
tests/Unit/Classes/SqlPermission.Tests.ps1
tests/[Uu]nit/**/*.[Tt]ests.ps1
📄 CodeRabbit inference engine (.github/instructions/dsc-community-style-guidelines-unit-tests.instructions.md)
tests/[Uu]nit/**/*.[Tt]ests.ps1: Test with localized strings usingInModuleScope -ScriptBlock { $script:localizedData.Key }
Mock files using the$TestDrivevariable (path to the test drive)
All public commands require parameter set validation tests
Use the exact setup block with BeforeDiscovery, BeforeAll, and AfterAll blocks including DscResource.Test module import and PSDefaultParameterValues configuration
Parameter set validation tests should use Get-Command with Where-Object filtering and Should assertions to verify ParameterSetName and ParameterListAsString
Parameter property tests should verify mandatory parameter attributes using Get-Command Parameters and Should -BeTrue assertions
Files:
tests/Unit/Classes/SqlPermission.Tests.ps1
⚙️ CodeRabbit configuration file
tests/[Uu]nit/**/*.[Tt]ests.ps1: # Unit Tests Guidelines
- Test with localized strings: Use
InModuleScope -ScriptBlock { $script:localizedData.Key }- Mock files: Use
$TestDrivevariable (path to the test drive)- All public commands require parameter set validation tests
- After modifying classes, always run tests in new session (for changes to take effect)
Test Setup Requirements
Use this exact setup block before
Describe:[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 noop" first.' } } BeforeAll { $script:moduleName = '{MyModuleName}' Import-Module -Name $script:moduleName -Force -ErrorAction 'Stop' $PSDefaultParameterValues['InModuleScope:ModuleName'] = $script:moduleName $PSDefaultParameterValues['Mock:ModuleName'] = $script:moduleName $PSDefaultParameterValues['Should:ModuleName'] = $script:moduleName } AfterAll { $PSDefaultParameterValues.Remove('InModuleScope:ModuleName') $PSDefaultParameterValues.Remove('Mock:ModuleNam...
Files:
tests/Unit/Classes/SqlPermission.Tests.ps1
tests/Unit/**/*.Tests.ps1
📄 CodeRabbit inference engine (.github/instructions/dsc-community-style-guidelines.instructions.md)
Unit tests should be located in
tests/Unit/{Classes|Public|Private}/{Name}.Tests.ps1
Files:
tests/Unit/Classes/SqlPermission.Tests.ps1
🧠 Learnings (37)
📓 Common learnings
Learnt from: johlju
Repo: dsccommunity/SqlServerDsc PR: 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.
Learnt from: CR
Repo: dsccommunity/SqlServerDsc PR: 0
File: .github/instructions/SqlServerDsc-guidelines.instructions.md:0-0
Timestamp: 2025-11-27T17:58:02.422Z
Learning: Applies to **/tests/Integration/**/*.ps1 : Integration tests: use `Connect-SqlDscDatabaseEngine` for SQL Server DB session with correct CI credentials, and always follow with `Disconnect-SqlDscDatabaseEngine`
Learnt from: CR
Repo: dsccommunity/SqlServerDsc PR: 0
File: .github/instructions/SqlServerDsc-guidelines.instructions.md:0-0
Timestamp: 2025-11-27T17:58:02.422Z
Learning: Applies to **/*.ps1 : Format public commands as `{Verb}-SqlDsc{Noun}` following PowerShell naming conventions
Learnt from: johlju
Repo: dsccommunity/SqlServerDsc PR: 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.
📚 Learning: 2025-11-27T17:58:42.327Z
Learnt from: CR
Repo: dsccommunity/SqlServerDsc PR: 0
File: .github/instructions/dsc-community-style-guidelines-localization.instructions.md:0-0
Timestamp: 2025-11-27T17:58:42.327Z
Learning: Applies to source/en-US/*.strings.psd1 : Prefix string IDs with an acronym derived from the first letter of each word in the class or function name (e.g., SqlSetup → SS, Get-SqlDscDatabase → GSDD), followed by sequential numbers starting from 0001
Applied to files:
source/en-US/SqlPermission.strings.psd1
📚 Learning: 2025-11-27T17:58:42.327Z
Learnt from: CR
Repo: dsccommunity/SqlServerDsc PR: 0
File: .github/instructions/dsc-community-style-guidelines-localization.instructions.md:0-0
Timestamp: 2025-11-27T17:58:42.327Z
Learning: Applies to source/en-US/*.strings.psd1 : Store class resource localized strings in source/en-US/{ResourceClassName}.strings.psd1 files
Applied to files:
source/en-US/SqlPermission.strings.psd1
📚 Learning: 2025-11-27T17:58:42.327Z
Learnt from: CR
Repo: dsccommunity/SqlServerDsc PR: 0
File: .github/instructions/dsc-community-style-guidelines-localization.instructions.md:0-0
Timestamp: 2025-11-27T17:58:42.327Z
Learning: Applies to source/en-US/*.strings.psd1 : Use Key Naming Pattern format: Verb_FunctionName_Action with underscore separators (e.g., Get_Database_ConnectingToDatabase)
Applied to files:
source/en-US/SqlPermission.strings.psd1
📚 Learning: 2025-11-27T17:59:01.508Z
Learnt from: CR
Repo: dsccommunity/SqlServerDsc PR: 0
File: .github/instructions/dsc-community-style-guidelines-mof-resources.instructions.md:0-0
Timestamp: 2025-11-27T17:59:01.508Z
Learning: Applies to source/DSCResources/**/en-US/DSC_*.strings.psd1 : Name localized strings file as `DSC_<ResourceName>.strings.psd1` in the `en-US` folder
Applied to files:
source/en-US/SqlPermission.strings.psd1
📚 Learning: 2025-11-27T17:58:42.327Z
Learnt from: CR
Repo: dsccommunity/SqlServerDsc PR: 0
File: .github/instructions/dsc-community-style-guidelines-localization.instructions.md:0-0
Timestamp: 2025-11-27T17:58:42.327Z
Learning: Applies to source/en-US/*.strings.psd1 : Store command/function localized strings in source/en-US/{MyModuleName}.strings.psd1 files
Applied to files:
source/en-US/SqlPermission.strings.psd1
📚 Learning: 2025-11-27T17:59:01.508Z
Learnt from: CR
Repo: dsccommunity/SqlServerDsc PR: 0
File: .github/instructions/dsc-community-style-guidelines-mof-resources.instructions.md:0-0
Timestamp: 2025-11-27T17:59:01.508Z
Learning: Applies to source/DSCResources/**/en-US/DSC_*.strings.psd1 : In `.strings.psd1` files, use underscores as word separators in localized string key names for multi-word keys
Applied to files:
source/en-US/SqlPermission.strings.psd1
📚 Learning: 2025-11-27T17:58:02.422Z
Learnt from: CR
Repo: dsccommunity/SqlServerDsc PR: 0
File: .github/instructions/SqlServerDsc-guidelines.instructions.md:0-0
Timestamp: 2025-11-27T17:58:02.422Z
Learning: Applies to **/resources/**/*.ps1 : Add `InstanceName`, `ServerName`, and `Credential` to `$this.ExcludeDscProperties` in Database Engine resources
Applied to files:
source/en-US/SqlPermission.strings.psd1
📚 Learning: 2025-11-27T17:58:02.422Z
Learnt from: CR
Repo: dsccommunity/SqlServerDsc PR: 0
File: .github/instructions/SqlServerDsc-guidelines.instructions.md:0-0
Timestamp: 2025-11-27T17:58:02.422Z
Learning: Applies to **/resources/**/*.ps1 : Database Engine resources must inherit from `SqlResourceBase`
Applied to files:
source/en-US/SqlPermission.strings.psd1
📚 Learning: 2025-10-04T21:33:23.022Z
Learnt from: dan-hughes
Repo: dsccommunity/UpdateServicesDsc PR: 85
File: source/en-US/UpdateServicesDsc.strings.psd1:1-2
Timestamp: 2025-10-04T21:33:23.022Z
Learning: In UpdateServicesDsc (and similar DSC modules), the module-level localization file (source/en-US/<ModuleName>.strings.psd1) can be empty when DSC resources have their own localization files in source/DSCResources/<ResourceName>/en-US/DSC_<ResourceName>.strings.psd1. Automated tests verify localization completeness for resources. Don't flag empty module-level localization files as issues when resources have separate localization.
Applied to files:
source/en-US/SqlPermission.strings.psd1
📚 Learning: 2025-11-27T17:58:02.422Z
Learnt from: CR
Repo: dsccommunity/SqlServerDsc PR: 0
File: .github/instructions/SqlServerDsc-guidelines.instructions.md:0-0
Timestamp: 2025-11-27T17:58:02.422Z
Learning: Applies to **/tests/Integration/**/*.ps1 : Integration tests: use `Connect-SqlDscDatabaseEngine` for SQL Server DB session with correct CI credentials, and always follow with `Disconnect-SqlDscDatabaseEngine`
Applied to files:
source/Classes/020.SqlPermission.ps1tests/Unit/Classes/SqlPermission.Tests.ps1
📚 Learning: 2025-08-17T10:13:30.079Z
Learnt from: johlju
Repo: dsccommunity/SqlServerDsc PR: 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:
source/Classes/020.SqlPermission.ps1tests/Unit/Classes/SqlPermission.Tests.ps1
📚 Learning: 2025-11-27T17:58:02.422Z
Learnt from: CR
Repo: dsccommunity/SqlServerDsc PR: 0
File: .github/instructions/SqlServerDsc-guidelines.instructions.md:0-0
Timestamp: 2025-11-27T17:58:02.422Z
Learning: Applies to **/tests/**/*.tests.ps1 : When unit tests test classes or commands containing SMO types like `[Microsoft.SqlServer.Management.Smo.*]`, ensure they are properly stubbed in SMO.cs
Applied to files:
tests/Unit/Classes/SqlPermission.Tests.ps1
📚 Learning: 2025-11-27T17:58:02.422Z
Learnt from: CR
Repo: dsccommunity/SqlServerDsc PR: 0
File: .github/instructions/SqlServerDsc-guidelines.instructions.md:0-0
Timestamp: 2025-11-27T17:58:02.422Z
Learning: Applies to **/tests/**/*.tests.ps1 : In unit tests: use SMO stub types from SMO.cs, never mock SMO types
Applied to files:
tests/Unit/Classes/SqlPermission.Tests.ps1
📚 Learning: 2025-11-27T17:58:02.422Z
Learnt from: CR
Repo: dsccommunity/SqlServerDsc PR: 0
File: .github/instructions/SqlServerDsc-guidelines.instructions.md:0-0
Timestamp: 2025-11-27T17:58:02.422Z
Learning: Applies to **/tests/**/*.tests.ps1 : Add `$env:SqlServerDscCI = $true` in `BeforeAll` block and remove in `AfterAll` block of unit tests
Applied to files:
tests/Unit/Classes/SqlPermission.Tests.ps1
📚 Learning: 2025-11-27T17:59:27.205Z
Learnt from: CR
Repo: dsccommunity/SqlServerDsc PR: 0
File: .github/instructions/dsc-community-style-guidelines-pester.instructions.md:0-0
Timestamp: 2025-11-27T17:59:27.205Z
Learning: Applies to **/*.[Tt]ests.ps1 : Mock variables prefix: 'mock'
Applied to files:
tests/Unit/Classes/SqlPermission.Tests.ps1
📚 Learning: 2025-11-27T17:59:27.205Z
Learnt from: CR
Repo: dsccommunity/SqlServerDsc PR: 0
File: .github/instructions/dsc-community-style-guidelines-pester.instructions.md:0-0
Timestamp: 2025-11-27T17:59:27.205Z
Learning: Applies to **/*.[Tt]ests.ps1 : Mocking in `BeforeAll` (`BeforeEach` only when required)
Applied to files:
tests/Unit/Classes/SqlPermission.Tests.ps1
📚 Learning: 2025-11-27T17:58:02.422Z
Learnt from: CR
Repo: dsccommunity/SqlServerDsc PR: 0
File: .github/instructions/SqlServerDsc-guidelines.instructions.md:0-0
Timestamp: 2025-11-27T17:58:02.422Z
Learning: After changing SMO stub types in SMO.cs, run tests in a new PowerShell session for changes to take effect
Applied to files:
tests/Unit/Classes/SqlPermission.Tests.ps1
📚 Learning: 2025-11-27T17:59:27.205Z
Learnt from: CR
Repo: dsccommunity/SqlServerDsc PR: 0
File: .github/instructions/dsc-community-style-guidelines-pester.instructions.md:0-0
Timestamp: 2025-11-27T17:59:27.205Z
Learning: Applies to **/*.[Tt]ests.ps1 : Set `$PSDefaultParameterValues` for `Mock:ModuleName`, `Should:ModuleName`, `InModuleScope:ModuleName`
Applied to files:
tests/Unit/Classes/SqlPermission.Tests.ps1
📚 Learning: 2025-11-27T17:59:27.205Z
Learnt from: CR
Repo: dsccommunity/SqlServerDsc PR: 0
File: .github/instructions/dsc-community-style-guidelines-pester.instructions.md:0-0
Timestamp: 2025-11-27T17:59:27.205Z
Learning: Applies to **/*.[Tt]ests.ps1 : Never use `Mock` inside `InModuleScope`-block
Applied to files:
tests/Unit/Classes/SqlPermission.Tests.ps1
📚 Learning: 2025-11-27T17:59:27.205Z
Learnt from: CR
Repo: dsccommunity/SqlServerDsc PR: 0
File: .github/instructions/dsc-community-style-guidelines-pester.instructions.md:0-0
Timestamp: 2025-11-27T17:59:27.205Z
Learning: Applies to **/*.[Tt]ests.ps1 : No `Should -Not -Throw` - invoke commands directly
Applied to files:
tests/Unit/Classes/SqlPermission.Tests.ps1
📚 Learning: 2025-11-27T17:59:27.205Z
Learnt from: CR
Repo: dsccommunity/SqlServerDsc PR: 0
File: .github/instructions/dsc-community-style-guidelines-pester.instructions.md:0-0
Timestamp: 2025-11-27T17:59:27.205Z
Learning: Applies to **/*.[Tt]ests.ps1 : Never use `Assert-MockCalled`, use `Should -Invoke` instead
Applied to files:
tests/Unit/Classes/SqlPermission.Tests.ps1
📚 Learning: 2025-11-27T17:58:31.910Z
Learnt from: CR
Repo: dsccommunity/SqlServerDsc PR: 0
File: .github/instructions/dsc-community-style-guidelines-integration-tests.instructions.md:0-0
Timestamp: 2025-11-27T17:58:31.910Z
Learning: Applies to tests/Integration/**/*.Integration.Tests.ps1 : Avoid `ExpectedMessage` parameter for `Should -Throw` assertions in integration tests
Applied to files:
tests/Unit/Classes/SqlPermission.Tests.ps1
📚 Learning: 2025-11-27T17:59:27.205Z
Learnt from: CR
Repo: dsccommunity/SqlServerDsc PR: 0
File: .github/instructions/dsc-community-style-guidelines-pester.instructions.md:0-0
Timestamp: 2025-11-27T17:59:27.205Z
Learning: Applies to **/*.[Tt]ests.ps1 : Never add an empty `-MockWith` block
Applied to files:
tests/Unit/Classes/SqlPermission.Tests.ps1
📚 Learning: 2025-11-27T17:59:27.205Z
Learnt from: CR
Repo: dsccommunity/SqlServerDsc PR: 0
File: .github/instructions/dsc-community-style-guidelines-pester.instructions.md:0-0
Timestamp: 2025-11-27T17:59:27.205Z
Learning: Applies to **/*.[Tt]ests.ps1 : Omit `-MockWith` when returning `$null`
Applied to files:
tests/Unit/Classes/SqlPermission.Tests.ps1
📚 Learning: 2025-11-27T18:00:20.934Z
Learnt from: CR
Repo: dsccommunity/SqlServerDsc PR: 0
File: .github/instructions/dsc-community-style-guidelines-unit-tests.instructions.md:0-0
Timestamp: 2025-11-27T18:00:20.934Z
Learning: Applies to tests/[Uu]nit/**/*.[Tt]ests.ps1 : Parameter set validation tests should use Get-Command with Where-Object filtering and Should assertions to verify ParameterSetName and ParameterListAsString
Applied to files:
tests/Unit/Classes/SqlPermission.Tests.ps1
📚 Learning: 2025-11-27T18:00:20.934Z
Learnt from: CR
Repo: dsccommunity/SqlServerDsc PR: 0
File: .github/instructions/dsc-community-style-guidelines-unit-tests.instructions.md:0-0
Timestamp: 2025-11-27T18:00:20.934Z
Learning: Applies to tests/[Uu]nit/**/*.[Tt]ests.ps1 : Parameter property tests should verify mandatory parameter attributes using Get-Command Parameters and Should -BeTrue assertions
Applied to files:
tests/Unit/Classes/SqlPermission.Tests.ps1
📚 Learning: 2025-12-04T17:07:00.186Z
Learnt from: CR
Repo: dsccommunity/SqlServerDsc PR: 0
File: .github/instructions/dsc-community-style-guidelines-powershell.instructions.md:0-0
Timestamp: 2025-12-04T17:07:00.186Z
Learning: Applies to **/*.{ps1,psm1,psd1} : Place ShouldProcess check immediately before each state-change operation
Applied to files:
tests/Unit/Classes/SqlPermission.Tests.ps1
📚 Learning: 2025-11-27T17:59:27.205Z
Learnt from: CR
Repo: dsccommunity/SqlServerDsc PR: 0
File: .github/instructions/dsc-community-style-guidelines-pester.instructions.md:0-0
Timestamp: 2025-11-27T17:59:27.205Z
Learning: Applies to **/*.[Tt]ests.ps1 : Never use `param()` inside `-MockWith` scriptblocks, parameters are auto-bound
Applied to files:
tests/Unit/Classes/SqlPermission.Tests.ps1
📚 Learning: 2025-08-17T10:15:48.194Z
Learnt from: johlju
Repo: dsccommunity/SqlServerDsc PR: 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/SqlPermission.Tests.ps1
📚 Learning: 2025-10-12T12:10:48.625Z
Learnt from: johlju
Repo: dsccommunity/SqlServerDsc PR: 2303
File: tests/Integration/Commands/PostInstallationConfiguration.Integration.Tests.ps1:127-143
Timestamp: 2025-10-12T12:10:48.625Z
Learning: For the SqlServerDsc module integration tests, ForceEncryption should not be enabled on the SQL Server instance (DSCSQLTEST) because the module needs to test both encrypted and non-encrypted connection scenarios in CI.
Applied to files:
tests/Unit/Classes/SqlPermission.Tests.ps1
📚 Learning: 2025-11-27T18:00:20.934Z
Learnt from: CR
Repo: dsccommunity/SqlServerDsc PR: 0
File: .github/instructions/dsc-community-style-guidelines-unit-tests.instructions.md:0-0
Timestamp: 2025-11-27T18:00:20.934Z
Learning: Applies to tests/[Uu]nit/**/*.[Tt]ests.ps1 : All public commands require parameter set validation tests
Applied to files:
tests/Unit/Classes/SqlPermission.Tests.ps1
📚 Learning: 2025-11-27T18:00:35.078Z
Learnt from: CR
Repo: dsccommunity/SqlServerDsc PR: 0
File: .github/instructions/dsc-community-style-guidelines.instructions.md:0-0
Timestamp: 2025-11-27T18:00:35.078Z
Learning: Follow PowerShell style and test guideline instructions strictly
Applied to files:
tests/Unit/Classes/SqlPermission.Tests.ps1
📚 Learning: 2025-08-16T13:22:15.230Z
Learnt from: johlju
Repo: dsccommunity/SqlServerDsc PR: 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/SqlPermission.Tests.ps1
📚 Learning: 2025-11-27T17:58:31.910Z
Learnt from: CR
Repo: dsccommunity/SqlServerDsc PR: 0
File: .github/instructions/dsc-community-style-guidelines-integration-tests.instructions.md:0-0
Timestamp: 2025-11-27T17:58:31.910Z
Learning: Applies to tests/Integration/**/*.Integration.Tests.ps1 : Call commands with `-Force` parameter where applicable to avoid prompting
Applied to files:
tests/Unit/Classes/SqlPermission.Tests.ps1
📚 Learning: 2025-11-27T17:59:27.205Z
Learnt from: CR
Repo: dsccommunity/SqlServerDsc PR: 0
File: .github/instructions/dsc-community-style-guidelines-pester.instructions.md:0-0
Timestamp: 2025-11-27T17:59:27.205Z
Learning: Applies to **/*.[Tt]ests.ps1 : Each scenario = separate `Context` block
Applied to files:
tests/Unit/Classes/SqlPermission.Tests.ps1
📚 Learning: 2025-11-27T17:59:27.205Z
Learnt from: CR
Repo: dsccommunity/SqlServerDsc PR: 0
File: .github/instructions/dsc-community-style-guidelines-pester.instructions.md:0-0
Timestamp: 2025-11-27T17:59:27.205Z
Learning: Applies to **/*.[Tt]ests.ps1 : Use nested `Context` blocks for complex scenarios
Applied to files:
tests/Unit/Classes/SqlPermission.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
🔇 Additional comments (12)
source/en-US/SqlPermission.strings.psd1 (1)
15-15: LGTM!The localized string correctly reflects the expanded principal support (login or server role) introduced by this refactor.
source/Classes/020.SqlPermission.ps1 (5)
356-385: LGTM!The principal detection logic correctly handles both logins and server roles. The pattern of checking both types and retrieving the appropriate object based on the result is clean and follows the established error handling patterns for class-based resources using
New-InvalidOperationException.
471-506: LGTM!The revocation flow correctly:
- Skips empty permission arrays (line 475 count check)
- Sets
-WithGrantforGrantWithGrantstate revocations- Dispatches to the appropriate parameter set (
-Loginvs-ServerRole) based on principal type- Propagates the original exception via
New-InvalidOperationException
528-543: LGTM!The Grant flow correctly dispatches to the appropriate
Grant-SqlDscServerPermissionvariant based on principal type.
545-561: LGTM!The
GrantWithGrantflow correctly sets-WithGrant = $trueand dispatches appropriately.
563-578: LGTM!The Deny flow correctly uses
Deny-SqlDscServerPermissionwith the appropriate principal parameter.tests/Unit/Classes/SqlPermission.Tests.ps1 (6)
1072-1075: LGTM!Good addition of
Test-SqlDscIsRolemock to ensure both principal type checks fail, correctly triggering the "principal not found" error path.
1101-1201: LGTM!Excellent addition of the server role test scenario. The test correctly:
- Mocks
Test-SqlDscIsLoginto return$falseandTest-SqlDscIsRoleto return$true- Creates a properly structured
ServerRoleobject with a validParentproperty (per learnings)- Verifies both
Get-SqlDscRoleinvocation andGrant-SqlDscServerPermissionwith correct permission
1292-1300: LGTM!The assertions correctly verify the new command behavior:
- Permission array containment check (
-contains 'ConnectSql')- Absence of
-WithGrantfor regular Grant state- Presence of
-WithGrant = $truefor GrantWithGrant state
1303-1393: LGTM!Good addition of a dedicated test context for the Deny permission path. The test correctly verifies that
Deny-SqlDscServerPermissionis invoked with the expected permission (ViewServerState).
1485-1502: LGTM!The revocation assertions correctly verify:
- Multiple permissions revoked together (
AlterAnyAvailabilityGroupandViewServerState)-WithGrant = $truefor revoking GrantWithGrant permissions- No
-WithGrantfor revoking regular Grant/Deny permissions
1709-1923: LGTM!The failure test context correctly:
- Uses a descriptive name reflecting all three command types
- Mocks all permission commands (
Grant-,Deny-,Revoke-SqlDscServerPermission) to throw errors- Tests both granting and revoking failure paths
- Verifies proper error message propagation using localized strings
There was a problem hiding this comment.
Actionable comments posted: 0
🧹 Nitpick comments (1)
source/Classes/020.SqlPermission.ps1 (1)
489-496: Consider extracting a helper for principal parameter selection.The pattern of selecting
-Login $principalObjectvs-ServerRole $principalObjectis repeated 5 times throughout theModify()method. This could be consolidated into a helper method or a splatting approach:# At the start of Modify(), after retrieving principalObject: $principalParameters = if ($isLogin) { @{ Login = $principalObject } } else { @{ ServerRole = $principalObject } } # Then use it like: Revoke-SqlDscServerPermission @principalParameters @revokeSqlDscServerPermissionParametersThis would reduce duplication and make the code more maintainable.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (4)
CHANGELOG.md(1 hunks)source/Classes/020.SqlPermission.ps1(4 hunks)source/en-US/SqlPermission.strings.psd1(1 hunks)tests/Unit/Classes/SqlPermission.Tests.ps1(12 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
- CHANGELOG.md
🧰 Additional context used
📓 Path-based instructions (16)
**/*.ps1
📄 CodeRabbit inference engine (.github/instructions/SqlServerDsc-guidelines.instructions.md)
**/*.ps1: Format public commands as{Verb}-SqlDsc{Noun}following PowerShell naming conventions
Format private functions as{Verb}-{Noun}following PowerShell naming conventions
Files:
source/Classes/020.SqlPermission.ps1tests/Unit/Classes/SqlPermission.Tests.ps1
source/[cC]lasses/020.*.ps1
📄 CodeRabbit inference engine (.github/instructions/dsc-community-style-guidelines-class-resource.instructions.md)
DSC class-based resources must use the file naming pattern
source/Classes/020.{ResourceName}.ps1
Files:
source/Classes/020.SqlPermission.ps1
source/[cC]lasses/**/*.ps1
📄 CodeRabbit inference engine (.github/instructions/dsc-community-style-guidelines-class-resource.instructions.md)
source/[cC]lasses/**/*.ps1: DSC class-based resources must be decorated with[DscResource(RunAsCredential = 'Optional')]or[DscResource(RunAsCredential = 'Mandatory')]based on requirements
DSC class-based resources must inherit fromResourceBaseclass from the DscResource.Base module
DSC class-based resources must use[Nullable[{FullTypeName}]]syntax for value-type properties (e.g.,[Nullable[System.Int32]])
DSC class-based resources must implement a required constructor with signatureResourceName () : base ($PSScriptRoot)and populate$this.ExcludeDscPropertiesarray
DSC class-based resources must implement required methods:Get(),Test(),Set(),GetCurrentState(), andModify()following the specified pattern
DSC class-based resources may optionally implement methods:AssertProperties()andNormalizeProperties()following the specified pattern
DSC class-based resources must include comment-based help with .DESCRIPTION section containing Requirements and Known issues sections with a link to all open issues on GitHub
DSC class-based resources must usetry/catchblocks for exception handling in classes
DSC class-based resources must useNew-*Exceptioncommands (such asNew-InvalidDataException,New-ArgumentException,New-InvalidOperationException,New-ObjectNotFoundException,New-InvalidResultException,New-NotImplementedException) instead ofthrowfor terminating errors in classes
Files:
source/Classes/020.SqlPermission.ps1
⚙️ CodeRabbit configuration file
source/[cC]lasses/**/*.ps1: # DSC Class-Based Resource GuidelinesApplies 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.localizedDatahashtable auto-populated byResourceBasefrom localization file- value-type properties: Use
[Nullable[{FullTypeName}]](e.g.,[Nullable[System.Int32]])Required constructor
MyResourceName () : base ($PSScriptRoot) { # Property names where state cannot be enforced, e.g. IsSingleInstance, Force $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, $p...
Files:
source/Classes/020.SqlPermission.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 in PowerShell scripts
Use localized string keys from $script:localizedData, not hardcoded strings, in diagnostic messages
Reference localized strings using the syntax: Write-Verbose -Message ($script:localizedData.KeyName -f $value1)Localize all strings using string keys; remove any orphaned string keys
Files:
source/Classes/020.SqlPermission.ps1
⚙️ CodeRabbit configuration file
source/**/*.ps1: # Localization GuidelinesRequirements
- Localize all Write-Debug, Write-Verbose, Write-Error, Write-Warning and $PSCmdlet.ThrowTerminatingError() messages
- Use localized string keys, not hardcoded strings
- Assume
$script:localizedDatais availableString Files
- Commands/functions:
source/en-US/{MyModuleName}.strings.psd1- Class resources:
source/en-US/{ResourceClassName}.strings.psd1Key Naming Patterns
- Format:
Verb_FunctionName_Action(underscore separators), e.g.Get_Database_ConnectingToDatabaseString 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.SqlPermission.ps1
source/Classes/*.ps1
📄 CodeRabbit inference engine (.github/instructions/dsc-community-style-guidelines.instructions.md)
source/Classes/*.ps1: Classes should be located insource/Classes/{DependencyGroupNumber}.{ClassName}.ps1
DSC resources should always be created as class-based resources
Files:
source/Classes/020.SqlPermission.ps1
**/*.{ps1,psm1,psd1}
📄 CodeRabbit inference engine (.github/instructions/dsc-community-style-guidelines-powershell.instructions.md)
**/*.{ps1,psm1,psd1}: Use descriptive names with 3+ characters and no abbreviations for functions, parameters, variables, keywords, and classes
Use PascalCase with Verb-Noun format for function names, using approved PowerShell verbs
Use PascalCase for parameter names
Use camelCase for variable names
Use lower-case for keywords
Use PascalCase for class names
Include scope for script/global/environment variables using$script:,$global:, or$env:prefixes
Use 4 spaces for indentation, not tabs
Use one space around operators (e.g.,$a = 1 + 2)
Use one space between type and variable (e.g.,[String] $name)
Use one space between keyword and parenthesis (e.g.,if ($condition))
Avoid spaces on empty lines
Limit lines to 120 characters
Place opening brace on a new line, except for variable assignments
Add one newline after opening brace
Add two newlines after closing brace (one if followed by another brace or continuation)
Use single quotes unless variable expansion is needed (e.g.,'text'vs"text $variable")
Use single-line array syntax for simple arrays:@('one', 'two', 'three')
Use multi-line array syntax with each element on a separate line with proper indentation
Do not use the unary comma operator (,) in return statements to force an array
Use empty hashtable syntax:@{}
Place each hashtable property on a separate line with proper indentation
Use PascalCase for hashtable properties
Use single-line comment format# Comment(capitalized, on own line)
Use multi-line comment format<# Comment #>with opening and closing brackets on own lines and indented text
Never include commented-out code
Always add comment-based help to all functions and scripts with SYNOPSIS, DESCRIPTION (40+ chars), PARAMETER, and EXAMPLE sections before function/class declaration
Use comment-based help indentation with keywords at 4 spaces and text at 8 spaces
Include examples in comment-based help for all parameter sets and combinations
In comment-based help INPUTS sec...
Files:
source/Classes/020.SqlPermission.ps1tests/Unit/Classes/SqlPermission.Tests.ps1source/en-US/SqlPermission.strings.psd1
**/[0-9][0-9][0-9].*.ps1
📄 CodeRabbit inference engine (.github/instructions/dsc-community-style-guidelines-powershell.instructions.md)
Name class files using
###.ClassName.ps1format (e.g.,001.SqlReason.ps1,004.StartupParameters.ps1)
Files:
source/Classes/020.SqlPermission.ps1
**/*.{ps1,psm1}
📄 CodeRabbit inference engine (.github/instructions/dsc-community-style-guidelines-powershell.instructions.md)
Use
$PSCmdlet.ThrowTerminatingError()for terminating errors (except in classes), use relevant error category, and in try-catch include exception with localized message
Files:
source/Classes/020.SqlPermission.ps1tests/Unit/Classes/SqlPermission.Tests.ps1
**
⚙️ CodeRabbit configuration file
**: # DSC Community GuidelinesTerminology
- Command: Public command
- Function: Private function
- Resource: DSC class-based resource
Build & Test Workflow Requirements
- Run PowerShell script files from repository root
- Setup build and test environment (once per
pwshsession):./build.ps1 -Tasks noop- Build project before running tests:
./build.ps1 -Tasks build- Always run tests in new
pwshsession:Invoke-Pester -Path @({test paths}) -Output DetailedFile Organization
- Public commands:
source/Public/{CommandName}.ps1- Private functions:
source/Private/{FunctionName}.ps1- Classes:
source/Classes/{DependencyGroupNumber}.{ClassName}.ps1- Enums:
source/Enum/{DependencyGroupNumber}.{EnumName}.ps1- Unit tests:
tests/Unit/{Classes|Public|Private}/{Name}.Tests.ps1- Integration tests:
tests/Integration/Commands/{CommandName}.Integration.Tests.ps1Requirements
- Follow instructions over existing code patterns
- Follow PowerShell style and test guideline instructions strictly
- 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
- DSC resources should always be created as class-based resources
- Add unit tests for all commands/functions/resources
- Add integration tests for all public commands and resources
Files:
source/Classes/020.SqlPermission.ps1tests/Unit/Classes/SqlPermission.Tests.ps1source/en-US/SqlPermission.strings.psd1
{**/*.ps1,**/*.psm1,**/*.psd1}
⚙️ CodeRabbit configuration file
{**/*.ps1,**/*.psm1,**/*.psd1}: # PowerShell GuidelinesNaming
- 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.ps1format (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 arrayHashtables
- Empty:
@{}- 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 as inline code with a 1‑line description...
Files:
source/Classes/020.SqlPermission.ps1tests/Unit/Classes/SqlPermission.Tests.ps1source/en-US/SqlPermission.strings.psd1
**/*.[Tt]ests.ps1
📄 CodeRabbit inference engine (.github/instructions/dsc-community-style-guidelines-pester.instructions.md)
**/*.[Tt]ests.ps1: 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
Test code only insideDescribeblocks
Assertions only inItblocks
Never test verbose messages, debug messages or parameter binding behavior
Pass all mandatory parameters to avoid prompts
InsideItblocks, assign unused return objects to$null(unless part of pipeline)
Tested entity must be called from within theItblocks
Keep results and assertions in sameItblock
Avoid try-catch-finally for cleanup, useAfterAllorAfterEach
Avoid unnecessary remove/recreate cycles
OneDescribeblock per file matching the tested entity name
Contextdescriptions start with 'When'
Itdescriptions start with 'Should', must not contain 'when'
Mock variables prefix: 'mock'
Public commands: Never useInModuleScope(unless retrieving localized strings or creating an object using an internal class)
Private functions/class resources: Always useInModuleScope
Each class method = separateContextblock
Each scenario = separateContextblock
Use nestedContextblocks for complex scenarios
Mocking inBeforeAll(BeforeEachonly when required)
Setup/teardown inBeforeAll,BeforeEach/AfterAll,AfterEachclose to usage
Spacing between blocks, arrange, act, and assert for readability
PascalCase:Describe,Context,It,Should,BeforeAll,BeforeEach,AfterAll,AfterEach
Use-BeTrue/-BeFalsenever-Be $true/-Be $false
Never useAssert-MockCalled, useShould -Invokeinstead
NoShould -Not -Throw- invoke commands directly
Never add an empty-MockWithblock
Omit-MockWithwhen returning$null
Set$PSDefaultParameterValuesforMock:ModuleName,Should:ModuleName,InModuleScope:ModuleName
Omit-ModuleNameparameter on Pester commands
Never useMockinsideInModuleScope-block
Never useparam()inside-MockWithscriptblock...
Files:
tests/Unit/Classes/SqlPermission.Tests.ps1
⚙️ CodeRabbit configuration file
**/*.[Tt]ests.ps1: # Tests GuidelinesCore 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
- Test code only inside
Describeblocks- Assertions only in
Itblocks- Never test verbose messages, debug messages or parameter binding behavior
- Pass all mandatory parameters to avoid prompts
Requirements
- Inside
Itblocks, assign unused return objects to$null(unless part of pipeline)- Tested entity must be called from within the
Itblocks- Keep results and assertions in same
Itblock- Avoid try-catch-finally for cleanup, use
AfterAllorAfterEach- Avoid unnecessary remove/recreate cycles
Naming
- One
Describeblock per file matching the tested entity nameContextdescriptions start with 'When'Itdescriptions start with 'Should', must not contain 'when'- Mock variables prefix: 'mock'
Structure & Scope
- Public commands: Never use
InModuleScope(unless retrieving localized strings or creating an object using an internal class)- Private functions/class resources: Always use
InModuleScope- Each class method = separate
Contextblock- Each scenario = separate
Contextblock- Use nested
Contextblocks for complex scenarios- Mocking in
BeforeAll(BeforeEachonly when required)- Setup/teardown in
BeforeAll,BeforeEach/AfterAll,AfterEachclose to usage- Spacing between blocks, arrange, act, and assert for readability
Syntax Rules
- PascalCase:
Describe,Context,It,Should,BeforeAll,BeforeEach,AfterAll,AfterEach- Use
-BeTrue/-BeFalsenever-Be $true/-Be $false- Never use
Assert-MockCalled, useShould -Invokeinstead- No
Should -Not -Throw- invoke commands directly- Never add an empty
-MockWithblock- Omit
-MockWithwhen returning$null- Set
$PSDefaultParameterValuesforMock:ModuleName,Should:ModuleName, `...
Files:
tests/Unit/Classes/SqlPermission.Tests.ps1
tests/Unit/Classes/*.[Tt]ests.ps1
📄 CodeRabbit inference engine (.github/instructions/dsc-community-style-guidelines-pester.instructions.md)
Class resources:
tests/Unit/Classes/{Name}.Tests.ps1
Files:
tests/Unit/Classes/SqlPermission.Tests.ps1
tests/[Uu]nit/**/*.[Tt]ests.ps1
📄 CodeRabbit inference engine (.github/instructions/dsc-community-style-guidelines-unit-tests.instructions.md)
tests/[Uu]nit/**/*.[Tt]ests.ps1: Test with localized strings usingInModuleScope -ScriptBlock { $script:localizedData.Key }
Mock files using the$TestDrivevariable (path to the test drive)
All public commands require parameter set validation tests
Use the exact setup block with BeforeDiscovery, BeforeAll, and AfterAll blocks including DscResource.Test module import and PSDefaultParameterValues configuration
Parameter set validation tests should use Get-Command with Where-Object filtering and Should assertions to verify ParameterSetName and ParameterListAsString
Parameter property tests should verify mandatory parameter attributes using Get-Command Parameters and Should -BeTrue assertions
Files:
tests/Unit/Classes/SqlPermission.Tests.ps1
⚙️ CodeRabbit configuration file
tests/[Uu]nit/**/*.[Tt]ests.ps1: # Unit Tests Guidelines
- Test with localized strings: Use
InModuleScope -ScriptBlock { $script:localizedData.Key }- Mock files: Use
$TestDrivevariable (path to the test drive)- All public commands require parameter set validation tests
- After modifying classes, always run tests in new session (for changes to take effect)
Test Setup Requirements
Use this exact setup block before
Describe:[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 noop" first.' } } BeforeAll { $script:moduleName = '{MyModuleName}' Import-Module -Name $script:moduleName -Force -ErrorAction 'Stop' $PSDefaultParameterValues['InModuleScope:ModuleName'] = $script:moduleName $PSDefaultParameterValues['Mock:ModuleName'] = $script:moduleName $PSDefaultParameterValues['Should:ModuleName'] = $script:moduleName } AfterAll { $PSDefaultParameterValues.Remove('InModuleScope:ModuleName') $PSDefaultParameterValues.Remove('Mock:ModuleNam...
Files:
tests/Unit/Classes/SqlPermission.Tests.ps1
tests/Unit/**/*.Tests.ps1
📄 CodeRabbit inference engine (.github/instructions/dsc-community-style-guidelines.instructions.md)
Unit tests should be located in
tests/Unit/{Classes|Public|Private}/{Name}.Tests.ps1
Files:
tests/Unit/Classes/SqlPermission.Tests.ps1
source/en-US/*.strings.psd1
📄 CodeRabbit inference engine (.github/instructions/dsc-community-style-guidelines-localization.instructions.md)
source/en-US/*.strings.psd1: Store command/function localized strings in source/en-US/{MyModuleName}.strings.psd1 files
Store class resource localized strings in source/en-US/{ResourceClassName}.strings.psd1 files
Use Key Naming Pattern format: Verb_FunctionName_Action with underscore separators (e.g., Get_Database_ConnectingToDatabase)
Format localized strings using ConvertFrom-StringData with placeholder syntax: KeyName = Message with {0} placeholder. (PREFIX0001)
Prefix string IDs with an acronym derived from the first letter of each word in the class or function name (e.g., SqlSetup → SS, Get-SqlDscDatabase → GSDD), followed by sequential numbers starting from 0001
Files:
source/en-US/SqlPermission.strings.psd1
**/*.psd1
📄 CodeRabbit inference engine (.github/instructions/dsc-community-style-guidelines-powershell.instructions.md)
Do not use
NestedModulesfor shared commands withoutRootModule
Files:
source/en-US/SqlPermission.strings.psd1
🧠 Learnings (31)
📓 Common learnings
Learnt from: CR
Repo: dsccommunity/SqlServerDsc PR: 0
File: .github/instructions/SqlServerDsc-guidelines.instructions.md:0-0
Timestamp: 2025-11-27T17:58:02.422Z
Learning: Applies to **/resources/**/*.ps1 : Database Engine resources must inherit from `SqlResourceBase`
Learnt from: johlju
Repo: dsccommunity/SqlServerDsc PR: 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.
Learnt from: CR
Repo: dsccommunity/SqlServerDsc PR: 0
File: .github/instructions/SqlServerDsc-guidelines.instructions.md:0-0
Timestamp: 2025-11-27T17:58:02.422Z
Learning: Applies to **/tests/Integration/**/*.ps1 : Integration tests: use `Connect-SqlDscDatabaseEngine` for SQL Server DB session with correct CI credentials, and always follow with `Disconnect-SqlDscDatabaseEngine`
📚 Learning: 2025-11-27T17:58:02.422Z
Learnt from: CR
Repo: dsccommunity/SqlServerDsc PR: 0
File: .github/instructions/SqlServerDsc-guidelines.instructions.md:0-0
Timestamp: 2025-11-27T17:58:02.422Z
Learning: Applies to **/tests/Integration/**/*.ps1 : Integration tests: use `Connect-SqlDscDatabaseEngine` for SQL Server DB session with correct CI credentials, and always follow with `Disconnect-SqlDscDatabaseEngine`
Applied to files:
source/Classes/020.SqlPermission.ps1tests/Unit/Classes/SqlPermission.Tests.ps1
📚 Learning: 2025-08-17T10:13:30.079Z
Learnt from: johlju
Repo: dsccommunity/SqlServerDsc PR: 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:
source/Classes/020.SqlPermission.ps1tests/Unit/Classes/SqlPermission.Tests.ps1
📚 Learning: 2025-11-27T17:58:02.422Z
Learnt from: CR
Repo: dsccommunity/SqlServerDsc PR: 0
File: .github/instructions/SqlServerDsc-guidelines.instructions.md:0-0
Timestamp: 2025-11-27T17:58:02.422Z
Learning: Applies to **/tests/**/*.tests.ps1 : When unit tests test classes or commands containing SMO types like `[Microsoft.SqlServer.Management.Smo.*]`, ensure they are properly stubbed in SMO.cs
Applied to files:
tests/Unit/Classes/SqlPermission.Tests.ps1
📚 Learning: 2025-11-27T17:58:02.422Z
Learnt from: CR
Repo: dsccommunity/SqlServerDsc PR: 0
File: .github/instructions/SqlServerDsc-guidelines.instructions.md:0-0
Timestamp: 2025-11-27T17:58:02.422Z
Learning: Applies to **/tests/**/*.tests.ps1 : In unit tests: use SMO stub types from SMO.cs, never mock SMO types
Applied to files:
tests/Unit/Classes/SqlPermission.Tests.ps1
📚 Learning: 2025-11-27T17:58:02.422Z
Learnt from: CR
Repo: dsccommunity/SqlServerDsc PR: 0
File: .github/instructions/SqlServerDsc-guidelines.instructions.md:0-0
Timestamp: 2025-11-27T17:58:02.422Z
Learning: Applies to **/tests/**/*.tests.ps1 : Add `$env:SqlServerDscCI = $true` in `BeforeAll` block and remove in `AfterAll` block of unit tests
Applied to files:
tests/Unit/Classes/SqlPermission.Tests.ps1
📚 Learning: 2025-11-27T17:58:02.422Z
Learnt from: CR
Repo: dsccommunity/SqlServerDsc PR: 0
File: .github/instructions/SqlServerDsc-guidelines.instructions.md:0-0
Timestamp: 2025-11-27T17:58:02.422Z
Learning: After changing SMO stub types in SMO.cs, run tests in a new PowerShell session for changes to take effect
Applied to files:
tests/Unit/Classes/SqlPermission.Tests.ps1
📚 Learning: 2025-11-27T17:59:27.205Z
Learnt from: CR
Repo: dsccommunity/SqlServerDsc PR: 0
File: .github/instructions/dsc-community-style-guidelines-pester.instructions.md:0-0
Timestamp: 2025-11-27T17:59:27.205Z
Learning: Applies to **/*.[Tt]ests.ps1 : Mock variables prefix: 'mock'
Applied to files:
tests/Unit/Classes/SqlPermission.Tests.ps1
📚 Learning: 2025-11-27T17:59:27.205Z
Learnt from: CR
Repo: dsccommunity/SqlServerDsc PR: 0
File: .github/instructions/dsc-community-style-guidelines-pester.instructions.md:0-0
Timestamp: 2025-11-27T17:59:27.205Z
Learning: Applies to tests/Unit/Public/*.[Tt]ests.ps1 : Public commands: `tests/Unit/Public/{Name}.Tests.ps1`
Applied to files:
tests/Unit/Classes/SqlPermission.Tests.ps1
📚 Learning: 2025-11-27T17:59:27.205Z
Learnt from: CR
Repo: dsccommunity/SqlServerDsc PR: 0
File: .github/instructions/dsc-community-style-guidelines-pester.instructions.md:0-0
Timestamp: 2025-11-27T17:59:27.205Z
Learning: Applies to **/*.[Tt]ests.ps1 : Mocking in `BeforeAll` (`BeforeEach` only when required)
Applied to files:
tests/Unit/Classes/SqlPermission.Tests.ps1
📚 Learning: 2025-11-27T17:59:27.205Z
Learnt from: CR
Repo: dsccommunity/SqlServerDsc PR: 0
File: .github/instructions/dsc-community-style-guidelines-pester.instructions.md:0-0
Timestamp: 2025-11-27T17:59:27.205Z
Learning: Applies to **/*.[Tt]ests.ps1 : Set `$PSDefaultParameterValues` for `Mock:ModuleName`, `Should:ModuleName`, `InModuleScope:ModuleName`
Applied to files:
tests/Unit/Classes/SqlPermission.Tests.ps1
📚 Learning: 2025-11-27T17:59:27.205Z
Learnt from: CR
Repo: dsccommunity/SqlServerDsc PR: 0
File: .github/instructions/dsc-community-style-guidelines-pester.instructions.md:0-0
Timestamp: 2025-11-27T17:59:27.205Z
Learning: Applies to **/*.[Tt]ests.ps1 : No `Should -Not -Throw` - invoke commands directly
Applied to files:
tests/Unit/Classes/SqlPermission.Tests.ps1
📚 Learning: 2025-11-27T17:59:27.205Z
Learnt from: CR
Repo: dsccommunity/SqlServerDsc PR: 0
File: .github/instructions/dsc-community-style-guidelines-pester.instructions.md:0-0
Timestamp: 2025-11-27T17:59:27.205Z
Learning: Applies to **/*.[Tt]ests.ps1 : Never use `Assert-MockCalled`, use `Should -Invoke` instead
Applied to files:
tests/Unit/Classes/SqlPermission.Tests.ps1
📚 Learning: 2025-11-27T17:58:31.910Z
Learnt from: CR
Repo: dsccommunity/SqlServerDsc PR: 0
File: .github/instructions/dsc-community-style-guidelines-integration-tests.instructions.md:0-0
Timestamp: 2025-11-27T17:58:31.910Z
Learning: Applies to tests/Integration/**/*.Integration.Tests.ps1 : Avoid `ExpectedMessage` parameter for `Should -Throw` assertions in integration tests
Applied to files:
tests/Unit/Classes/SqlPermission.Tests.ps1
📚 Learning: 2025-11-27T17:59:27.205Z
Learnt from: CR
Repo: dsccommunity/SqlServerDsc PR: 0
File: .github/instructions/dsc-community-style-guidelines-pester.instructions.md:0-0
Timestamp: 2025-11-27T17:59:27.205Z
Learning: Applies to **/*.[Tt]ests.ps1 : Never use `Mock` inside `InModuleScope`-block
Applied to files:
tests/Unit/Classes/SqlPermission.Tests.ps1
📚 Learning: 2025-11-27T17:59:27.205Z
Learnt from: CR
Repo: dsccommunity/SqlServerDsc PR: 0
File: .github/instructions/dsc-community-style-guidelines-pester.instructions.md:0-0
Timestamp: 2025-11-27T17:59:27.205Z
Learning: Applies to **/*.[Tt]ests.ps1 : Never add an empty `-MockWith` block
Applied to files:
tests/Unit/Classes/SqlPermission.Tests.ps1
📚 Learning: 2025-11-27T17:59:27.205Z
Learnt from: CR
Repo: dsccommunity/SqlServerDsc PR: 0
File: .github/instructions/dsc-community-style-guidelines-pester.instructions.md:0-0
Timestamp: 2025-11-27T17:59:27.205Z
Learning: Applies to **/*.[Tt]ests.ps1 : Omit `-MockWith` when returning `$null`
Applied to files:
tests/Unit/Classes/SqlPermission.Tests.ps1
📚 Learning: 2025-11-27T18:00:20.934Z
Learnt from: CR
Repo: dsccommunity/SqlServerDsc PR: 0
File: .github/instructions/dsc-community-style-guidelines-unit-tests.instructions.md:0-0
Timestamp: 2025-11-27T18:00:20.934Z
Learning: Applies to tests/[Uu]nit/**/*.[Tt]ests.ps1 : Parameter set validation tests should use Get-Command with Where-Object filtering and Should assertions to verify ParameterSetName and ParameterListAsString
Applied to files:
tests/Unit/Classes/SqlPermission.Tests.ps1
📚 Learning: 2025-11-27T18:00:20.934Z
Learnt from: CR
Repo: dsccommunity/SqlServerDsc PR: 0
File: .github/instructions/dsc-community-style-guidelines-unit-tests.instructions.md:0-0
Timestamp: 2025-11-27T18:00:20.934Z
Learning: Applies to tests/[Uu]nit/**/*.[Tt]ests.ps1 : Parameter property tests should verify mandatory parameter attributes using Get-Command Parameters and Should -BeTrue assertions
Applied to files:
tests/Unit/Classes/SqlPermission.Tests.ps1
📚 Learning: 2025-12-04T17:07:00.186Z
Learnt from: CR
Repo: dsccommunity/SqlServerDsc PR: 0
File: .github/instructions/dsc-community-style-guidelines-powershell.instructions.md:0-0
Timestamp: 2025-12-04T17:07:00.186Z
Learning: Applies to **/*.{ps1,psm1,psd1} : Place ShouldProcess check immediately before each state-change operation
Applied to files:
tests/Unit/Classes/SqlPermission.Tests.ps1
📚 Learning: 2025-11-27T17:59:27.205Z
Learnt from: CR
Repo: dsccommunity/SqlServerDsc PR: 0
File: .github/instructions/dsc-community-style-guidelines-pester.instructions.md:0-0
Timestamp: 2025-11-27T17:59:27.205Z
Learning: Applies to **/*.[Tt]ests.ps1 : Never use `param()` inside `-MockWith` scriptblocks, parameters are auto-bound
Applied to files:
tests/Unit/Classes/SqlPermission.Tests.ps1
📚 Learning: 2025-08-17T10:15:48.194Z
Learnt from: johlju
Repo: dsccommunity/SqlServerDsc PR: 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/SqlPermission.Tests.ps1
📚 Learning: 2025-10-12T12:10:48.625Z
Learnt from: johlju
Repo: dsccommunity/SqlServerDsc PR: 2303
File: tests/Integration/Commands/PostInstallationConfiguration.Integration.Tests.ps1:127-143
Timestamp: 2025-10-12T12:10:48.625Z
Learning: For the SqlServerDsc module integration tests, ForceEncryption should not be enabled on the SQL Server instance (DSCSQLTEST) because the module needs to test both encrypted and non-encrypted connection scenarios in CI.
Applied to files:
tests/Unit/Classes/SqlPermission.Tests.ps1
📚 Learning: 2025-11-27T18:00:20.934Z
Learnt from: CR
Repo: dsccommunity/SqlServerDsc PR: 0
File: .github/instructions/dsc-community-style-guidelines-unit-tests.instructions.md:0-0
Timestamp: 2025-11-27T18:00:20.934Z
Learning: Applies to tests/[Uu]nit/**/*.[Tt]ests.ps1 : All public commands require parameter set validation tests
Applied to files:
tests/Unit/Classes/SqlPermission.Tests.ps1
📚 Learning: 2025-11-27T18:00:35.078Z
Learnt from: CR
Repo: dsccommunity/SqlServerDsc PR: 0
File: .github/instructions/dsc-community-style-guidelines.instructions.md:0-0
Timestamp: 2025-11-27T18:00:35.078Z
Learning: Follow PowerShell style and test guideline instructions strictly
Applied to files:
tests/Unit/Classes/SqlPermission.Tests.ps1
📚 Learning: 2025-08-16T13:22:15.230Z
Learnt from: johlju
Repo: dsccommunity/SqlServerDsc PR: 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/SqlPermission.Tests.ps1
📚 Learning: 2025-11-27T17:58:31.910Z
Learnt from: CR
Repo: dsccommunity/SqlServerDsc PR: 0
File: .github/instructions/dsc-community-style-guidelines-integration-tests.instructions.md:0-0
Timestamp: 2025-11-27T17:58:31.910Z
Learning: Applies to tests/Integration/**/*.Integration.Tests.ps1 : Call commands with `-Force` parameter where applicable to avoid prompting
Applied to files:
tests/Unit/Classes/SqlPermission.Tests.ps1
📚 Learning: 2025-11-27T17:59:27.205Z
Learnt from: CR
Repo: dsccommunity/SqlServerDsc PR: 0
File: .github/instructions/dsc-community-style-guidelines-pester.instructions.md:0-0
Timestamp: 2025-11-27T17:59:27.205Z
Learning: Applies to **/*.[Tt]ests.ps1 : Each scenario = separate `Context` block
Applied to files:
tests/Unit/Classes/SqlPermission.Tests.ps1
📚 Learning: 2025-11-27T17:59:27.205Z
Learnt from: CR
Repo: dsccommunity/SqlServerDsc PR: 0
File: .github/instructions/dsc-community-style-guidelines-pester.instructions.md:0-0
Timestamp: 2025-11-27T17:59:27.205Z
Learning: Applies to **/*.[Tt]ests.ps1 : Use nested `Context` blocks for complex scenarios
Applied to files:
tests/Unit/Classes/SqlPermission.Tests.ps1
📚 Learning: 2025-11-27T17:58:42.327Z
Learnt from: CR
Repo: dsccommunity/SqlServerDsc PR: 0
File: .github/instructions/dsc-community-style-guidelines-localization.instructions.md:0-0
Timestamp: 2025-11-27T17:58:42.327Z
Learning: Applies to source/en-US/*.strings.psd1 : Use Key Naming Pattern format: Verb_FunctionName_Action with underscore separators (e.g., Get_Database_ConnectingToDatabase)
Applied to files:
source/en-US/SqlPermission.strings.psd1
📚 Learning: 2025-11-27T17:58:42.327Z
Learnt from: CR
Repo: dsccommunity/SqlServerDsc PR: 0
File: .github/instructions/dsc-community-style-guidelines-localization.instructions.md:0-0
Timestamp: 2025-11-27T17:58:42.327Z
Learning: Applies to source/en-US/*.strings.psd1 : Prefix string IDs with an acronym derived from the first letter of each word in the class or function name (e.g., SqlSetup → SS, Get-SqlDscDatabase → GSDD), followed by sequential numbers starting from 0001
Applied to files:
source/en-US/SqlPermission.strings.psd1
⏰ 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 (15)
tests/Unit/Classes/SqlPermission.Tests.ps1 (8)
1069-1076: LGTM!The addition of
Test-SqlDscIsRolemock correctly aligns with the source changes that now check for both login and server role principals. The mock pattern follows guidelines with no-MockWithblock when returning$false.
1101-1201: Good test coverage for server role principals.The new context properly validates the server role principal path, including correct mock setup and verification that
Get-SqlDscRoleandGrant-SqlDscServerPermissionare invoked appropriately.
1256-1268: LGTM!The mock setup correctly creates the Login SMO object with a proper Server parent containing the InstanceName. The permission command mocks follow the guideline of omitting
-MockWithwhen returning$null.
1292-1299: LGTM!The parameter filter correctly validates that
Grant-SqlDscServerPermissionis called with the expected permission and properly distinguishes between regular Grant (no WithGrant) and GrantWithGrant scenarios.
1303-1395: LGTM!Good addition of a dedicated context to test the Deny permission path. The test properly verifies that
Deny-SqlDscServerPermissionis invoked with the correct permission.
1485-1502: LGTM!The revoke assertions properly validate that
Revoke-SqlDscServerPermissionis called for each permission state with the correct permissions andWithGrantparameter handling.
1709-1709: LGTM!The renamed context accurately reflects that the tests now cover failures from the granular Grant/Deny/Revoke commands rather than the deprecated Set-SqlDscServerPermission.
1772-1780: LGTM!The error-throwing mocks for all three permission commands ensure the error handling paths are exercised when any operation fails.
source/Classes/020.SqlPermission.ps1 (6)
356-373: LGTM!Good refactoring to support both logins and server roles. The combined check
(-not $isLogin -and -not $isRole)correctly handles the case where the principal doesn't exist as either type, and the error message has been updated to reflect this.
375-385: LGTM!The principal object retrieval correctly uses
Get-SqlDscLoginorGet-SqlDscRolebased on the principal type, with-ErrorAction 'Stop'ensuring any failures are properly handled.
471-506: LGTM!The revoke logic correctly:
- Guards against empty permission arrays before calling the revoke command
- Handles
WithGrantforGrantWithGrantstate- Uses the appropriate
-Loginor-ServerRoleparameter based on principal type- Properly catches and rethrows errors with localized messages
528-543: LGTM!The Grant implementation correctly builds parameters and dispatches to
Grant-SqlDscServerPermissionwith the appropriate principal parameter.
545-561: LGTM!The GrantWithGrant case correctly adds
WithGrant = $trueto the parameters before callingGrant-SqlDscServerPermission.
563-578: LGTM!The Deny implementation correctly uses
Deny-SqlDscServerPermissionwith the appropriate principal parameter.source/en-US/SqlPermission.strings.psd1 (1)
15-15: LGTM!The updated error message correctly reflects that the principal can now be either a login or a server role, aligning with the source code changes in
Modify().
…incipal parameters
Pull Request (PR) description
SqlPermission(
Grant-SqlDscServerPermission,Deny-SqlDscServerPermission,Revoke-SqlDscServerPermission, andGet-SqlDscServerPermission)instead of the deprecated
Set-SqlDscServerPermissioncommand(issue #2159).
This Pull Request (PR) fixes the following issues
Set-SqlDscServerPermission: Use new object-based server permission commands #2159Task list
file CHANGELOG.md. Entry should say what was changed and how that
affects users (if applicable), and reference the issue being resolved
(if applicable).
This change is