private/Set-OSDeployPSDefaultParameterValues.ps1

function Set-OSDeployPSDefaultParameterValues {
    <#
    .SYNOPSIS
        Applies layered OSDeploy default parameter values
 
    .DESCRIPTION
        Loads flat key-value pairs from a module defaults JSON file, followed by an
        optional user defaults JSON file. User values are loaded last and replace matching
        module values. Before parsing, the function removes single-line and block comments.
 
        Every loaded value is written to both the global and module-script
        PSDefaultParameterValues dictionaries. Missing files are skipped. Read or parse
        failures produce warnings and do not stop processing of the other layer.
 
    .PARAMETER ModuleDefaultsPath
        Specifies the mandatory path to the module-shipped PSDefaultParameterValues.json file.
        A missing file is skipped with verbose output.
 
    .PARAMETER UserDefaultsPath
        Specifies the mandatory path value for the Boot-Assets override file. The file itself
        is optional; when absent, no user overrides are applied and no warning is written.
 
    .EXAMPLE
        PS> Set-OSDeployPSDefaultParameterValues -ModuleDefaultsPath 'C:\Modules\OSDeploy\core\PSDefaultParameterValues.json' -UserDefaultsPath 'C:\ProgramData\OSDeployCore\boot-assets\PSDefaultParameterValues.json'
 
        Loads module defaults and then applies any user overrides to both default-value dictionaries.
 
    .INPUTS
        None. This function does not accept pipeline input.
 
    .OUTPUTS
        None.
 
    .NOTES
        Author: David Segura
        Company: Recast Software
        Version: 1.0.0
        Date: 2026-08-28
 
        Modifies $global:PSDefaultParameterValues and $script:PSDefaultParameterValues.
 
    .LINK
        about_Parameters_Default_Values
    #>

    [CmdletBinding()]
    param (
        [Parameter(Mandatory)]
        [string]$ModuleDefaultsPath,

        [Parameter(Mandatory)]
        [string]$UserDefaultsPath
    )

    # Layer 1: module-shipped defaults
    if (Test-Path -LiteralPath $ModuleDefaultsPath -PathType Leaf) {
        try {
            $rawJson = Get-Content -LiteralPath $ModuleDefaultsPath -Raw -ErrorAction Stop
            $rawJson = $rawJson -replace '(?m)(?<=^([^"]|"[^"]*")*)//.*' -replace '(?ms)/\*.*?\*/'
            $moduleDefaults = ConvertFrom-Json $rawJson -ErrorAction Stop
            $moduleDefaults.PSObject.Properties | ForEach-Object {
                $global:PSDefaultParameterValues[$_.Name] = $_.Value
                $script:PSDefaultParameterValues[$_.Name] = $_.Value
                Write-Verbose "[$($MyInvocation.MyCommand.Name)] PSDefaultParameterValues (module): '$($_.Name)' = '$($_.Value)'"
            }
        }
        catch {
            Write-Warning "[$(Get-Date -Format s)] Failed to load module PSDefaultParameterValues from '$ModuleDefaultsPath': $_"
        }
    }
    else {
        Write-Verbose "[$($MyInvocation.MyCommand.Name)] Module defaults file not found: '$ModuleDefaultsPath'"
    }

    # Layer 2: user profile overrides (silent if absent, wins over layer 1)
    if (Test-Path -LiteralPath $UserDefaultsPath -PathType Leaf) {
        try {
            $rawSettings = Get-Content -LiteralPath $UserDefaultsPath -Raw -ErrorAction Stop
            $rawSettings = $rawSettings -replace '(?m)(?<=^([^"]*|"[^"]*")*)//.*' -replace '(?ms)/\*.*?\*/'
            $settings = ConvertFrom-Json $rawSettings -ErrorAction Stop
            $settings.PSObject.Properties | ForEach-Object {
                $global:PSDefaultParameterValues[$_.Name] = $_.Value
                $script:PSDefaultParameterValues[$_.Name] = $_.Value
                Write-Verbose "[$($MyInvocation.MyCommand.Name)] PSDefaultParameterValues (user): '$($_.Name)' = '$($_.Value)'"
            }
        }
        catch {
            Write-Warning "[$(Get-Date -Format s)] Failed to load user PSDefaultParameterValues from '$UserDefaultsPath': $_"
        }
    }
}