使用PowerShell更新JSON文件

pst*_*ker 13 powershell json azure-devops azure-pipelines

我目前正在尝试使用VSTS设置一个持续集成系统,并遇到了一些障碍.作为发布过程的一部分,我需要根据环境更新JSON文件中的特定对象值.我可以使用的唯一工具可以在VSTS环境中完成,这是PowerShell.

我已经做了很多研究,但却无法弄清楚这是怎么做到的.我发现这个问题和答案在这里堆栈溢出" 我如何使用PowerShell的更新JSON文件,但在执行中的答案提供的脚本显着改变的JSON文件的结构,并增加了相当多的什么样子PowerShell中的元数据".

理想情况下,我想获取一个已部署的现有JSON文件,并在下面的示例JSON中更新connectionString属性的值.

{
    "policies": {
         "Framework.DataContext": {
         "connectionString": "Server=ServerName;Database=DateBaseName;Integrated Security=sspi;"
         }
    }
}
Run Code Online (Sandbox Code Playgroud)

有没有人对如何做到这一点有任何建议?到目前为止,我已经尝试运行以下脚本但它抛出了"在此对象上找不到属性'connectionString'.验证该属性是否存在且可以设置." 例外.我已经验证对象遍历是正确的,并且connectionString属性存在.

$pathToJson = "D:\Path\To\JSON\file.json"
$a = Get-Content $pathToJson | ConvertFrom-Json
$a.policies.'Framework.DataContext'.connectionString = "Server=ServerName;Database=DateBaseName;Integrated Security=sspi;"
$a | ConvertTo-Json | set-content $pathToJson
Run Code Online (Sandbox Code Playgroud)

file.json的全部内容如下

