You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何阻止PowerShell Out-File覆盖JSON文件中未修改的区块

问题:PowerShell脚本更新JSON文件时意外覆盖非目标环境区块

我有一个包含dev、preprod、prod三个区块的JSON文件,用于存储对应环境下Azure资源(App Reg、安全组等)的信息。编写的PowerShell脚本在创建资源后,会将信息写入JSON的对应环境区块,但存在问题:

  • 首次针对dev运行时,能正确填充dev区块
  • 后续针对preprod运行时,虽能填充preprod区块,但会将dev区块设为null,相当于覆盖了整个文件

我需要脚本仅更新目标环境的区块,保留其他环境的原有内容。当前代码如下:

if ($environment -eq "Development") {
  $devBlock = @{
    "Project" = $projectName
    "tenant" = $tenantName
    "AppRegId" = $spdetails.appId
    "ProjectId" = $projectSubId
    "projectsubname" = $projectSubName
    "Date" = $date
    "Username" = $actor
    "RoGroup" = $RoGroupid.id
    "FcGroup" = $FcGroupid.id
    "environment" = $environment
  }
}
elseif ($environment -eq "PreProduction") {
  $preprodBlock = @{
    "Project" = $projectName
    "tenant" = $tenantName
    "AppRegId" = $spdetails.appId
    "ProjectId" = $projectSubId
    "projectsubname" = $projectSubName
    "Date" = $date
    "Username" = $actor
    "RoGroup" = $RoGroupid.id
    "FcGroup" = $FcGroupid.id
    "environment" = $environment
  }
} 
else {
  $prodBlock = @{
    "Project" = $projectName
    "tenant" = $tenantName
    "AppRegId" = $spdetails.appId
    "ProjectId" = $projectSubId
    "projectsubname" = $projectSubName
    "Date" = $date
    "Username" = $actor
    "RoGroup" = $RoGroupid.id
    "FcGroup" = $FcGroupid.id
    "environment" = $environment
  }
}

$data = @{
  "dev" = $devBlock
  "preprod" = $preprodBlock
  "prod" = $prodBlock
}

# Convert the hashtable to a JSON string
$json = $data | ConvertTo-Json -Depth 10

# Define the path for the JSON file
$jsonFilePath = $projectName + ".json"

# Write the JSON string to the file
$json | Out-File -FilePath $jsonFilePath -Encoding utf8

Write-Output "JSON file created at $jsonFilePath"

解决方案

问题根源:当前脚本每次运行时,仅初始化目标环境的变量,其他环境变量未被赋值(默认是$null),最终生成的哈希表会把非目标区块设为null,覆盖原有文件。

修改思路:

  1. 先读取现有JSON文件(如果存在),保留已有区块的内容
  2. 仅更新目标环境的区块数据
  3. 将更新后的哈希表写回文件

修改后的完整代码:

# 定义JSON文件路径
$jsonFilePath = "$projectName.json"

# 初始化数据哈希表:如果文件存在则读取现有内容,否则创建空结构
if (Test-Path $jsonFilePath) {
    $data = Get-Content $jsonFilePath -Raw | ConvertFrom-Json -AsHashtable
} else {
    $data = @{
        "dev" = $null
        "preprod" = $null
        "prod" = $null
    }
}

# 生成当前环境的区块数据
$currentEnvBlock = @{
    "Project" = $projectName
    "tenant" = $tenantName
    "AppRegId" = $spdetails.appId
    "ProjectId" = $projectSubId
    "projectsubname" = $projectSubName
    "Date" = $date
    "Username" = $actor
    "RoGroup" = $RoGroupid.id
    "FcGroup" = $FcGroupid.id
    "environment" = $environment
}

# 根据环境更新对应区块
switch ($environment) {
    "Development" { $data["dev"] = $currentEnvBlock }
    "PreProduction" { $data["preprod"] = $currentEnvBlock }
    default { $data["prod"] = $currentEnvBlock }
}

# 转换为JSON并写入文件
$data | ConvertTo-Json -Depth 10 | Out-File -FilePath $jsonFilePath -Encoding utf8

Write-Output "JSON file updated at $jsonFilePath"

关键优化点:

  • 使用Test-Path检查文件是否存在,存在则读取原有内容(ConvertFrom-Json -AsHashtable确保可以修改)
  • 统一生成环境区块数据,避免重复代码
  • 使用switch语句替代多分支if/else,逻辑更清晰
  • 仅更新目标环境的键,保留其他环境的原有内容

内容的提问来源于stack exchange,提问作者Keagan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.15 01:30:11