Private/Merge-AACObject.ps1
|
function Merge-AACObject { <# .SYNOPSIS A copy of -Base with -Overlay's values laid over it, at every level of nested dictionaries; lists and plain values in -Overlay replace -Base's. .DESCRIPTION Keys match case-insensitively; -Overlay's spelling wins. Neither input is changed. Used to send a resource's current settings with the desired ones merged in, so the settings a deployment doesn't manage stay as they are. #> [CmdletBinding()] [OutputType([System.Collections.Specialized.OrderedDictionary])] param( [AllowNull()] [System.Collections.IDictionary] $Base, [AllowNull()] [System.Collections.IDictionary] $Overlay ) $out = [ordered]@{} if ($Base) { foreach ($key in $Base.Keys) { $out[[string]$key] = $Base[$key] } } if ($Overlay) { foreach ($key in $Overlay.Keys) { $existing = @($out.Keys | Where-Object { $_ -ieq [string]$key }) | Select-AACFirst 1 $value = $Overlay[$key] if ($null -ne $existing) { $old = $out[$existing] $out.Remove($existing) $out[[string]$key] = if ($value -is [System.Collections.IDictionary] -and $old -is [System.Collections.IDictionary]) { Merge-AACObject -Base $old -Overlay $value } else { $value } } else { $out[[string]$key] = $value } } } $out } |