diff --git a/CHANGELOG.md b/CHANGELOG.md index 627d75d9d..53208f4da 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +### Fixed + +- SPShellAdmins + - Fixed that the Member comparison was not case insensitive. + ## [5.5.0] - 2024-04-22 ### Added diff --git a/RequiredModules.psd1 b/RequiredModules.psd1 index 93a5515bb..111143eaf 100644 --- a/RequiredModules.psd1 +++ b/RequiredModules.psd1 @@ -17,7 +17,13 @@ 'Sampler.GitHubTasks' = 'latest' MarkdownLinkCheck = 'latest' 'DscResource.Common' = 'latest' - 'DscResource.Test' = 'latest' + # Using Prerelease to Fix HQRM Test for SharePointDsc.Reverse: https://github.com/dsccommunity/SharePointDsc/pull/1440#issuecomment-2485466538 + 'DscResource.Test' = @{ + Version = 'latest' + Parameters = @{ + AllowPrerelease = $true + } + } 'DscResource.AnalyzerRules' = 'latest' xDscResourceDesigner = 'latest' 'DscResource.DocGenerator' = 'latest' diff --git a/SharePointDsc/DSCResources/MSFT_SPShellAdmins/MSFT_SPShellAdmins.psm1 b/SharePointDsc/DSCResources/MSFT_SPShellAdmins/MSFT_SPShellAdmins.psm1 index 999c7d374..daf88e08a 100644 --- a/SharePointDsc/DSCResources/MSFT_SPShellAdmins/MSFT_SPShellAdmins.psm1 +++ b/SharePointDsc/DSCResources/MSFT_SPShellAdmins/MSFT_SPShellAdmins.psm1 @@ -424,7 +424,7 @@ function Set-TargetResource { foreach ($member in $params.MembersToInclude) { - if (-not $shellAdmins.UserName.Contains($member)) + if ($shellAdmins.UserName -notcontains $member) { try { @@ -479,7 +479,7 @@ function Set-TargetResource { foreach ($member in $params.MembersToExclude) { - if ($shellAdmins.UserName.Contains($member)) + if ($shellAdmins.UserName -contains $member) { try { @@ -651,7 +651,7 @@ function Set-TargetResource { foreach ($member in $database.MembersToInclude) { - if (-not $dbShellAdmins.UserName.Contains($member)) + if ($dbShellAdmins.UserName -notcontains $member) { try { @@ -745,7 +745,7 @@ function Set-TargetResource { foreach ($member in $database.MembersToExclude) { - if ($dbShellAdmins.UserName.Contains($member)) + if ($dbShellAdmins.UserName -contains $member) { try { @@ -937,7 +937,7 @@ function Set-TargetResource { foreach ($member in $params.MembersToInclude) { - if (-not $dbShellAdmins.UserName.Contains($member)) + if ($dbShellAdmins.UserName -notcontains $member) { try { @@ -1031,7 +1031,7 @@ function Set-TargetResource { foreach ($member in $params.MembersToExclude) { - if ($dbShellAdmins.UserName.Contains($member)) + if ($dbShellAdmins.UserName -contains $member) { try { @@ -1164,7 +1164,7 @@ function Test-TargetResource foreach ($member in $MembersToInclude) { - if (-not($CurrentValues.Members.Contains($member))) + if ($CurrentValues.Members -notcontains $member) { $message = "$member is not a Shell Admin." Write-Verbose -Message $message @@ -1187,7 +1187,7 @@ function Test-TargetResource { foreach ($member in $MembersToExclude) { - if ($CurrentValues.Members.Contains($member)) + if ($CurrentValues.Members -contains $member) { $message = "$member is a Shell Admin." Write-Verbose -Message $message @@ -1260,7 +1260,7 @@ function Test-TargetResource foreach ($member in $MembersToInclude) { - if (-not($database.Members.Contains($member))) + if ($database.Members -notcontains $member) { $message = "$member is not a Shell Admin." Write-Verbose -Message $message @@ -1282,7 +1282,7 @@ function Test-TargetResource { foreach ($member in $MembersToExclude) { - if ($database.Members.Contains($member)) + if ($database.Members -contains $member) { $message = "$member is a Shell Admin." Write-Verbose -Message $message @@ -1365,7 +1365,7 @@ function Test-TargetResource foreach ($member in $database.MembersToInclude) { - if (-not($currentCDB.Members.Contains($member))) + if ($currentCDB.Members -notcontains $member) { $message = "$member is not a Shell Admin." Write-Verbose -Message $message @@ -1388,7 +1388,7 @@ function Test-TargetResource { foreach ($member in $database.MembersToExclude) { - if ($currentCDB.Members.Contains($member)) + if ($currentCDB.Members -contains $member) { $message = "$member is a Shell Admin." Write-Verbose -Message $message diff --git a/azure-pipelines.yml b/azure-pipelines.yml index d9c9994cb..76580a55b 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -26,7 +26,7 @@ stages: vmImage: "windows-latest" steps: - pwsh: | - dotnet tool install --global GitVersion.Tool + dotnet tool install --global GitVersion.Tool --version 5.12.0 $gitVersionObject = dotnet-gitversion | ConvertFrom-Json $gitVersionObject.PSObject.Properties.ForEach{ Write-Host -Object "Setting Task Variable '$($_.Name)' with value '$($_.Value)'." diff --git a/build.yaml b/build.yaml index b8ef68c99..a615f665e 100644 --- a/build.yaml +++ b/build.yaml @@ -92,6 +92,7 @@ DscTest: Tag: ExcludeSourceFile: - output + - Modules/SharePointDsc.Reverse/SharePointDsc.Reverse.psm1 ExcludeModuleFile: - Modules/DscResource.Common diff --git a/tests/Unit/SharePointDsc/SharePointDsc.SPShellAdmins.Tests.ps1 b/tests/Unit/SharePointDsc/SharePointDsc.SPShellAdmins.Tests.ps1 index 17dbfb47b..de3833aa2 100644 --- a/tests/Unit/SharePointDsc/SharePointDsc.SPShellAdmins.Tests.ps1 +++ b/tests/Unit/SharePointDsc/SharePointDsc.SPShellAdmins.Tests.ps1 @@ -459,6 +459,116 @@ try } } + Context -Name "AllDatabases parameter is used with MembersToInclude and permissions do not match" -Fixture { + BeforeAll { + $testParams = @{ + IsSingleInstance = "Yes" + MembersToInclude = "contoso\user1", "contoso\user2", "contoso\sa_farm" + AllDatabases = $true + } + + Mock -CommandName Get-SPShellAdmin -MockWith { + if ($database) + { + # Database parameter used, return database permissions + return @{ + UserName = "contoso\user3", "contoso\user4" + } + } + else + { + # Database parameter not used, return general permissions + return @{ + UserName = "contoso\user3", "contoso\user4" + } + } + } + + Mock -CommandName Get-SPDatabase -MockWith { + return @( + @{ + Name = "SharePoint_Content_Contoso1" + Id = "F9168C5E-CEB2-4faa-B6BF-329BF39FA1E4" + NormalizedDataSource = 'SQL01' + }, + @{ + Name = "SharePoint_Content_Contoso2" + Id = "936DA01F-9ABD-4d9d-80C7-02AF85C822A8" + NormalizedDataSource = 'SQL01' + } + ) + } + } + + It "Should return null from the get method" { + Get-TargetResource @testParams | Should -Not -BeNullOrEmpty + } + + It "Should return false from the test method" { + Test-TargetResource @testParams | Should -Be $false + } + + It "Should throw an exception in the set method" { + Set-TargetResource @testParams + Assert-MockCalled Add-SPShellAdmin + } + } + + Context -Name "AllDatabases parameter is used with MembersToExclude and permissions do not match" -Fixture { + BeforeAll { + $testParams = @{ + IsSingleInstance = "Yes" + MembersToExclude = "contoso\user3", "contoso\user4" + AllDatabases = $true + } + + Mock -CommandName Get-SPShellAdmin -MockWith { + if ($database) + { + # Database parameter used, return database permissions + return @{ + UserName = "contoso\user1", "contoso\user3", "contoso\user4" + } + } + else + { + # Database parameter not used, return general permissions + return @{ + UserName = "contoso\user2", "contoso\user3", "contoso\user4" + } + } + } + + Mock -CommandName Get-SPDatabase -MockWith { + return @( + @{ + Name = "SharePoint_Content_Contoso1" + Id = "F9168C5E-CEB2-4faa-B6BF-329BF39FA1E4" + NormalizedDataSource = 'SQL01' + }, + @{ + Name = "SharePoint_Content_Contoso2" + Id = "936DA01F-9ABD-4d9d-80C7-02AF85C822A8" + NormalizedDataSource = 'SQL01' + } + ) + } + } + + It "Should return null from the get method" { + Get-TargetResource @testParams | Should -Not -BeNullOrEmpty + } + + It "Should return false from the test method" { + Test-TargetResource @testParams | Should -Be $false + } + + It "Should throw an exception in the set method" { + Set-TargetResource @testParams + Assert-MockCalled Remove-SPShellAdmin + } + } + Context -Name "Configured Members do not match the actual members - General permissions" -Fixture { BeforeAll { $testParams = @{ @@ -517,8 +627,9 @@ try else { # Database parameter not used, return general permissions + # The Username "contoso\User2" is mocked with Upercase to test if the resource is case insenitive. return @{ - UserName = "contoso\user1", "contoso\user2" + UserName = "contoso\user1", "contoso\User2" } } } @@ -623,15 +734,17 @@ try if ($database) { # Database parameter used, return database permissions + # The Username "contoso\User2" is mocked with Upercase to test if the resource is case insenitive. return @{ - UserName = "contoso\user1", "contoso\user2" + UserName = "contoso\user1", "contoso\User2" } } else { # Database parameter not used, return general permissions + # The Username "contoso\User2" is mocked with Upercase to test if the resource is case insenitive. return @{ - UserName = "contoso\user1", "contoso\user2" + UserName = "contoso\user1", "contoso\User2" } } } @@ -720,8 +833,9 @@ try else { # Database parameter not used, return general permissions + # The Username "contoso\User2" is mocked with Upercase to test if the resource is case insenitive. return @{ - UserName = "contoso\user1", "contoso\user2", "contoso\user3" + UserName = "contoso\user1", "contoso\User2", "contoso\user3" } } } @@ -825,15 +939,17 @@ try if ($database) { # Database parameter used, return database permissions + # The Username "contoso\User2" is mocked with Upercase to test if the resource is case insenitive. return @{ - UserName = "contoso\user1", "contoso\user2", "contoso\user3" + UserName = "contoso\user1", "contoso\User2", "contoso\user3" } } else { # Database parameter not used, return general permissions + # The Username "contoso\User2" is mocked with Upercase to test if the resource is case insenitive. return @{ - UserName = "contoso\user1", "contoso\user2" + UserName = "contoso\user1", "contoso\User2" } } } @@ -964,15 +1080,17 @@ try if ($database) { # Database parameter used, return database permissions + # The Username "contoso\User2" is mocked with Upercase to test if the resource is case insenitive. return @{ - UserName = "contoso\user1", "contoso\user2" + UserName = "contoso\user1", "contoso\User2" } } else { # Database parameter not used, return general permissions + # The Username "contoso\User2" is mocked with Upercase to test if the resource is case insenitive. return @{ - UserName = "contoso\user1", "contoso\user2" + UserName = "contoso\user1", "contoso\User2" } } }