Replace symbol in JSON with different array values - arrays

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"
}
]
}

Related

Powershell converting array to json yields unexpected results

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.

Access Array of object inside a PSCustomObject Powershell

I have this PSCustomObject which I'm trying to format into a table and export it to an .csv file, when the .csv file is built, the output in the cell is System.Object[].
$tableFindings = #()
foreach ($item in $findings.results) {
$tabledata = [ordered]#{
dnsName = $item.assets| ForEach-Object dsnName
}
$tableFindings += New-Object psobject -Property $tabledata
}
$tableFindings outputs
{
"temporary_id": "xxxxxxxxxxxxxxxxxx",
"affects_rating": true,
"assets": [
{
"asset": "xxxxxxxx",
"identifier": null,
"category": "critical",
"dnsName": [
"xxxxxxxxxxxxxxx",
"xxxxxxxxxxxxxxx"
],
"is_ip": false
},
{
"asset": "xxxxxxxx",
"identifier": null,
"category": "critical",
"dnsName": [
"xxxxxxxxxxxxxxx",
"xxxxxxxxxxxxxxx"
],
"is_ip": false
}
]
}
I'm having a hard time trying to figure out how to access the array of objects, assets is one of the arrays, but inside there is dnsName that is also an array.
Any suggestions?
If all you're interested in is a flat array of the dnsName values, across all objects stored in the assets array, use member-access enumeration:
$item.assets.dnsName
To incorporate this into [pscustomobject] instances you can send to Export-Csv:
$tableFindings = foreach ($item in $findings.results) {
[pscustomobject] #{
# ... add other properties as needed.
dnsName = $item.assets.dnsName
}
}
Note how the foreach statement is used as an expression, which means that PowerShell automatically collects the [pscustomobject] instances output in each iteration in variable $tableFindings.

Convert JSON array object to String in Powershell

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.

I want to extract the data present in JSON file from a odata url but i am unable to extract the content using a loop

Below is the JSON file which i am referring..
{
"#odata.context": "https://ac.com/odata/$metadata#ModelVariableDataTypes(Id,ModelVariable,DoubleValues,ModelVariable(Id,Name,UnitOfMeasure,UnitOfMeasure(Name,Abbreviation)),DoubleValues(Id,Value,Timestamp,DataQuality,DataQuality(Id,Name)))",
"#odata.count": 1,
"value": [
{
"Id": 1928155,
"ModelVariable": {
"Id": 1929663,
"Name": "AccCore_CPULoadProcess",
"UnitOfMeasure": {
"Name": "%",
"Abbreviation": "%"
}
},
"DoubleValues": [
{
"Id": 75865549,
"Value": 0.0,
"Timestamp": "2018-09-25T03:35:00Z",
"DataQuality": {
"Id": 1,
"Name": "Good"
}
},
{
"Id": 75865729,
"Value": 0.0,
"Timestamp": "2018-09-25T03:40:00Z",
"DataQuality": {
"Id": 1,
"Name": "Good"
}
},
{
"Id": 75865873,
"Value": 0.0,
"Timestamp": "2018-09-25T03:45:00Z",
"DataQuality": {
"Id": 1,
"Name": "Good"
}
}
]
}
]
}
I want to extract the data present in JSON file from a odata url but i am unable to extract the content using a loop as in the JSON file the odata count is mentioned as 1(#odata.count": 1) so when i am trying to catch the entire data using a loop it is not working.
I want to extract the data present in the array field of doublevalues and wanted to show the output of the top three values of CPU process.
I am trying with the below code to extract the JSON data.
$path= "C:\Users\s.papolu\Desktop\mem.json"
$data = Get-Content -Path 'C:\Users\S.Papolu\Desktop\mem.json' | ConvertFrom-Json
$maxCount = $data.'#odata.count'
$maxCount
#"
for ($i = 0; $i -lt $maxCount; $i++)
{
$Name = $("{0:N1}" -f $data.value.ModelVariable.Name)
$cpu = $("{$i`:N2}" -f $data.value.DoubleValues.Value)
}
write-host $Name,$cpu
I'm not quite sure what you're asking here. For one thing, you've got an extraneous at-sign and double-quote in there.
MaxCount is just 1 here, so the loop only runs once. For each item, though, are you trying to store the results in some structure and then show it? Which of the DoubleValues do you want? The top three?
Is this closer to what you want?
$data = Get-Content -Path $path | ConvertFrom-Json
$maxCount = $data.'#odata.count'
$maxCount
$results = #()
for ($i = 0; $i -lt $maxCount; $i++)
{
# get the top three doubles values
$Doubles = #($data.value[$i].DoubleValues | sort -Property Value -Descending | select -first 3)
$results += [PsCustomObject]#{
Name = $data.value[$i].ModelVariable[0].Name;
Cpu = $Doubles;
}
}
$results | ft

How to add an object in array on parsed JSON?

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.

Resources