PowerShell基于外部JSON修改appsettings.json:值未更新问题排查
问题排查与修复:PowerShell脚本未更新appsettings.json配置值
你的脚本能成功删除JSON注释,但无法更新目标配置值,核心有三个问题:
1. 替换值读取路径错误
原代码读取替换值时多嵌套了一层.value,导致获取不到正确的替换内容。每个变量对象的结构是{"isSecret": null, "value": "目标值"},直接取value属性即可。
原错误代码:
$value = $replacementData.variables.PSObject.Properties["$key"].value.value
修复后代码:
$value = $replacementData.variables.$key.value
2. 嵌套属性修改未作用到原JSON对象
原代码遍历嵌套路径时,仅将$property变量指向了目标属性,但最后$property = $value只是修改了变量本身的引用,并没有改变$jsonContent里的实际配置值。需要跟踪父对象,直接修改父对象的属性。
原错误代码段:
$pathParts = $key -split "\." # Splitting the key $property = $null foreach ($keyPart in $pathParts) { Write-Host $keyPart if($property -eq $null) { $property = $jsonContent.PSObject.Properties[$keyPart] } else { $property = $property.$keyPart } Write-Host $property } if($property -ne $null) { Write-Host "setting '$key': '$value'" $property = $value }
修复后代码段:
$pathParts = $key -split "\." $currentObj = $jsonContent $lastPartIndex = $pathParts.Count - 1 # 遍历到父对象层级 for ($i = 0; $i -lt $lastPartIndex; $i++) { $part = $pathParts[$i] $currentObj = $currentObj.$part if (-not $currentObj) { Write-Warning "路径部分 '$part' 不存在,跳过键 '$key'" continue } } # 修改最终属性 $finalProperty = $pathParts[$lastPartIndex] if ($currentObj.PSObject.Properties[$finalProperty]) { Write-Host "设置 '$key': '$value'" $currentObj.$finalProperty = $value } else { Write-Warning "属性 '$finalProperty' 不存在,跳过键 '$key'" }
3. 处理首个文件后提前退出
原脚本在处理完第一个appsettings.json后执行了exit,导致后续文件无法被处理,直接删除该exit即可。
完整修复后的脚本
# Vars $baseDir = "HIS\API" # 应用程序根路径 $replacementFilePath = "Parameters-localhost.json" # 替换值配置文件 # 读取替换值文件 if (-Not (Test-Path $replacementFilePath)) { Write-Host "替换值文件不存在: $replacementFilePath" -ForegroundColor Red exit } $replacementData = Get-Content $replacementFilePath -Raw | ConvertFrom-Json if (-Not $replacementData.variables) { Write-Host "文件中没有可替换的变量值。" -ForegroundColor Red exit } # 构建替换字典 $replacements = @{} foreach ($key in $replacementData.variables.PSObject.Properties.Name) { $value = $replacementData.variables.$key.value $replacements[$key] = $value } # 递归查找所有appsettings.json文件并处理 Get-ChildItem -Path $baseDir -Recurse -Filter "appsettings.json" | ForEach-Object { $filePath = $_.FullName Write-Host "正在处理文件: $filePath" -ForegroundColor Cyan try { Write-Host "加载文件中..." -ForegroundColor Cyan # 逐行读取并移除注释 $jsontext = Get-Content $filePath | ForEach-Object { $line = $_ # 删除//开头的注释行 if ($line -match '^\s*//') { $line = $line -replace '^\s*//.*$', '' } $line } | Out-String $jsonContent = $jsontext | ConvertFrom-Json -ErrorAction Stop # 执行替换操作 Write-Host "遍历替换键..." -ForegroundColor Cyan foreach ($key in $replacements.Keys) { Write-Host " - 处理键: $key" $value = $replacements[$key] $pathParts = $key -split "\." $currentObj = $jsonContent $lastPartIndex = $pathParts.Count - 1 # 定位到父对象 $validPath = $true for ($i = 0; $i -lt $lastPartIndex; $i++) { $part = $pathParts[$i] if (-not $currentObj.$part) { Write-Warning "路径部分 '$part' 不存在,跳过键 '$key'" $validPath = $false break } $currentObj = $currentObj.$part } if (-not $validPath) { continue } # 修改目标属性 $finalProperty = $pathParts[$lastPartIndex] if ($currentObj.PSObject.Properties[$finalProperty]) { Write-Host "设置 '$key': '$value'" $currentObj.$finalProperty = $value } else { Write-Warning "属性 '$finalProperty' 不存在,跳过键 '$key'" } } # 保存修改后的文件 $jsonContent | ConvertTo-Json -Depth 8 | Set-Content $filePath -Force Write-Host "已更新文件: $filePath" -ForegroundColor Yellow } catch { Write-Host "处理文件 $filePath 时出错" -ForegroundColor Red $errorMessage = $_.Exception.Message Write-Host $errorMessage -ForegroundColor Red } }
内容的提问来源于stack exchange,提问作者Milton Calderon
相关产品推荐
相关产品推荐

