Replace content by key in JSON - json

I've the JSON file with the following structure:
{
"Url": "placeholder",
}
I'd like to write a Powershell script which replaces the value ("placeholder") by key ("Url").
I know how to replace content by I don't know how to save it back to the file.
$snapshot = (Get-Content settings.json | ConvertFrom-Json)
$snapshot.Url = "Test"

You can write it back using the Set-Content cmdlet. E. g.:
$snapshot | ConvertTo-Json | Set-Content

Related

Adjust json file using ConvertFrom-Json

I have a json file with the following content
{
"name":"myApp",
"version":"1"
}
I would like to use Powershell to read this json file, adjust the version number, then output the new json to the same file.
I currently have this, but it doesn't work and only outputs an empty file
Get-Content file.json | ConvertFrom-Json | ForEach{$_.version = "2"} | ConvertTo-Json | Out-File file.json -Encoding ascii
I am getting stuck on how to update values on the Json object created by ConvertFrom-Json and pipe this back into ConvertTo-Json
I would like to do this all in one line if possible.
Once you assign the JSON to an object, you should be able to change it from there then write it to a file (if desired).
Create JSON object from file contents:
$jsonObject = Get-Content file.json -Raw | ConvertFrom-Json
Change the current object. In your example the "version" property:
#update object
$jsonObject| %{$_.version = "2"}
Write object to file:
$jsonObject | ConvertTo-Json | Out-File "file.json" -Encoding ascii

replace string with varying content using powershell

I have a set of folders in which there are some json files. I am trying to write a powershell script to convert the below line for all the json in the folder:
"objectStatus": "ACTIVE",
The above line from json files can differ with more than one space between the key and value:
"objectStatus": "ACTIVE",
The script that I wrote is:
$jsonFiles = Get-ChildItem . *.json -rec
foreach ($file in $jsonFiles)
{
(Get-Content $file.PSPath) |
Foreach-Object {$_ -replace '"ACTIVE"','"INACTIVE"'} |
Set-Content $file.PSPath
}
You can see that the above replaces the string '"ACTIVE"' to '"INACTIVE"'. However, I want to replace the '"ACTIVE"' string only when the key is "objectStatus". Also, there can be more than one space between the key and value. How can I handle that while replacing the string?
Thanks in advance!
You can make search by full string like this. '"objectStatus":\s*"ACTIVE"','"objectStatus": "INACTIVE"'
$jsonFiles = Get-ChildItem . *.json -rec
foreach ($file in $jsonFiles)
{
(Get-Content $file.PSPath) |
Foreach-Object {$_ -replace '"objectStatus":\s*"ACTIVE"','"objectStatus": "INACTIVE"'} |
Set-Content $file.PSPath
}

I need to get a a specific value from Json file using powershell

I converted a plain text inside note-pad to JSON file using this command ConvertTo-Json;
so how do I get the specific key value that equivalents to note-pad text content?
get-content -Path c:\Users\ayyub\oneDrive\Desktop\Jayson.txt | ConvertTo-
Json
Let's say your .json looks like this:
{
"person": {
"kevin": {
"phone": "00000099999"
}
}
}
After converting the .txt to a .json you can probably try this:
$json = (Get-Content "example.json" -Raw) | ConvertFrom-Json
$json.person.kevin.phone

Using Powershell to convert a file's contents into a string that can be transferred using JSON

How does one convert a text file's contents into a string and then insert this string into a JSON file?
For example, if a file contains:
this
is
a
sample
file
The script would generate:
"this\r\nis\r\na\r\nsample\r\nfile"
To insert into a JSON template:
"something":"<insertPoint>"
To produce:
"something":"this\r\nis\r\na\r\nsample\r\nfile"
I'm using Powershell 5 and have managed to load the file, generate some JSON and insert it by running:
# get contents and convert to JSON
$contentToInsert = Get-Content $sourceFilePath -raw | ConvertTo-Json
# write in output file
(Get-Content $outputFile -Raw).replace('<insertPoint>', $contentToInsert) | Set-Content $outputFile
However, a lot of other, unwanted fields are also added.
"something":"{
"value": "this\r\nis\r\na\r\nsample\r\nfile"
"PSPath": "C:\\src\\intro.md",
"PSParentPath": "C:\\src",
"PSChildName": "intro.md",
etc...
Ultimately, I'm trying to send small rich text segments to a web page via JSON but want to edit and store them locally using Markdown. If this doesn't make sense and there's a better way of sending these then please let me know also.
iRon's answer helpfully suggests not using string manipulation to create JSON in PowerShell, but to use hashtables (or custom objects) to construct the data and then convert it to JSON.
However, that alone does not solve your problem:
PS> #{ something = Get-Content -Raw $sourceFilePath } | ConvertTo-Json
{
"something": {
"value": "this\nis\na\nsample\nfile\n",
"PSPath": "/Users/mklement/Desktop/pg/lines.txt",
# ... !! unwanted properties are still there
}
The root cause of the problem is that Get-Content decorates the strings it outputs with metadata in the form of NoteProperty properties, and ConvertTo-Json currently invariably includes these.
A proposal to allow opting out of this decoration when calling Get-Content can be found in GitHub issue #7537.
Complementarily, GitHub issue #5797 suggests that ConvertTo-Json should ignore the extra properties for primitive .NET types such as strings.
The simplest workaround is to access the underlying .NET instance with .psobject.baseobject, which bypasses the invisible wrapper object PowerShell uses to supply the extra properties:
PS> #{ something = (Get-Content -Raw $sourceFilePath).psobject.baseobject } |
ConvertTo-Json
{
"something": "this\nis\na\nsample\nfile\n"
}
Just a general recommendation apart from the actually issue described by #mklement0 and metadata added to the Get-Content results:
Do not poke (replace, insert, etc.) in any Json content.
Instead, modify the object (if necessary, use ConvertFrom-Json to restore the object) prior converting it into (ConvertTo-Json) a Json file.
In this example, I would use a hash-table with a here-string for this:
#{'something' = #'
this
is
a
sample
file
'#
} | ConvertTo-Json
Result:
{
"something": "this\nis\na\nsample\nfile"
}
You can use the Out-String cmdlet to coerce the output of Get-Content into a flat string first:
#{ "something" = (Get-Content lines.txt | Out-String) } | ConvertTo-Json
This produces:
{
"something": "this\r\nis\r\na\r\nsample\r\nfile\r\n"
}

Replace only first occurrence

I have a PowerShell scripts which replaces
"version" : "xxx"
with
"version" : "myBuildNumber"
Now I encountered that I have multiple of these in my file.
I only want to replace the first occurrence.
I tried already Powershell - Replace first occurrences of String but it does not work with my regex.
Here's my script:
(Get-Content myFile.txt) -replace '(?<pre>"version"[\s]*:[\s]*)(?<V>"[^\"]*")', "`$1`"$Env:BUILD_VERSION`"" | Out-File myFile.txt
Since you are patching a JSON file, regex isn't the way to go. Instead you should parse the JSON, access and change the property you want and write it back:
$filePath = 'your_Path_To_project.json'
$json = (Get-Content $filePath -raw | ConvertFrom-Json)
$json.version = $Env:BUILD_VERSION
$json | ConvertTo-Json -Depth 10 | Set-Content $filePath