Private/Merge-Object.ps1
function Merge-Object { [CmdletBinding()] [OutputType([PSCustomObject])] [OutputType([System.Collections.Specialized.OrderedDictionary])] param( [Parameter(Mandatory = $true)] [ValidateNotNullOrEmpty()] [PSObject] $FirstObject, [Parameter(Mandatory = $false)] [ValidateNotNullOrEmpty()] [string] $FirstObjectName, [Parameter(Mandatory = $true)] [ValidateNotNullOrEmpty()] [PSObject] $SecondObject, [Parameter(Mandatory = $false)] [ValidateNotNullOrEmpty()] [string] $SecondObjectName, [Parameter(Mandatory = $false)] [switch] $AsHashtable ) begin { Write-Debug 'Starting Merge-Object' } process { $firstObjectProperties = $FirstObject | Get-Member -MemberType 'Properties' | Select-Object -ExpandProperty 'Name' $secondObjectProperties = $SecondObject | Get-Member -MemberType 'Properties' | Select-Object -ExpandProperty 'Name' $uniqueFirstObjectProperties = $firstObjectProperties | Where-Object { $_ -notin $secondObjectProperties } $uniqueSecondObjectProperties = $secondObjectProperties | Where-Object { $_ -notin $firstObjectProperties } $sharedProperties = $firstObjectProperties | Where-Object { $_ -in $secondObjectProperties } $result = [ordered]@{} # Add unique properties from both objects foreach ($property in $uniqueFirstObjectProperties) { $result[$property] = $FirstObject.$property } foreach ($property in $uniqueSecondObjectProperties) { $result[$property] = $SecondObject.$property } # Add shared properties with handling for different values # If the values are the same, just use one value # If they differ, create a hashtable with both values # If FirstObjectName or SecondObjectName are provided, use them as keys in the hashtable # Otherwise, use generic keys 'FirstObject' and 'SecondObject' foreach ($property in $sharedProperties) { if ($FirstObject.$property -eq $SecondObject.$property) { $result[$property] = $FirstObject.$property } else { $result[$property] = @{} if ($PSBoundParameters.ContainsKey('FirstObjectName')) { $result[$property][$FirstObjectName] = $FirstObject.$property } else { $result[$property]['FirstObject'] = $FirstObject.$property } if ($PSBoundParameters.ContainsKey('SecondObjectName')) { $result[$property][$SecondObjectName] = $SecondObject.$property } else { $result[$property]['SecondObject'] = $SecondObject.$property } } } # Add the original objects to the result, using the provided names if available if ($PSBoundParameters.ContainsKey('FirstObjectName')) { $result[$FirstObjectName] = $FirstObject } else { $result['FirstObject'] = $FirstObject } if ($PSBoundParameters.ContainsKey('SecondObjectName')) { $result[$SecondObjectName] = $SecondObject } else { $result['SecondObject'] = $SecondObject } if ($AsHashtable) { $result } else { [PSCustomObject]$result } } end { Write-Debug 'Finished Merge-Object' } } |