Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 14 additions & 6 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,14 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [Unreleased]

### Changed

- `Assert-BoundParameter`
- Enhanced parameter `IfParameterPresent` to support both string arrays and
hashtables for conditional assertion logic.
- Added alias `IfEqualParameterList` to parameter `IfParameterPresent` for
backward compatibility.

## [0.24.0] - 2025-08-26

### Added
Expand All @@ -18,18 +26,18 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Added parameter `IfEqualParameterList` to conditionally perform assertions
only when specified parameters have exact values [#160](https://github.com/dsccommunity/DscResource.Common/issues/160).
- `Format-Path`
- Added parameter `ExpandEnvironmentVariable` fixes [#147](https://github.com/dsccommunity/DscResource.Common/issues/147).
- Added support to `Compare-DscParameterState` for comparing large hashtables
that contain lists of elements.
- Added parameter `ExpandEnvironmentVariable` (issue [#147](https://github.com/dsccommunity/DscResource.Common/issues/147)).
- `Compare-DscParameterState`
- Added support for comparing large hashtables that contain lists of elements.

### Changed

- `Get-ComputerName`
- Replaced platform-specific logic with cross-platform implementation using
- Replaced platform-specific logic with cross-platform implementation using
`[System.Environment]::MachineName` for consistent short name behavior.
- Enhanced FQDN functionality to use `[System.Net.Dns]::GetHostByName()` for
- Enhanced FQDN functionality to use `[System.Net.Dns]::GetHostEntry()` for
proper domain name resolution on Windows, Linux, and macOS.
- Improved error handling to gracefully fallback to short name when DNS
- Improved error handling to gracefully fallback to short name when DNS
resolution fails.

## [0.22.0] - 2025-04-25
Expand Down
5 changes: 1 addition & 4 deletions source/Private/Assert-RequiredCommandParameter.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
Throws an exception if either of the two parameters are not specified.

.EXAMPLE
Assert-RequiredCommandParameter -BoundParameter $PSBoundParameters -RequiredParameter @('PBStartPortRange', 'PBEndPortRange') -RequiredBehavior 'AtLeastOnce'
Assert-RequiredCommandParameter -BoundParameter $PSBoundParameters -RequiredParameter @('PBStartPortRange', 'PBEndPortRange') -RequiredBehavior 'Any'

Throws an exception if at least one of the two parameters are not specified.

Expand Down Expand Up @@ -84,7 +84,6 @@ function Assert-RequiredCommandParameter
{
$errorMessage = if ($PSBoundParameters.ContainsKey('IfParameterPresent'))
{

$script:localizedData.RequiredCommandParameter_SpecificParametersMustAllBeSetWhenParameterExist -f ($RequiredParameter -join ''', '''), ($IfParameterPresent -join ''', ''')
}
else
Expand Down Expand Up @@ -116,7 +115,6 @@ function Assert-RequiredCommandParameter
{
$errorMessage = if ($PSBoundParameters.ContainsKey('IfParameterPresent'))
{

$script:localizedData.RequiredCommandParameter_SpecificParametersAtLeastOneMustBeSetWhenParameterExist -f ($RequiredParameter -join ''', '''), ($IfParameterPresent -join ''', ''')
}
else
Expand All @@ -137,6 +135,5 @@ function Assert-RequiredCommandParameter
break
}
}

}
}
68 changes: 45 additions & 23 deletions source/Public/Assert-BoundParameter.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -52,10 +52,9 @@
If neither of the parameter names has been specified the evaluation of required
parameters are not made.

.PARAMETER IfEqualParameterList
A hashtable of parameter names and their expected values. The assertion will
only be performed if all the specified parameters in the BoundParameterList
have the exact values specified in this hashtable.
This parameter can also accept a hashtable of parameter names and their expected
values. The assertion will only be performed if all the specified parameters in
the BoundParameterList have the exact values specified in this hashtable.

.PARAMETER AtLeastOneList
An array of parameter names where at least one must be bound.
Expand Down Expand Up @@ -110,7 +109,7 @@
MutuallyExclusiveList2 = @(
'MessageId'
)
IfEqualParameterList = @{
IfParameterPresent = @{
Ensure = 'Present'
}
}
Expand All @@ -121,13 +120,13 @@
the value `Present`.

.EXAMPLE
Assert-BoundParameter -BoundParameterList $PSBoundParameters -RequiredParameter @('Property2', 'Property3') -IfEqualParameterList @{ Property1 = 'SpecificValue' }
Assert-BoundParameter -BoundParameterList $PSBoundParameters -RequiredParameter @('Property2', 'Property3') -IfParameterPresent @{ Property1 = 'SpecificValue' }

Throws an exception if the parameter 'Property1' has the value 'SpecificValue'
and either of the required parameters are not specified.

.EXAMPLE
Assert-BoundParameter -BoundParameterList $PSBoundParameters -AtLeastOneList @('Severity', 'MessageId') -IfEqualParameterList @{ Ensure = 'Present' }
Assert-BoundParameter -BoundParameterList $PSBoundParameters -AtLeastOneList @('Severity', 'MessageId') -IfParameterPresent @{ Ensure = 'Present' }

Throws an exception if the parameter 'Ensure' has the value 'Present' and
none of the parameters 'Severity' or 'MessageId' are specified.
Expand Down Expand Up @@ -159,26 +158,37 @@ function Assert-BoundParameter
$RequiredBehavior = [BoundParameterBehavior]::All,

[Parameter(ParameterSetName = 'RequiredParameter')]
[System.String[]]
$IfParameterPresent,

[Parameter(ParameterSetName = 'MutuallyExclusiveParameters')]
[Parameter(ParameterSetName = 'RequiredParameter')]
[Parameter(ParameterSetName = 'AtLeastOne')]
[System.Collections.Hashtable]
$IfEqualParameterList,
[Alias('IfEqualParameterList')]
[System.Object]
$IfParameterPresent,

[Parameter(ParameterSetName = 'AtLeastOne', Mandatory = $true)]
[System.String[]]
$AtLeastOneList
)

# Early return if IfEqualParameterList conditions are not met
if ($PSBoundParameters.ContainsKey('IfEqualParameterList'))
# Early return if IfParameterPresent conditions are not met
if ($PSBoundParameters.ContainsKey('IfParameterPresent'))
{
foreach ($parameterName in $IfEqualParameterList.Keys)
if ($IfParameterPresent -is [System.Collections.Hashtable])
{
if (-not $BoundParameterList.ContainsKey($parameterName) -or $BoundParameterList[$parameterName] -ne $IfEqualParameterList[$parameterName])
# Handle hashtable case (original IfEqualParameterList behavior)
foreach ($parameterName in $IfParameterPresent.Keys)
{
if (-not $BoundParameterList.ContainsKey($parameterName) -or $BoundParameterList[$parameterName] -ne $IfParameterPresent[$parameterName])
{
return
}
}
}
else
{
# Handle string array case (original IfParameterPresent behavior)
$hasIfParameterPresent = $BoundParameterList.Keys.Where( { $_ -in $IfParameterPresent } )

if (-not $hasIfParameterPresent)
{
return
}
Expand Down Expand Up @@ -207,17 +217,29 @@ function Assert-BoundParameter

'RequiredParameter'
{
if ($PSBoundParameters.ContainsKey('IfEqualParameterList'))
{
$PSBoundParameters.Remove('IfEqualParameterList')
$assertRequiredCommandParameterParams = @{
BoundParameterList = $BoundParameterList
RequiredParameter = $RequiredParameter
RequiredBehavior = $RequiredBehavior
}

if (-not $PSBoundParameters.ContainsKey('RequiredBehavior'))
# Pass IfParameterPresent to Assert-RequiredCommandParameter for better error messages
if ($PSBoundParameters.ContainsKey('IfParameterPresent'))
{
$PSBoundParameters.RequiredBehavior = $RequiredBehavior
if ($IfParameterPresent -is [System.Collections.Hashtable])
{
# For hashtable case, pass the keys as IfParameterPresent
$assertRequiredCommandParameterParams.IfParameterPresent = $IfParameterPresent.Keys
}
else
{
# For string array case, pass as-is
$assertRequiredCommandParameterParams.IfParameterPresent = $IfParameterPresent
}
}

Assert-RequiredCommandParameter @PSBoundParameters
Assert-RequiredCommandParameter @assertRequiredCommandParameterParams

break
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,9 @@ BeforeDiscovery {
}

BeforeAll {
$script:dscModuleName = 'DscResource.Common'
$script:moduleName = 'DscResource.Common'

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

Describe 'Assert-BoundParameter Integration Tests' -Tag 'AssertBoundParameterIntegration' {
Expand Down Expand Up @@ -693,29 +693,6 @@ Describe 'Assert-BoundParameter Integration Tests' -Tag 'AssertBoundParameterInt
Assert-BoundParameter @assertBoundParameterParameters
} | Should -Not -Throw
}

It 'Should work with multiple conditions and IfParameterPresent together' {
{
$assertBoundParameterParameters = @{
BoundParameterList = @{
ConfigType = 'Advanced'
Environment = 'Production'
TriggerParam = 'Present'
Param1 = 'Value1'
Param2 = 'Value2'
}
RequiredParameter = @('Param1', 'Param2')
IfParameterPresent = @('TriggerParam')
IfEqualParameterList = @{
ConfigType = 'Advanced'
Environment = 'Production'
}
ErrorAction = 'Stop'
}

Assert-BoundParameter @assertBoundParameterParameters
} | Should -Not -Throw
}
}

Context 'When the IfEqualParameterList condition is not met' {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,9 @@ BeforeDiscovery {
}

BeforeAll {
$script:dscModuleName = 'DscResource.Common'
$script:moduleName = 'DscResource.Common'

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

Describe 'Get-ComputerName' -Tag 'GetComputerName' {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,9 @@ BeforeDiscovery {
}

BeforeAll {
$script:dscModuleName = 'DscResource.Common'
$script:moduleName = 'DscResource.Common'

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

Describe 'Set-DscMachineRebootRequired' -Tag 'Set-DscMachineRebootRequired' {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,9 +36,9 @@ BeforeDiscovery {
}

BeforeAll {
$script:dscModuleName = 'DscResource.Common'
$script:moduleName = 'DscResource.Common'

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

Describe 'Set-PSModulePath' -Tag 'SetPSModulePath' {
Expand Down
6 changes: 3 additions & 3 deletions tests/Unit/Private/Assert-RequiredCommandParameter.Tests.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ BeforeAll {
# Make sure there are not other modules imported that will conflict with mocks.
Get-Module -Name $script:moduleName -All | Remove-Module -Force

Import-Module -Name $script:moduleName
Import-Module -Name $script:moduleName -Force -ErrorAction 'Stop'

$PSDefaultParameterValues['InModuleScope:ModuleName'] = $script:moduleName
$PSDefaultParameterValues['Mock:ModuleName'] = $script:moduleName
Expand Down Expand Up @@ -144,7 +144,7 @@ Describe 'Assert-RequiredCommandParameter' -Tag 'Private' {
}

Context 'When the parameters in IfParameterPresent is present and required parameters are present' {
It 'Should throw the correct error' {
It 'Should not throw an error' {
InModuleScope -ScriptBlock {
Set-StrictMode -Version 1.0

Expand Down Expand Up @@ -240,7 +240,7 @@ Describe 'Assert-RequiredCommandParameter' -Tag 'Private' {
}

Context 'When the parameters in IfParameterPresent is present and one of the required parameters are present' {
It 'Should throw the correct error' {
It 'Should not throw an error' {
InModuleScope -ScriptBlock {
Set-StrictMode -Version 1.0

Expand Down
2 changes: 1 addition & 1 deletion tests/Unit/Private/Clear-ZeroedEnumPropertyValue.Tests.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ BeforeAll {
# Make sure there are not other modules imported that will conflict with mocks.
Get-Module -Name $script:moduleName -All | Remove-Module -Force

Import-Module -Name $script:moduleName
Import-Module -Name $script:moduleName -Force -ErrorAction 'Stop'

$PSDefaultParameterValues['InModuleScope:ModuleName'] = $script:moduleName
$PSDefaultParameterValues['Mock:ModuleName'] = $script:moduleName
Expand Down
12 changes: 6 additions & 6 deletions tests/Unit/Private/Test-DscPropertyIsAssigned.Tests.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -24,13 +24,13 @@ BeforeDiscovery {
}

BeforeAll {
$script:dscModuleName = 'DscResource.Common'
$script:moduleName = 'DscResource.Common'

Import-Module -Name $script:dscModuleName
Import-Module -Name $script:moduleName -Force -ErrorAction 'Stop'
Comment thread
johlju marked this conversation as resolved.

$PSDefaultParameterValues['InModuleScope:ModuleName'] = $script:dscModuleName
$PSDefaultParameterValues['Mock:ModuleName'] = $script:dscModuleName
$PSDefaultParameterValues['Should:ModuleName'] = $script:dscModuleName
$PSDefaultParameterValues['InModuleScope:ModuleName'] = $script:moduleName
$PSDefaultParameterValues['Mock:ModuleName'] = $script:moduleName
$PSDefaultParameterValues['Should:ModuleName'] = $script:moduleName
}

AfterAll {
Expand All @@ -39,7 +39,7 @@ AfterAll {
$PSDefaultParameterValues.Remove('Should:ModuleName')

# Unload the module being tested so that it doesn't impact any other tests.
Get-Module -Name $script:dscModuleName -All | Remove-Module -Force
Get-Module -Name $script:moduleName -All | Remove-Module -Force
}

Describe 'Test-DscPropertyIsAssigned' -Tag 'Private' {
Expand Down
Loading