Skip to content

Instantly share code, notes, and snippets.

@Master-Guy
Created November 6, 2021 13:32
Show Gist options
  • Select an option

  • Save Master-Guy/c4e57464c33857c869a72f8c11b25ea0 to your computer and use it in GitHub Desktop.

Select an option

Save Master-Guy/c4e57464c33857c869a72f8c11b25ea0 to your computer and use it in GitHub Desktop.
Merge two JSON files
# Function to merge two JSON files, where the 2nd will override any settings in the 1st with the same name.
# Original by https://github.com/Master-Guy (Discord: Master-Guy#0001)
function JsonMerge {
param(
[Parameter(Mandatory)]
[PSCustomObject] $Json1,
[Parameter(Mandatory)]
[PSCustomObject] $Json2,
[parameter(DontShow)]
[int] $Nesting = 0,
[parameter(DontShow)]
[string] $VerboseInfo = ""
)
if($Json1.GetType().Name -eq "PSCustomObject" -and $Json2.GetType().Name -eq "PSCustomObject") {
Write-Verbose "[${Nesting}] === Beginning JSON merge === ${VerboseInfo}"
$ModifiedJson = $Json1
# Loop over all the properties in the 2nd Json object
foreach($property in $Json2 | Get-Member -type NoteProperty, Property) {
$propertyName = $property.Name
$propertyValue = $Json2.$($propertyName)
$propertyType = $propertyValue.GetType().Name
Write-Verbose "[${Nesting}] Property found: ${propertyName} = [${propertyType}] ${propertyValue} ${VerboseInfo}"
# Check if the property already exists
if($null -eq $ModifiedJson.$($propertyName)) {
# If property does not yet exist, add it
Write-Verbose "[${Nesting}] Addign new property: ${propertyName} ${VerboseInfo}"
$ModifiedJson | Add-Member -Name $propertyName -Value $propertyValue -MemberType NoteProperty
} else {
Write-Verbose "[${Nesting}] Property already exists: ${propertyName} ${VerboseInfo}"
# If the property already exists, iterate through the values and merge them
if($propertyType -eq "PSCustomObject") {
# Recursive merge
Write-Verbose "[${Nesting}] Recursivly merging: ${propertyName} ${VerboseInfo}"
$curValue = $Json1.$($propertyName)
$appValue = $propertyValue
$NextNestLevel = $Nesting + 1
$newValue = JsonMerge -Json1 $curValue -Json2 $appValue -Nesting $NextNestLevel -VerboseInfo "${VerboseInfo}/${propertyName}"
$ModifiedJson | Add-Member -Name $propertyName -Value $newValue -MemberType NoteProperty -Force
} else {
# Override existing value
Write-Verbose "[${Nesting}] Overriding value: ${propertyName} ${VerboseInfo}"
$ModifiedJson | Add-Member -Name $propertyName -Value $propertyValue -MemberType NoteProperty -Force
}
}
}
Write-Verbose "[${Nesting}] === Finishing JSON merge === ${VerboseInfo}"
} else {
Write-Host "Error! JsonMerge got non-object parameters:"
Write-Host "Json1:"
Write-Host $Json1.GetType().Name
Write-Host "Json2:"
Write-Host $Json2.GetType().Name
}
return $ModifiedJson
}
$SettingsPath = ".\file1.json"
$SettingsJson = Get-Content $SettingsPath -Raw | ConvertFrom-Json
$PreferredSettingsPath = ".\file2.json"
$PreferredSettingsJson = Get-Content $PreferredSettingsPath -Raw | ConvertFrom-Json
$CombinedJson = JsonMerge -Json1 $SettingsJson -Json2 $PreferredSettingsJson -Verbose
$CombinedJson | ConvertTo-Json -Depth 32 | Out-File $SettingsPath
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment