ps/Modules/Cole.PowerShell.Developer/Public/Merge-Objects.ps1
2023-05-30 22:51:22 -07:00

90 lines
3.1 KiB
PowerShell

function Merge-Objects {
<#
.SYNOPSIS
Used to merge two or more objects into a single output.
Two objects with the same name will replace the value of the former with the latter.
If two properties can be merged, they will be, as far down the stack as we can go.
.EXAMPLE
$FoundUser1 = [pscustomobject] @{
'Duplicate Group1' = 'test1'
'User2' = 'test2'
}
$FoundUser2 = [pscustomobject] @{
'Duplicate Group2' = 'test3'
'User1' = 'test4'
}
Merge-Objects -Objects $FoundUser1, $FoundUser2
.EXAMPLE
Mixin @{ cole = "name" },@{ test = @{ result = "passed" } },@{ cole = "replaced" },@{ test = @{ result = "double passed"; reason = "success" } }
#>
[CmdletBinding()]
[OutputType([object[]])]
param (
[Object[]]$Objects,
[switch]$DontClobber,
[switch]$DontDeepMerge
)
$logLead = (Get-LogLeadName)
# ensure it's an array of objects so we can iterate
$Objects = @($Objects)
$returnObject = [Ordered]@{}
$restrictedPropertyNames = @(
'IsReadOnly'
'IsFixedSize'
'IsSynchronized'
'Keys'
'Values'
'SyncRoot'
'Count'
)
foreach($object in $Objects) {
$properties = @($object.Keys)
if (!(Any $properties)) {
$properties = @($object.PSObject.Properties.Where({$_.MemberType -eq 'NoteProperty'}).Name)
}
if (!(Any $properties)) {
Write-Verbose "One of the objects presented does not have a parseable keys object property"
# Write-Verbose $object
continue
}
foreach ($property in $properties) {
if ($restrictedPropertyNames -contains $property) {
continue
}
if ($returnObject.Keys -contains $property) {
Write-Verbose "`$returnObject.$property.GetType() = [$(($returnObject.$property).GetType())]"
Write-Verbose "`$object.$property.GetType() = [$(($object.$property).GetType())]"
if (!$DontDeepMerge -and (($returnObject.$property).GetType().Name -eq 'Hashtable') -and (($object.$property).GetType().Name -eq 'Hashtable')) {
Write-Host "Merging two hashtables"
$temp = Merge-Objects @($returnObject.$property,$object.$property)
$returnObject.$property = $temp
} else {
if ($DontClobber) {
$temp = $returnObject.$property
$returnObject.$property = @($temp)
$returnObject.$property += $object.$property
} else {
Write-Verbose "$logLead : New object clobbered the property [$property] from a previous object."
$returnObject.$property = $object.$property
}
}
} else {
$returnObject += @{$property = $object.$property}
}
}
}
return [PSCustomObject]$returnObject
}
Set-Alias -Name Combine -Value Merge-Objects
Set-Alias -Name Mixin -Value Merge-Objects