diff --git a/CHANGELOG.md b/CHANGELOG.md index c8eb0bf8..fb93cfc5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,7 @@ For older change log history see the [historic changelog](HISTORIC_CHANGELOG.md) ### Changed - `WebAdministrationDsc` + - Return Absent when WebsitePath does not exist and treat empty string value as Present - Update to latest Sampler files. - Remove `windows-2019` images. [#649](https://github.com/dsccommunity/WebAdministrationDsc/issues/649). - Add `windows-2025` images. diff --git a/source/DSCResources/DSC_WebConfigProperty/DSC_WebConfigProperty.psm1 b/source/DSCResources/DSC_WebConfigProperty/DSC_WebConfigProperty.psm1 index 6b394c78..a37e2b1b 100644 --- a/source/DSCResources/DSC_WebConfigProperty/DSC_WebConfigProperty.psm1 +++ b/source/DSCResources/DSC_WebConfigProperty/DSC_WebConfigProperty.psm1 @@ -48,32 +48,53 @@ function Get-TargetResource Write-Verbose ` -Message ($script:localizedData.VerboseTargetCheckingTarget -f $PropertyName, $Filter, $WebsitePath ) - $existingValue = Get-ItemValue ` - -WebsitePath $WebsitePath ` - -Filter $Filter ` - -PropertyName $PropertyName - $result = @{ - WebsitePath = $WebsitePath - Filter = $Filter + WebsitePath = $WebsitePath + Filter = $Filter PropertyName = $PropertyName - Ensure = 'Present' - Value = $existingValue + Ensure = 'Absent' + Value = $null } - if (-not($existingValue)) + $getItemValueParameters = @{ + WebsitePath = $WebsitePath + Filter = $Filter + PropertyName = $PropertyName + } + + try + { + $existingValue = Get-ItemValue @getItemValueParameters + } + catch [System.Management.Automation.ItemNotFoundException] { - # Property was not found. Write-Verbose ` - -Message ($script:localizedData.VerboseTargetPropertyNotFound -f $PropertyName ) + -Message ($script:localizedData.VerboseWebsitePathNotFound -f $WebsitePath) - $result.Ensure = 'Absent' + return $result + } + catch [System.IO.FileNotFoundException] + { + Write-Verbose ` + -Message ($script:localizedData.VerboseWebsitePathNotFound -f $WebsitePath) + + return $result + } + + $result.Value = $existingValue + + if ($null -eq $existingValue) + { + # Property was not found. + Write-Verbose ` + -Message ($script:localizedData.VerboseTargetPropertyNotFound -f $PropertyName) } else { # Property was found. + $result.Ensure = 'Present' Write-Verbose ` - -Message ($script:localizedData.VerboseTargetPropertyFound -f $PropertyName ) + -Message ($script:localizedData.VerboseTargetPropertyFound -f $PropertyName) } return $result diff --git a/source/DSCResources/DSC_WebConfigProperty/en-US/DSC_WebConfigProperty.strings.psd1 b/source/DSCResources/DSC_WebConfigProperty/en-US/DSC_WebConfigProperty.strings.psd1 index f39e314b..4067734b 100644 --- a/source/DSCResources/DSC_WebConfigProperty/en-US/DSC_WebConfigProperty.strings.psd1 +++ b/source/DSCResources/DSC_WebConfigProperty/en-US/DSC_WebConfigProperty.strings.psd1 @@ -5,4 +5,5 @@ ConvertFrom-StringData -StringData @' VerboseTargetPropertyFound = Property "{0}" has been found. VerboseSetTargetEditItem = Ensuring property "{0}" is set. VerboseSetTargetRemoveItem = Property "{0}" exists, removing property. + VerboseWebsitePathNotFound = Cannot find path '{0}' because it does not exist. '@ diff --git a/tests/Unit/DSC_WebConfigProperty.Tests.ps1 b/tests/Unit/DSC_WebConfigProperty.Tests.ps1 index cc6d66a6..f48a9f50 100644 --- a/tests/Unit/DSC_WebConfigProperty.Tests.ps1 +++ b/tests/Unit/DSC_WebConfigProperty.Tests.ps1 @@ -19,8 +19,8 @@ function Invoke-TestSetup -ResourceType 'Mof' ` -TestType 'Unit' - Import-Module -Name (Join-Path -Path $PSScriptRoot -ChildPath '..\MockWebAdministrationWindowsFeature.psm1') - Import-Module -Name (Join-Path -Path $PSScriptRoot -ChildPath '..\TestHelper\CommonTestHelper.psm1') + Import-Module -Name (Join-Path -Path $PSScriptRoot -ChildPath '..\MockWebAdministrationWindowsFeature.psm1') + Import-Module -Name (Join-Path -Path $PSScriptRoot -ChildPath '..\TestHelper\CommonTestHelper.psm1') } function Invoke-TestCleanup @@ -100,6 +100,46 @@ try Assert-MockCalled -CommandName Get-ItemValue -Times 1 -Exactly } } + + Context 'When value is an empty string' { + BeforeEach { + Mock -CommandName Get-ItemValue -ModuleName $script:dscResourceName -MockWith { + return [System.String]::Empty + } + } + + It 'Should return Ensure as Present and an empty string value' { + $result = Get-TargetResource ` + -WebsitePath 'MACHINE/WEBROOT/APPHOST' ` + -Filter 'system.webServer/advancedLogging/server' ` + -PropertyName 'enabled' + + $result.Ensure | Should -Be 'Present' + $result.Value | Should -Be '' + + Assert-MockCalled -CommandName Get-ItemValue -Times 1 -Exactly + } + } + + Context 'When WebsitePath does not exist' { + BeforeEach { + Mock -CommandName Get-ItemValue -ModuleName $script:dscResourceName -MockWith { + throw [System.IO.FileNotFoundException] 'Path not found' + } + } + + It 'Should return Ensure as Absent without propagating the error' { + $result = Get-TargetResource ` + -WebsitePath 'MACHINE/WEBROOT/APPHOST' ` + -Filter 'system.webServer/advancedLogging/server' ` + -PropertyName 'enabled' + + $result.Ensure | Should -Be 'Absent' + $result.Value | Should -BeNullOrEmpty + + Assert-MockCalled -CommandName Get-ItemValue -Times 1 -Exactly + } + } } #endregion Function Get-TargetResource @@ -224,7 +264,7 @@ try #region Non-Exported Function Unit Tests Describe "$($script:dscResourceName)\Get-ItemPropertyType" { $propertyType = 'UInt32' - $parameters = @{ + $parameters = @{ WebsitePath = 'IIS:\' Filter = 'system.webServer/security/dynamicIpSecurity/denyByConcurrentRequests' PropertyName = 'maxConcurrentRequests' @@ -260,7 +300,6 @@ try $returnValue | Should -BeOfType [$dataType] } - } #endregion Non-Exported Function Unit Tests }