使用PowerShell 5修改JSON文件IP规则属性时的格式异常问题
在PowerShell 5中修复JSON序列化深度不足导致的格式异常
问题背景
需要从文本文件读取IP列表,更新ARM模板中resources[0].properties.networkAcls.ipRules字段。该操作在PowerShell 7中正常执行,但PowerShell 5中ConvertTo-Json/ConvertFrom-Json无-Depth参数,默认仅支持2层序列化,导致深层嵌套对象(如properties)被转为字符串形式(例如@{networkAcls=; supportsHttpsTrafficOnly=True...}),输出JSON格式损坏。
问题根源
PowerShell 5.x的内置JSON处理命令默认序列化深度为2,超过该层级的嵌套对象会被转换为PowerShell对象的字符串表示,而非保持JSON嵌套结构。
解决方案
方案1:使用.NET序列化器突破深度限制
利用.NET的System.Web.Script.Serialization.JavaScriptSerializer实现自定义深度的序列化/反序列化,完全规避PS5的深度限制。
修改后的完整脚本:
# 读取IP列表并构造规则对象 $ipRules = Get-Content .\ipv4.txt | ForEach-Object { [pscustomobject]@{ value = $_ action = 'Allow' } } # 自定义支持深度的JSON序列化函数 function ConvertTo-JsonWithDepth { param( [Parameter(Mandatory, ValueFromPipeline)] $InputObject, [int]$Depth = 100 ) $serializer = New-Object System.Web.Script.Serialization.JavaScriptSerializer $serializer.RecursionLimit = $Depth # 二次转换确保格式对齐PowerShell风格 $serializer.Serialize($InputObject) | ConvertFrom-Json | ConvertTo-Json } # 读取并反序列化ARM模板(避免PS5默认深度限制) $rawJson = Get-Content "myTemplate.json" -Raw $deserializer = New-Object System.Web.Script.Serialization.JavaScriptSerializer $deserializer.RecursionLimit = 100 $template = $deserializer.DeserializeObject($rawJson) # 定位存储账户资源并更新ipRules $storageResource = $template.resources | Where-Object { $_.type -eq "Microsoft.Storage/storageAccounts" } $storageResource.properties.networkAcls.ipRules = $ipRules # 序列化并写入结果文件 $template | ConvertTo-JsonWithDepth -Depth 100 | Set-Content "myTemplate.json" -Encoding UTF8
方案2:手动重构嵌套对象(简易场景适用)
如果模板结构固定,可手动重构深层对象,确保序列化层级不超过PS5默认限制:
$template = Get-Content "myTemplate.json" | ConvertFrom-Json $ipRules = Get-Content .\ipv4.txt | ForEach-Object { [pscustomobject]@{value = $_; action = 'Allow'} } $storageResource = $template.resources | Where-Object { $_.type -eq "Microsoft.Storage/storageAccounts" } # 重新构造networkAcls对象,确保层级清晰 $storageResource.properties.networkAcls = [pscustomobject]@{ resourceAccessRules = @() bypass = "AzureServices" virtualNetworkRules = @() ipRules = $ipRules defaultAction = "Allow" } # 多次转换强制保留嵌套结构 $template | ConvertTo-Json | ConvertFrom-Json | ConvertTo-Json | Set-Content "myTemplate.json" -Encoding UTF8
效果验证
执行脚本后,输出的JSON将保持正确的嵌套结构,properties字段会以标准JSON对象形式存在,与PowerShell 7中的期望输出一致。
内容的提问来源于stack exchange,提问作者RKN
相关产品推荐
相关产品推荐

