Utilities/Merge-ObjectDeep.ps1
function Merge-ObjectDeep { param( [Parameter(Mandatory)] $Base, [Parameter(Mandatory)] $Override ) if ($null -eq $Override) { return $Base } function _ToHashtable($o) { if ($null -eq $o) { return $null } if ($o -is [hashtable]) { return $o } if ($o -is [pscustomobject]) { $ht = @{} foreach ($prop in $o.PSObject.Properties) { $ht[$prop.Name] = $prop.Value } return $ht } return $o } $bIsMap = ($Base -is [hashtable] -or $Base -is [pscustomobject]) $oIsMap = ($Override -is [hashtable] -or $Override -is [pscustomobject]) if ($bIsMap -or $oIsMap) { $b = _ToHashtable $Base $o = _ToHashtable $Override $resultIsPso = ($Base -is [pscustomobject]) $result = if ($resultIsPso) { [pscustomobject]@{} } else { @{} } $bKeys = if ($b) { $b.Keys } else { @() } $oKeys = if ($o) { $o.Keys } else { @() } $allKeys = @($bKeys + $oKeys | Select-Object -Unique) foreach ($k in $allKeys) { $bv = if ($b -and $b.ContainsKey($k)) { $b[$k] } else { $null } $ov = if ($o -and $o.ContainsKey($k)) { $o[$k] } else { $null } $val = if ($null -ne $ov -and ($bv -is [hashtable] -or $bv -is [pscustomobject])) { Merge-ObjectDeep $bv $ov } elseif ($null -ne $ov) { $ov } else { $bv } if ($resultIsPso) { $result | Add-Member -NotePropertyName $k -NotePropertyValue $val } else { $result[$k] = $val } } return $result } # arrays/scalars: override wins if provided if ($null -ne $Override) { return $Override } return $Base } |