PowerShell中向JSON文件添加HashTable的正确方法及优化方案咨询
问题描述
我有如下哈希表:
$a = @{ "computer1" = @{ "app1" = "2023.04.04" "app2" = "2022.07.11" }}
需要将其添加到文件$jsonReportPath = "./report.json"中,要求:
- 添加前文件可能不存在
- 封装为函数,接收哈希表作为参数
- 仅当哈希表的键(如示例中的"computer1")未在JSON文件中存在时,才执行添加操作
- 不替换现有内容,仅新增条目
例如初始JSON内容:
{ "computer": { "program": "22.9.0.135", "program1": "4.0.1.23758" }, "computer0": { "program": "22.5.0.135", "program1": "4.7.1.23758" } }
添加后应变为:
{ "computer": { "program": "22.9.0.135", "program1": "4.0.1.23758" }, "computer0": { "program": "22.5.0.135", "program1": "4.7.1.23758" }, "computer1": { "app1": "2023.04.04", "app2": "2022.07.11" } }
我自己编写了一个函数,但觉得实现略显繁琐,想了解更优、更规范的写法:
function AddItemToJsonReport([Hashtable]$item) { $jsonReportPath = "C:\path\to\json\report.json" $report = Get-Content -Path $jsonReportPath -Raw | ConvertFrom-Json -AsHashtable if (-not $report) { $report = @{} } # If the json report is empty, initialize it as an empty hashtable $nodeName = $item.PSObject.Properties.Name # Get the key of the hashtable, the node name # If the node already exists in the json report, don't add it again if ($report.ContainsKey($nodeName)) { return } $item.GetEnumerator() | ForEach-Object { $report[$.Key] = $.Value } $updatedJsonReport = ConvertTo-Json $report -Depth 100 $fileExists = Test-Path $jsonReportPath if ($fileExists) { Out-File -FilePath $jsonReportPath -InputObject $updatedJsonReport -Encoding utf8 } }
优化后的实现
以下是更简洁规范的函数版本,解决了原代码的冗余问题,同时完善了边界场景处理:
function Add-ComputerToJsonReport { [CmdletBinding()] param( [Parameter(Mandatory=$true)] [Hashtable]$ComputerData, [string]$JsonPath = "./report.json" ) # 读取现有JSON或初始化空哈希表 $report = if (Test-Path $JsonPath) { Get-Content -Path $JsonPath -Raw | ConvertFrom-Json -AsHashtable -ErrorAction SilentlyContinue } $report ??= @{} # 获取传入哈希表的唯一键(假设传入的是单键哈希表) $computerName = $ComputerData.Keys | Select-Object -First 1 if (-not $computerName) { return } # 检查键是否已存在,存在则直接返回 if ($report.ContainsKey($computerName)) { Write-Verbose "计算机 $computerName 已在报告中,跳过添加" return } # 添加新条目并写入文件 $report[$computerName] = $ComputerData[$computerName] $report | ConvertTo-Json -Depth 100 | Set-Content -Path $JsonPath -Encoding UTF8 }
优化点说明
- 参数化设计:将文件路径设为可选参数,提升函数的复用性和灵活性
- 简化初始化逻辑:使用PowerShell 7+的
??=空合并赋值运算符,替代冗余的if判断,代码更简洁 - 高效获取键:直接通过
$ComputerData.Keys获取哈希表键,比PSObject.Properties.Name更直观高效 - 简化写入流程:使用
Set-Content替代Out-File,无需单独判断文件是否存在(Set-Content会自动创建不存在的文件) - 调试友好:添加
Write-Verbose输出,便于跟踪执行状态 - 符合命名规范:采用PowerShell标准的动词-名词函数命名格式(
Add-ComputerToJsonReport),可读性更强 - 错误处理优化:添加
-ErrorAction SilentlyContinue,避免文件为空或格式异常时的转换报错
内容的提问来源于stack exchange,提问作者Andrei Suslov
相关产品推荐
相关产品推荐

