Replacing boolean values in JSON using powershell - json

I'm trying to update a boolean value inside a JSON formated file using powershell but I'm not getting the required output.
From the below,
{
"setComputerName": false,
"setWallpaper": true
}
I would like to get the output as,
{
"setComputerName": true,
"setWallpaper": true
}
Below is my script,
$file = Get-Content 'C:\temp\Config.json' -raw | ConvertFrom-Json
$file = $file.setComputerName = 'true'
$file | ConvertTo-Json | set-content 'C:\temp\Config1.json'

All you have to do once you import your json is.
$file.setComputerName=$true
$file | ConvertTo-Json | set-content 'C:\temp\Config1.json'
You were trying to set the value as a string and it needs to be boolean, so you need to use $true or $false in order to set those values.
Hope this helps!

Related

Powershell convertto-json gives a bad format

Hello I'm trying to use convertto-json to create a json file from another output and save it but I'm getting a bad json format
Here is my function
$output.value | ForEach-Object {
"{"+"id"+':'+ $_.id+','+"outcome" +':'+ '"'+$_.results.outcome+'"'+','+"idtc"+':' +$_.testCaseReference.id + "}"
} | ConvertTo-Json| Out-File -FilePath .\tfs.json
Here is the outcome of the tfs.json
[
"{id:11431,outcome:\"passed\",idtc:70155}",
"{id:11432,outcome:\"unspecified\",idtc:70156}",
"{id:11433,outcome:\"failed\",idtc:70157}",
"{id:11434,outcome:\"unspecified\",idtc:70158}"
]
Can anyone help why it does appear in that way instead of
[
{"id":11431,"outcome":"passed","idtc":70155"},
{"id":11432,"outcome":"unspecified","idtc":70156"},
{"id":11433,"outcome":"failed","idtc":70157"},
{"id":11434,"outcome":"unspecified","idtc":70158"}
]
The output you're receiving from ConvertTo-JSON is pretty much expected. You're passing a string to the cmdlet hence it is returning a string as JSON.
Try this instead:
$output.value | ForEach-Object {
[pscustomobject]#{
id = $_.id
outcome = $_.results.outcome
idtc = $_.testCaseReference.id
}
} | ConvertTo-Json | Out-File -FilePath .\tfs.json

How to write a value in json file using if conditions in powershell?

I am trying to add value in key pair json file using Powershell. I am getting an error. Need some guidance on PS Scripting.
Powershell 5.1 version and json file with key pair inside it.
MYJSON File:
{ "Theme":{"Res_List": {
"Method": "POST",
"Name":""}}}
PowerShell Script:
$file_path="C:\Users\RelativeConfig.json"
$json = Get-Content $file_path | Out-String | ConvertFrom-Json
$timestamp = Get-Date -Format ddMMHHmm
$namevalue = 'resource'+$timestamp+'e3'
echo $namevalue ##prints resource16sep2019 I want this to write in json as value for Name Key
$files = $json | Get-Member -MemberType Properties | Select-Object - ExpandProperty Name
$result = Foreach ($file in $json)
{
if ($file.Name -eq "Name") { $file.Value = $namevalue}
}
$result | ConvertTo-Json | Set-Content $json
Error:
No error but json is not updated with new values.
Expected:
{ "Theme":{"Res_List": {
"Method": "POST",
"Name":"resource16sep2019 "}}}
Actual:
{ "Theme":{"Res_List": {
"Method": "POST",
"Name":""}}}
To update your value in json you can do something like below
$bucket_name = "resource16sep2019" ## I want this to write in json as value for Name Key
$json.Theme.Res_List.Name = $bucket_name
It will directly replace the $bucket_name value with the Name value in JSON.
If you want to write this to the respective file use the below command,
$json | ConvertTo-Json -depth 32| set-content $file_path
Hope it helps! Cheers

Find and Replace Nested JSON Values with Powershell

I have an appsettings.json file that I would like to transform with a PowerShell script in a VSTS release pipeline PowerShell task. (BTW I'm deploying a netstandard 2 Api to IIS). The JSON is structured like the following:
{
"Foo": {
"BaseUrl": "http://foo.url.com",
"UrlKey": "12345"
},
"Bar": {
"BaseUrl": "http://bar.url.com"
},
"Blee": {
"BaseUrl": "http://blee.url.com"
}
}
I want to replace BaseUrl and, if it exists, the UrlKey values in each section which are Foo, Bar and Blee. (Foo:BaseUrl, Foo:UrlKey, Bar:BaseUrl, etc.)
I'm using the following JSON structure to hold the new values:
{
"##{FooUrl}":"$(FooUrl)",
"##{FooUrlKey}":"$(FooUrlKey)",
"##{BarUrl}":"$(BarUrl)",
"##{BleeUrl}":"$(BleeUrl)"
}
So far I have the following script:
# Get file path
$filePath = "C:\mywebsite\appsettings.json"
# Parse JSON object from string
$jsonString = "$(MyReplacementVariablesJson)"
$jsonObject = ConvertFrom-Json $jsonString
# Convert JSON replacement variables object to HashTable
$hashTable = #{}
foreach ($property in $jsonObject.PSObject.Properties) {
$hashTable[$property.Name] = $property.Value
}
# Here's where I need some help
# Perform variable replacements
foreach ($key in $hashTable.Keys) {
$sourceFile = Get-Content $filePath
$sourceFile -replace $key, $hashTable[$key] | Set-Content $filePath
Write-Host 'Replaced key' $key 'with value' $hashTable[$key] 'in' $filePath
}
Why are you defining your replacement values as a JSON string? That's just going to make your life more miserable. If you're defining the values in your script anyway just define them as hashtables right away:
$newUrls = #{
'Foo' = 'http://newfoo.example.com'
'Bar' = 'http://newbaz.example.com'
'Blee' = 'http://newblee.example.com'
}
$newKeys = #{
'Foo' = '67890'
}
Even if you wanted to read them from a file you could make that file a PowerShell script containing those hashtables and dot-source it. Or at least define the values as lists of key=value lines in text files, which can easily be turned into hashtables:
$newUrls = Get-Content 'new_urls.txt' | Out-String | ConvertFrom-StringData
$newKeys = Get-Content 'new_keys.txt' | Out-String | ConvertFrom-StringData
Then iterate over the top-level properties of your input JSON data and replace the nested properties with the new values:
$json = Get-Content $filePath | Out-String | ConvertFrom-Json
foreach ($name in $json.PSObject.Properties) {
$json.$name.BaseUrl = $newUrls[$name]
if ($newKeys.ContainsKey($name)) {
$json.$name.UrlKey = $newKeys[$name]
}
}
$json | ConvertTo-Json | Set-Content $filePath
Note that if your actual JSON data has more than 2 levels of hierarchy you'll need to tell ConvertTo-Json via the parameter -Depth how many levels it's supposed to convert.
Side note: piping the Get-Content output through Out-String is required because ConvertFrom-Json expects JSON input as a single string, and using Out-String makes the code work with all PowerShell versions. If you have PowerShell v3 or newer you can simplify the code a little by replacing Get-Content | Out-String with Get-Content -Raw.
Thank you, Ansgar for your detailed answer, which helped me a great deal. Ultimately, after having no luck iterating over the top-level properties of my input JSON data, I settled on the following code:
$json = (Get-Content -Path $filePath) | ConvertFrom-Json
$json.Foo.BaseUrl = $newUrls["Foo"]
$json.Bar.BaseUrl = $newUrls["Bar"]
$json.Blee.BaseUrl = $newUrls["Blee"]
$json.Foo.Key = $newKeys["Foo"]
$json | ConvertTo-Json | Set-Content $filePath
I hope this can help someone else.
To update values of keys at varying depth in the json/config file, you can pass in the key name using "." between the levels, e.g. AppSettings.Setting.Third to represent:
{
AppSettings = {
Setting = {
Third = "value I want to update"
}
}
}
To set the value for multiple settings, you can do something like this:
$file = "c:\temp\appSettings.json"
# define keys and values in hash table
$settings = #{
"AppSettings.SettingOne" = "1st value"
"AppSettings.SettingTwo" = "2nd value"
"AppSettings.SettingThree" = "3rd value"
"AppSettings.SettingThree.A" = "A under 3rd"
"AppSettings.SettingThree.B" = "B under 3rd"
"AppSettings.SettingThree.B.X" = "Z under B under 3rd"
"AppSettings.SettingThree.B.Y" = "Y under B under 3rd"
}
# read config file
$data = Get-Content $file -Raw | ConvertFrom-Json
# loop through settings
$settings.GetEnumerator() | ForEach-Object {
$key = $_.Key
$value = $_.Value
$command = "`$data.$key = $value"
Write-Verbose $command
# update value of object property
Invoke-Expression -Command $command
}
$data | ConvertTo-Json -Depth 10 | Out-File $file -Encoding "UTF8"

Access Object From JSON File in Powershell

I have a JSON file that I am reading in Powershell. The structure of the file is below.
[
["computer1", ["program1", versionX]],
["computer2", ["program2", versionY]],
["computer3", ["program3", "versionX"],
["program1", "versionZ"]
],
]
What I want in the program is use $env:computername and compare it with the computerX in the JSON file. If found a match, then iterate through and get the values of programName and ProgramVersion.
However, I don't know how to search through the objects and find ALL items under that.
This is what I have so far.
$rawData = Get-Content -Raw -Path "file.json" | ConvertFrom-Json
$computername=$env:computername
$data = $rawData -match $computername
This gives me objects under it. But how do I iterate through and get individual values?
But don't know what I do after that.
To start you need to be using a valid JSON file
{
"computer1": {
"program1": "versionX"
},
"computer2": {
"program2": "versionY"
},
"computer3": {
"program3": "versionX",
"program1": "versionZ"
}
}
Then you can access the PSObject Properties
$rawData = Get-Content -Raw -Path "file.json" | ConvertFrom-Json
$rawData.PsObject.Properties |
Select-Object -ExpandProperty Name |
ForEach-Object { IF ($_ -eq $env:COMPUTERNAME) {
Write-Host "Computer Name : " $_
Write-Host "Value : " $rawData."$_"
}
}
EDIT for Computer, Program, and Version as separate values
psobject.Properties.Name will give all the program names.
psobject.Properties.Name[0] will give the first program name.
psobject.Properties.value[0] will give the first program version value.
You need to increment the value to get second value, you can also use -1 as a shortcut for the last value.
$rawData = Get-Content -Raw -Path "file.json" | ConvertFrom-Json
$rawData.PsObject.Properties |
Select-Object -ExpandProperty Name |
ForEach-Object { IF ($_ -eq $env:COMPUTERNAME) {
$Computer = $_
$Values = $rawData.$_
}
}
$Computer
$Values.psobject.Properties
$Values.psobject.Properties.Name
$Values.psobject.Properties.Name[0]
$Values.psobject.Properties.value[0]
$Values.psobject.Properties.Name[1]
$Values.psobject.Properties.value[1]
You could also use the program name
$Values.program1
$Values.program2
$Values.program3

Export Matches array object to CSV in Powershell

I have a powershell script to find particular instances and then export them to CSV. Here's an example of the way the code works
$items = "Hello Tim", "Hola Bob", "Hello Susan"
$filter = $items | Select-String -Pattern "Hello"
$filter | Select-Object Line, Matches | Export-Csv "C:\log.csv"
Invoke-Item "C:\log.csv"
When I run the Select-Object in PS, it's nicely formatted info like this:
However, when I export to CSV, it exports the whole object and writes it as the following string: System.Text.RegularExpressions.Match[]
How can I get it to export just the first match or a listing of all matches into a single field when writing to CSV?
Here is one way using a PSObject:
$items = "Hello Tim", "Hola Bob", "Hello Susan"
$filter = $items | Select-String -Pattern "Hello"
$filter | % {New-Object PSObject -property #{
Line = $_.Line
Matches = $_.Matches.Groups[0].Value}
} | Export-Csv "C:\log.csv" -NoTypeInformation
Quickly note that Matches is an array which may create issues exporting to a csv.
Try joining the array into a string with a chosen delimiter. I used "::" in my example.
$filter | Select Line, #{Expression={$_.Matches -join "::"}; Label="Matches"} | Export-Csv "C:\log.csv"