I have this file .json:
{
"topologyTypes": {
"stations": {
"instances": [
{
"#name": "value1",
"#address": "value2"
},
{
"#name": "value3",
"#address": "value4"
}
]
}
},
"agg": {},
"inter": {}
}
I want to add an object like this in topologyType.stations.instances with PowerShell
{
"#name": "value4",
"#adress": "value5"
}
So I tried this following code in PowerShell, but it doesn't work:
$path = "./data.json"
$jsonFile = Get-Content $path -Raw | ConvertFrom-Json
$jsonContent = #"
{
"#name": "value4",
"#adress": "value5"
}
"#
$jsonFile.topologyTypes.stations.instances |
Add-Content -Value (ConvertFrom-Json $jsonContent)
The desired output I would like to get is like this:
{
"topologyTypes": {
"stations": {
"instances": [
{
"#name": "value1",
"#address": "value2"
},
{
"#name": "value3",
"#address": "value4"
},
{
"#name": "value4",
"#address": "value5"
}
]
}
},
"agg": {},
"inter": {}
}
Define the new content as a PowerShell custom object:
$jsonContent = [PSCustomObject]#{
'#name' = 'value4'
'#adress' = 'value5'
}
append it to the instances substructure of your imported JSON data:
$jsonFile.topologyTypes.stations.instances += $jsonContent
then convert the data back to a JSON string:
$jsonFile | ConvertTo-Json -Depth 4
Note that ConvertTo-Json inserts a lot of intention space. If you want exactly the format you posted you need to do some pretty-printing yourself. Something like this might help.
Related
I am trying to get the list of "enabled" features from featureset array from below JSON snippet with powershell.
output expected :
feature1, feature2, feature4
I tried this piece of code but I was only able to get to the specific index of the array, not all elements, also not able to put condition for "enable" = true :
$output = foreach( $feature in $jsn.abc.comp1.featureset[0].psobject.Properties ) {
[PSCustomObject]#{
featureName = $feature.Name
featureValue = $feature.Value
}
}
json:
{
"abc": {
"comp1": {
"id": "1308",
"featureset":[
{
"name": "feature1",
"enable" : true,
"ID": "0670FF495355878281174937"
},
{
"name": "feature2",
"enable" : true,
"ID": "0670FF495355878281174937"
},
{
"name": "feature3",
"enable" : false,
"ID": "0670FF495355878281174937"
},
{
"name": "feature4",
"enable" : true,
"ID": "0670FF495355878281174937"
}
]
}
}
}
Loop over the whole featureset array, use Where-Object to filter:
$output = $jsn.abc.comp1.featureset |Where-Object enable -eq $true |ForEach-Object {
$_.Name
}
I'm trying to dump a powershell array of hash tables to json like this:
$body= ,#($someArray | % {
{
#{
name = $_
}
}
})
$body | ConvertTo-Json
But this yields this result:
{
"value": [
{
"name": "test"
},
{
"name": "test-2"
}
],
"Count": 2
}
Not sure how to only get the value.
If I do ConvertTo-Json | $body, I get:
[
[
{
"name": "test",
},
{
"name": "test-2",
}
]
]
I'm doing the ,#() syntax because otherwise if I only have one object in my array it gets converted to an Hash Table instead of an array.
I am on Powershell 5.
here is my json body .
{
"source": 2,
"revision": 3,
"description": null,
"triggers": [],
"releaseNameFormat": "Release-$(rev:r)",
"tags": [],
"pipelineProcess": {
"type": 1
},
"properties": {
"DefinitionCreationSource": {
"$type": "System.String",
"$value": "BuildSummary"
},
"System.EnvironmentRankLogicVersion": {
"$type": "System.String",
"$value": "2"
}
},
"id": 5,
"name": "CheckListAPI - CD",
"path": "\\Admin",
"projectReference": null,
"url": "",
"_links": {
"self": {
"href": ""
},
"web": {
"href": ""
}
}
}
I want to add some values inside the brackets at "triggers": [],
What I'm trying to get is:
"triggers":
[
{
"artifactAlias": "_DV_NJ_PIPE",
"triggerConditions": [],
"triggerType": 1
}
],
i tried -replace and replace() saving the json file to local system, but none of them are working, I even tried to edit the json file directly like this but failed.
$alias = $json.triggers
foreach ($artifact in $alias )
{
$artifact.artifactAlias = "_$DefName"
$artifact.triggerConditions = "{}"
$artifact.triggertype = "artifactSource"
}
Please help.
You can import the json file as PowerShell objects, manipulate the structure until it looks the way you want it to and export it back to json format:
$pipeline = Get-Content .\input.json | ConvertFrom-Json
$trigger = [ordered]#{
artifactAlias = "_DV_NJ_PIPE"
triggerConditions = #()
triggerType = 1
}
$pipeline.triggers += $trigger
$pipeline | ConvertTo-Json -Depth 5 | Out-File .\output.json
As it was pointed out in the comments, it is of course also possible to import the trigger definition from a json file instead of building it in a hash table.
I have 2 files
text.json that contains
{
"Files": [
{
"pattern": "/Something/Something/*"
},
{
"pattern": "/Something/Something/*"
},
{
"pattern": "/Something/Something/*"
},
{
"pattern": "/Something/Something/*"
},
{
"pattern": "/Something/Something/*"
},
{
"pattern": "/Something/Something/*"
}
]
}
and dlls.txt
1.dll
2.dll
..
6.dll
I want to replace the symbol * with the necessary dll like this :
"Files": [
{
"pattern": "/Something/Something/1.dll"
},
{
"pattern": "/Something/Something/2.dll"
},
.
.
.
{
"pattern": "/Something/Something/6.dll"
}
]
}
So far my code replaces the symbol but only with the last array element.
Since you're dealing with a structured data format - JSON - using a dedicated parser is always preferable to performing purely textual processing based on regexes.
While using the dedicated ConvertFrom-Json and ConvertTo-Json cmdlets to parse from and serialize back to JSON is slower than textual processing, it is much more robust.
# Read the DLL names from the text file into an array of strings.
$dlls = Get-Content dlls.txt
# Read the JSON file and parse it into an object.
$objFromJson = Get-Content -Raw text.json | ConvertFrom-Json
# Loop over all elements of the array in the .Files property and
# update their .pattern property based on the corresponding DLL names.
$i = 0
$objFromJson.Files.ForEach({
$_.pattern = $_.pattern -replace '(?<=/)\*$', $dlls[$i++]
})
# Convert the updated object back to JSON; save to a file as needed.
$objFromJson | ConvertTo-Json
Why not skip the 'C:\Users\itsan\Desktop\text.json' file alltogether and simply create a new JSON from the dll filenames you have in 'C:\Users\itsan\Desktop\dlls.txt' ?
$dlls = Get-Content -Path 'C:\Users\itsan\Desktop\dlls.txt'
$result = [PsCustomObject]#{
Files = foreach($file in $dlls) {
"" | Select-Object #{Name = 'pattern'; Expression = {"/Something/Something/$file"}}
}
}
$result | ConvertTo-Json
If you want that as new file, simply change the last line into
$result | ConvertTo-Json | Set-Content -Path 'C:\Users\itsan\Desktop\dll.json'
Output wil be like this:
{
"Files": [
{
"pattern": "/Something/Something/1.dll"
},
{
"pattern": "/Something/Something/2.dll"
},
{
"pattern": "/Something/Something/3.dll"
},
{
"pattern": "/Something/Something/4.dll"
},
{
"pattern": "/Something/Something/5.dll"
},
{
"pattern": "/Something/Something/6.dll"
}
]
}
I am working with a JSON like that looks like this:
[
{
"Ack": "no",
"Rule": "dont",
"Tags": [
"server"
],
"Type": "blue"
},
{
"Ack": "no1",
"Rule": "knock",
"Tags": [
"yellow",
"green"
],
"Type": "multiplecolour"
}
]
I need to convert the Tags array into a comma-separated string [and replace the array with the converted string in the JSON file]. I have tried converting from JSON, but I am struggling to convert the array into string in a clean way, still learning PS so please bear with me.
ConvertFrom-Json may work for you. Here's an example of converting your JSON string to an array of PowerShell objects, then joining the tags for each object with a comma delimiter:
$json = #"
[
{
"Ack": "no",
"Rule": "dont",
"Tags": [
"server"
],
"Type": "blue"
},
{
"Ack": "no1",
"Rule": "knock",
"Tags": [
"yellow",
"green"
],
"Type": "multiplecolour"
}
]
"#
(ConvertFrom-Json -InputObject $json) `
| ForEach-Object { $_.Tags = ($_.Tags -join ","); $_ } `
| ConvertTo-Json `
| Out-File -FilePath new.json
EDIT: Note (as #mklement0 points out), the parentheses around ConvertFrom-Json are required to force the enumeration of the results as an array of objects through the pipeline.