1

I want to change content of JSON file from a bat file. I thought doing that by calling powershell and use a single-line pipeline command.

Here I am so far:

Get-Content test.json -raw | ConvertFrom-Json | Set-ItemProperty -Name "ServiceAccess.Host" -Value "localhost:5000" |  ConvertTo-Json | Set-Content test.json

Here is my JSON file:

{
    "ServiceAccess":  
    {
        "Host":  "localhost:3000"
    }
}

It does not work:

Set-ItemProperty : The input object cannot be bound to any parameters for the command either because the command does not take pipeline input or the input and its properties do not match any of the parameters that take pipeline input. At line:1 char:49 + ... From-Json | Set-ItemProperty -Name "ServiceAccess.Host" -Value "local ... + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + CategoryInfo : InvalidArgument: (@{ServiceAccess=}:PSObject) [Set-ItemProperty], ParameterBindingExcept ion + FullyQualifiedErrorId : InputObjectNotBound,Microsoft.PowerShell.Commands.SetItemPropertyCommand

What is the proper way to change a JSON object in the powershell pipeline?

3 Answers 3

2

If you must do it all in a single pipeline (spread across multiple lines for readability):

Get-Content test.json -Raw | ConvertFrom-Json |
  ForEach-Object { $_.ServiceAccess.Host = 'localhost:5000'; $_ } |
    ConvertTo-Json | Set-Content test.json

Note that using -Raw to read the entire input file at once makes it possible to write back to the same file in the same pipeline (without -Raw, you'd have to enclose the Get-Content call in (...) to force reading of its lines all at once).

In the ForEach-Object block, the input object is first modified ($_.ServiceAccess.Host = 'localhost:5000'), and then (;) passed through ($_) to ConvertTo-Json for reconversion to JSON, which Set-Content then writes back to the input file.


As for what you tried:

*-Item* cmdlets such as Set-ItemProperty aren't designed for general in-memory object manipulation.

Instead, an item is a specific type of object that a PowerShell provider exposes, such as a file or folder in the case of the filesystem provider, or a registry key in the case of the registry provider.

Sign up to request clarification or add additional context in comments.

Comments

0
$Json = Get-Content test.json -Raw | ConvertFrom-Json
$Json.ServiceAccess.Host = 'localhost:5000'
$Json | ConvertTo-Json | Set-Content test.json

If you bang on it for awhile you could probably get this into a single line of code, but you may run into file locking issues when Get-Content and Set-Content are operating on the same file in the same pipeline.

Be aware that PowerShell's JSON support is a little quirky. This is partially due to the fact that it uses the .Net dialect of JSON, which isn't always identical to the JSON that other systems use. Second, JSON support is a relatively recent addition, so Windows PowerShell (v5.1 and below) is more quirky than PowerShell Core (v6+). If your outermost JSON element is an unnamed array, for example, PowerShell will tend to drop the square brackets.

Comments

0

try this:

$json = get-content test.json | ConvertFrom-Json           
$json | % { $_.ServiceAccess.Host = "localhost:5000" }     
$json | ConvertTo-Json | out-file test1.json               

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.