如何用PowerShell向JSON书签指定节点添加条目合并Chrome与Edge书签
PowerShell 合并Chrome与Edge书签可实施方案
直接拼接两个书签JSON文件后无法被Edge识别,核心原因有三点:
- 书签文件内所有书签、文件夹条目的
id字段要求全局唯一,直接合并会出现大量重复id - 书签存在多层嵌套结构,默认JSON序列化深度不足会导致深层内容被截断,结构损坏
- 输出文件编码不符合要求、原校验值失效也会导致加载失败,其中校验值不需要手动计算,浏览器识别到结构合法后会自动重新生成
合并逻辑
你已经完成两个书签文件的读取与JSON解析,后续按以下逻辑处理即可:
- 以Edge原书签文件作为合并基底,保留Edge原有书签结构
- 递归遍历基底所有节点,记录当前已使用的最大id值
- 遍历Chrome书签中
bookmark_bar、other两个目标节点的子条目,递归为所有条目分配不重复的新id、生成新的唯一guid,避免标识冲突 - 将修正后的Chrome书签条目追加到Edge对应节点的子列表中,更新对应文件夹的最后修改时间戳
- 清空原校验值,以足够的序列化深度、UTF-8无BOM编码输出最终文件
完整实现代码
在你已编写的读取代码后,补充以下内容即可:
# 以Edge书签数据作为合并基底 $mergedBookmark = $data2 # 指定需要合并的根节点 $targetNodes = @("bookmark_bar", "other") # 递归获取节点下所有书签id function Get-AllExistedIds { param($currentNode) $idList = @() if ($currentNode.id) { $idList += [int]$currentNode.id } if ($currentNode.children) { foreach ($child in $currentNode.children) { $idList += Get-AllExistedIds $child } } return $idList } # 递归重排书签id、替换guid,保证全局唯一 function Reset-BookmarkIdentifier { param($currentNode, [ref]$startId) $startId.Value += 1 $currentNode.id = $startId.Value.ToString() $currentNode.guid = [guid]::NewGuid().ToString() if ($currentNode.children) { foreach ($child in $currentNode.children) { Reset-BookmarkIdentifier $child $startId } } } # 计算基底文件当前最大id $existedIds = Get-AllExistedIds $mergedBookmark.roots $currentMaxId = ($existedIds | Measure-Object -Maximum).Maximum # 逐个合并目标节点内容 foreach ($node in $targetNodes) { $chromeItems = $store1.$node.children if (-not $chromeItems -or $chromeItems.Count -eq 0) { continue } # 修正所有待合并条目的标识 foreach ($item in $chromeItems) { Reset-BookmarkIdentifier $item ([ref]$currentMaxId) } # 追加到对应节点 $mergedBookmark.roots.$node.children += $chromeItems # 更新节点修改时间(采用Chrome/Edge使用的1601纪元100纳秒时间戳格式) $mergedBookmark.roots.$node.date_modified = [DateTimeOffset]::UtcNow.ToFileTimeUtc().ToString() } # 清空原有校验和,浏览器加载时会自动计算新值 $mergedBookmark.checksum = "" # 输出合并后的文件,注意使用UTF8无BOM编码、足够的序列化深度 $outputPath = Join-Path $BackupStore "Merged-Bookmarks.json" $mergedBookmark | ConvertTo-Json -Depth 100 | Out-File -FilePath $outputPath -Encoding utf8NoBOM
验证与替换注意事项
- 替换Edge书签前务必关闭所有Edge进程,否则文件会被占用导致替换失败,同时建议提前备份原书签文件
ConvertTo-Json必须指定-Depth 100参数,默认序列化深度仅为2,会导致嵌套的书签文件夹内容被截断- 若使用PowerShell 5.1 没有
utf8NoBOM编码选项,可以先输出内容后用其他编辑器转成无BOM的UTF-8格式,带BOM的文件会被Edge识别为损坏 - 替换完成后启动Edge,浏览器会自动校验文件结构、重算checksum,合并的书签会正常显示在书签栏和其他书签目录下
内容的提问来源于stack exchange,提问作者Michalis
相关产品推荐
相关产品推荐