{
"log": {
    "level": 0,
    "file": "c:\\temp\\simport.log",
    "formats": {
        "error": null,
        "start": null,
        "requestBegin": null,
        "requestWork": "",
        "requestError": null,
        "requestEnd": null,
        "stop": null
    },
    "eventLog": {
        "name": "Application"
    }
},

"diagnostic": {
    "stackTrace": false
},

"api": {
    "simport": true
},

"roles": {
    "0": "Anonymous",
    "1": "Administrator",
    "2": "Participant",
    "3": "Facilitator"
},

"pathType": {
    "area": 1,
    "region": 2,
    "session": 3,
    "team": 4
},

"scenarios": {
    "default": {
       "default": true,
        "initState": "Init",
        "rounds": [
            {
                "name": "round1",
                "displayName": "R1",
                "beginTime": 1,
                "endTime": 3
            },
            {
                "name": "round2",
                "displayName": "R2",
                "beginTime": 4,
                "endTime": 6
            },
            {
                "name": "round3",
                "displayName": "R3",
                "beginTime": 7,
                "endTime": 9
            },
            {
                "name": "round4",
                "displayName": "R4",
                "beginTime": 10,
                "endTime": 12
            }
        ]
    }
},

"simportQueries": {
    "package": "bin/trc.simport3.zip"
},

"customQueries": {
    "package": "app/config/custom-queries.zip",
    "parameters": {
    }
},

"audit": {
    "Path.Create": true,
    "Path.Delete": true,
    "Team.Create": true,
    "Team.Update": true,
    "Team.Delete": true,
    "SimportData.SaveValues": true
},

"tasks": {
    "task1": {
        "state": "",
        "required": "",
        "completed": "C:Task1Status:+0"
    }
},

"feedback": {
    "welcome": {
        "text": {
            "": "en-us",
            "en-us": "Welcome"
        }
    }
},

"contentCategories": {
    "demo1": {
        "round": 1
    }
},

"policies": {
    "Simport.Web.Module": {
        "fileMask": ".aspx,.asmx",
        "deny": {
            "statusCode": 404,
            "statusDescription": "Not found",
            "location": [
                "/{0,1}app/config/(.*\\.json)$",
                "/{0,1}app/config/(.*\\.xml)$",
                "/{0,1}app/config/(.*\\.zip)$",
                "/{0,1}app/config/(.*\\.xlsx)$"
            ]
        },
        "formDataContentType": [ "application/x-www-form-urlencoded" ]
    },

    "Framework.DataContext": {
        "connectionString": "Server=(local);Database=Simport3;Integrated Security=sspi;",
        "commandTimeout": 30
    },

    "Simport.Security": {
        "passwordEncryption": "",
        "passwordSalt": "",
        "passwordPolicy": {
            "disabled": true,
            "min": 8,
            "max": 100,
            "rules": [
                { "id": "digit", "pattern": "\\d+", "flags": "i" },
                { "id": "letter", "pattern": "\\w+", "flags": "i" },
                { "id": "upper", "pattern": "[A-Z]+" },
                { "id": "lower", "pattern": "[a-z]+" },
                { "id": "special", "pattern": "[\\!#@\\$_~]+", "flags": "i" },
                { "id": "prohibited", "pattern": "[\\\\/'\"\\?\\^&\\+\\-\\*\\%\\:;,\\.]+", "flags": "gi", "match": false }
            ]
        }
    },

    "Simport.PackageDefinition": {
        "path": "~/app/config/manifest.xml"
    },

    "Security.SignIn": {
        "result": {
            "default": "u,p,p.props,t"
        },
        "claims": [
            [ "userId", "firstName", "lastName" ]
        ]
    },

    "Security.GetContext": {
        "result": {
            "default": "u,p,p.props,pr,t"
        }
    },

    "Security.ChangePassword": {
        "allowedRoles": [ 1, 2, 3 ]
    },

    "Security.ResetPassword": {
        "allowedRoles": [ 1, 2 ]
    },

    "Security.Register": {
        "allowedRoles": [ 0 ],
        "!pathType-0": 4,
        "!roleId-0": 2
    },

    "Path.Create": {
        "allowedRoles": [ 1, 2, 3 ]
    },

    "Path.Select": {
        "allowedRoles": [ 1, 2, 3 ],
        "result-1": {
        }
    },

    "Path.Delete": {
        "allowedRoles": [ 1, 2 ]
    },

    "User.Select": {
        "allowedRoles": [ 1, 2, 3 ],
        "result": {
            "select": [ "id", "pathid", "roleid", "name", "email", "login", "props" ],
            "restrict": [ "password" ]
        },
        "result-1": {
            "select": "*",
            "group": true
        }
    },

    "User.Create": {
        "allowedRoles": [ 1, 2 ],
        "result": {
            "select": [ "id", "pathid", "roleid", "name", "email", "login", "props" ],
            "restrict": [ "password" ]
        },
        "result-1": {
            "select": "*",
            "group": true
        }
    },

    "User.Update": {
        "allowedRoles": [ 1, 2, 3 ],
        "result": {
            "select": [ "id", "pathid", "roleid", "name", "email", "login", "props" ],
            "restrict": [ "password" ]
        }
    },

    "User.Delete": {
        "allowedRoles": [ 1, 2 ],
        "result": {
            "restrict": [ "password" ]
        }
    },

    "Session.Select": {
        "allowedRoles": [ 1, 2, 3 ],
        "enforcePathLevel": true,
        "result": {
            "default": [ "name", "beginDate", "endDate" ],
            "restrict": [ "password" ]
        },
        "result-1": {
            "default": [ "name", "beginDate", "endDate" ],
            "treeAllowed": true,
            "treeDefault": false
        }
    },

    "Session.Create": {
        "allowedRoles": [ 1, 2 ],
        "enforcePathLevel": true
    },

    "Session.Update": {
        "allowedRoles": [ 1, 2 ],
        "enforcePathLevel": true,
        "update-restictions": [ "password" ],
        "update-restictions-1": [ ],
        "result": {
            "restrict": [ "password" ]
        }
    },

    "Session.Delete": {
        "allowedRoles": [ 1, 2 ],
        "result": {
            "restrict": [ "password" ]
        }
    },

    "Team.Select": {
        "allowedRoles": [ 1, 2, 3 ],
        "enforcePathLevel": false,
        "enforcePathLevel-1": true,
        "result-1": {
            "treeAllowed": true,
            "treeDefault": false
        }
    },

    "Team.Create": {
        "allowedRoles": [ 1, 2, 3 ],
        "enforcePathLevel": true,
        "enforcePathLevel-1": false,
        "allowMultiple": false,
        "allowMultiple-1": true,
        "result": {
        },
        "overrides": {
            "roleID": 3
        }
    },

    "Team.Reset": {
        "allowedRoles": [ 1, 2, 3 ]
    },

    "Team.Delete": {
        "allowedRoles": [ 1, 2, 3 ],
        "deleteMultiple": true,
        "result": {
            "default": "t"
        }
    },

    "Team.TransitionTo": {
        "allowedRoles": [ 1, 2, 3 ],
        "inboundRules": {
            "Round1Init": {
                "allowedRoles": [ ]
            }
        },
        "outboundRules": {
            "Round1Wait": {
                "allowedRoles": [ 1, 2, 3 ]
            }
        }
    },

    "Team.TakeControl": {
        "allowedRoles": [ 1, 2, 3, 4 ],
        "select-1": {
            "select": "*",
            "restrict": [ "ctrl.userID", "ctrl.loginName" ]
        }
    },

    "Team.ReleaseControl": {
        "allowedRoles": [ 1, 2, 3, 4 ],
        "select-1": {
            "select": "*",
            "restrict": [ "ctrl.userID", "ctrl.loginName" ]
        }
    },

    "Team.GetStatus": {
        "allowedRoles": [ 1, 2, 3 ],
        "result": {
            "default": "p,t,pr"
        }
    },

    "Data.Select": {
        "allowedRoles": [ 1, 2, 3 ]
    },

    "Data.Update": {
        "allowedRoles": [ 1, 2, 3 ],
        "audit": {
            "g": false,
            "i": true,
            "o": true,
            "s": true
        }
    },

    "Data.ExecuteQuery": {
        "allowedRoles": [ 0, 1, 2, 3 ],
        "allowed-0": [ "login4\\areas", "login4\\regions", "login4\\sessions", "login4\\teams" ],
        "restrict-3": [ "prohibitedQueryNameHere" ]
    },

    "Document.Select": {
        "defaultTextEncoding": "utf-16"
    },

    "Document.Create": {
        "~allowFileExt": [ ],
        "denyFileExt": [ ".exe", ".com", ".cmd", ".bat", ".ps1" ],
        "~allowContentType": [ ],
        "denyContentType": [ "application/x-msdownload" ],
        "maxContentLength": 0,
        "defaultTextEncoding": "utf-16"
    },

    "Document.Update": {
        "allowedRoles": [ 1, 2, 3 ]
    },

    "Document.Delete": {
    },

    "Document.Download": {
    }
}
}
Run Code Online (Sandbox Code Playgroud)

