Skip to content

Commit

Permalink
Fixed Compare-DscParameterState returning false positive when paramet…
Browse files Browse the repository at this point in the history
…er with an empty hashtable or CimInstance property is passed in DesriedValues - fixes issue dsccommunity#65 (dsccommunity#76)
  • Loading branch information
NicolasBn authored Sep 10, 2021
1 parent 8d7f8d6 commit c816a09
Show file tree
Hide file tree
Showing 4 changed files with 481 additions and 13 deletions.
16 changes: 16 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,22 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [Unreleased]

### Fixed

- Correction to `Compare-DscParameterState` returning false positive when parameter
with an empty hashtable or CimInstance property is passed in `DesriedValues` - fixes
[issue #65](https://github.com/dsccommunity/DscResource.Common/issues/65).
- Correction somes problems in `Compare-DscParameterState` - see [issue #70](https://github.com/dsccommunity/DscResource.Common/issues/70) :
- When you use `-ReverseCheck`, this value is used in recursive call of
`Test-DscParameterState` and `Compare-DscParameterState`, and that called
another time the function.
- When you use `-Properties` and `-ReverseCheck`, and you have an array in member,
that return a wrong value, because the properties are set in recursive calls of
`-ReverseCheck` to test the value of array.
- When you use `-ReverseCheck` and, in the function `Test-DscCompareState`/`Compare-DscParameterState`
are recursively called (like to test or compare value of array), `-ReverseCheck`
value is removed from `$PSBoundParameters`. And the ReverseCheck isn't done.

## [0.10.3] - 2021-06-26

### Added
Expand Down
43 changes: 33 additions & 10 deletions source/Public/Compare-DscParameterState.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -322,6 +322,12 @@ function Compare-DscParameterState
$InDesiredStateTable.InDesiredState = $false
continue # pass to the next key
}
elseif ($desiredType.Name -eq 'Unknown' -and $desiredType.Name -ne $currentType.Name)
{
Write-Verbose -Message ($script:localizedData.NoMatchTypeMismatchMessage -f $key, $currentType.Name, $desiredType.Name)
$InDesiredStateTable.InDesiredState = $false
continue # pass to the next key
}
}
#endregion TestType
#region Check if the value of Current and desired state is the same but only if they are not an array
Expand All @@ -331,7 +337,7 @@ function Compare-DscParameterState
continue # pass to the next key
}
#endregion check same value
#region Check if the DesiredValuesClean has the key and if it don't have, it's not necessary to check his value
#region Check if the DesiredValuesClean has the key and if it doesn't have, it's not necessary to check his value
if ($desiredValuesClean.GetType().Name -in 'HashTable', 'PSBoundParametersDictionary')
{
$checkDesiredValue = $desiredValuesClean.ContainsKey($key)
Expand Down Expand Up @@ -455,11 +461,11 @@ function Compare-DscParameterState

if ($desiredType -eq [System.Collections.Hashtable] -and $currentType -eq [System.Collections.Hashtable])
{
$param = $PSBoundParameters
$param = @{} + $PSBoundParameters
$param.CurrentValues = $currentArrayValues[$i]
$param.DesiredValues = $desiredArrayValues[$i]

'IncludeInDesiredState','IncludeValue' | ForEach-Object {
'IncludeInDesiredState','IncludeValue','Properties','ReverseCheck' | ForEach-Object {
if ($param.ContainsKey($_))
{
$null = $param.Remove($_)
Expand Down Expand Up @@ -494,11 +500,11 @@ function Compare-DscParameterState
}
elseif ($desiredType -eq [System.Collections.Hashtable] -and $currentType -eq [System.Collections.Hashtable])
{
$param = $PSBoundParameters
$param = @{} + $PSBoundParameters
$param.CurrentValues = $currentValue
$param.DesiredValues = $desiredValue

'IncludeInDesiredState','IncludeValue' | ForEach-Object {
'IncludeInDesiredState','IncludeValue','Properties','ReverseCheck' | ForEach-Object {
if ($param.ContainsKey($_))
{
$null = $param.Remove($_)
Expand All @@ -507,11 +513,22 @@ function Compare-DscParameterState

if ($InDesiredStateTable.InDesiredState)
{
$InDesiredStateTable.InDesiredState = Test-DscParameterState @param
<#
if desiredvalue is an empty hashtable and not currentvalue, it's not necessery to compare them, it's not compliant.
See issue 65 https://github.com/dsccommunity/DscResource.Common/issues/65
#>
if ($desiredValue.Keys.Count -eq 0 -and $currentValue.Keys.Count -ne 0)
{
Write-Verbose -Message ($script:localizedData.NoMatchKeyMessage -f $desiredType.FullName, $key, $($currentValue.Keys -join ', '))
$InDesiredStateTable.InDesiredState = $false
}
else{
$InDesiredStateTable.InDesiredState = Test-DscParameterState @param
}
}
else
{
Test-DscParameterState @param | Out-Null
$null = Test-DscParameterState @param
}
continue
}
Expand Down Expand Up @@ -555,9 +572,15 @@ function Compare-DscParameterState
if ($ReverseCheck)
{
Write-Verbose -Message $script:localizedData.StartingReverseCheck
$reverseCheckParameters = $PSBoundParameters
$reverseCheckParameters.CurrentValues = $DesiredValues
$reverseCheckParameters.DesiredValues = $CurrentValues
$reverseCheckParameters = @{} + $PSBoundParameters
$reverseCheckParameters['CurrentValues'] = $DesiredValues
$reverseCheckParameters['DesiredValues'] = $CurrentValues
$reverseCheckParameters['Properties'] = $keyList + $CurrentValues.Keys | Select-Object -Unique
if ($ExcludeProperties)
{
$reverseCheckParameters['Properties'] = $reverseCheckParameters['Properties'] | Where-Object -FilterScript { $_ -notin $ExcludeProperties }
}

$null = $reverseCheckParameters.Remove('ReverseCheck')

if ($returnValue)
Expand Down
1 change: 1 addition & 0 deletions source/en-US/DscResource.Common.strings.psd1
Original file line number Diff line number Diff line change
Expand Up @@ -35,4 +35,5 @@ ConvertFrom-StringData @'
PropertyInDesiredState = The parameter '{0}' is in desired state. (DRC0039)
PropertyNotInDesiredState = The parameter '{0}' is not in desired state. (DRC0040)
PropertyNotInDesiredStateMessage = Property '{0}' is not in desired state. (DRC0041)
NoMatchKeyMessage = NOTMATCH: Value (type '{0}') for property '{1}' does not match. Current state has the key(s) '{2}' and desired state has not. (DRC0042)
'@
Loading

0 comments on commit c816a09

Please sign in to comment.