Mar*_*ndl 19

你的json缺少起始和结束的大括号:

{
    "policies": {
         "Framework.DataContext": {
            "connectionString": "Server=ServerName;Database=DateBaseName;Integrated Security=sspi;"
         }
    }
}
Run Code Online (Sandbox Code Playgroud)

现在您可以像这样更新文件:

$pathToJson = "F:\Path\To\JSON\file.json"
$a = Get-Content $pathToJson | ConvertFrom-Json
$a.policies.'Framework.DataContext'.connectionString = "Server=ServerName;Database=DateBaseName;Integrated Security=sspi2;"
$a | ConvertTo-Json | set-content $pathToJson
Run Code Online (Sandbox Code Playgroud)

你也可以使用一些Select-Object来获得财产:

$connectionString = $a | select -expand policies | select -expand Framework.DataContext 
$connectionString.connectionString = 'Test'
Run Code Online (Sandbox Code Playgroud)

  • 这是错误的,它应该是一个`PsCustomObject`。尝试添加括号:`$a = (Get-Content $pathToJson | ConvertFrom-Json)`。另外,尝试复制我的示例 json 并且不要更改任何内容,然后尝试是否可行。 (2认同)
  • 我也试过@jisaak 的例子,它在 PowerShell 5 上没有问题 (2认同)
  • 结果我的 JSON 无效,因为它在反馈对象中有一个空的属性名称。鉴于该属性,名称解决了该问题。谢谢你的帮助! (2认同)
  • 对于其他Google员工的相关提示:如果该属性尚不存在,则“添加成员”会很有用。 (2认同)