4

Using Windows PowerShell terminal for running a PS script.

I need to do (among the rest) some json file parsing. I ended up in a strange situation, here below posting a minimal example:

Json file:

{
  "mykey": "myvalue"
}

PS script:

$jsonContent = Get-Content "myfile.json" -Raw | ConvertFrom-Json
$jsonContent.GetType().FullName
$key = "mykey"
Write-Host "Using bracket notation: $($jsonContent[$key])"
Write-Host "Using dot notation: $($jsonContent.$key)"

Output:

System.Management.Automation.PSCustomObject
Using bracket notation:
Using dot notation: myvalue

I expected the exact opposite, bracket notation to work and dot notation to not work: what's happening here?

As an additional detail, $PSVersionTable.PSVersion returns 5.1.22621.4391.

1
  • 2
    Generally, PowerShell supports only dot notation for accessing instance of types that do not also implement the IDictionary interface (e.g., ([pscustomobject] @{ Foo = 42 }).Foo). For instances of types that do implement the IDictionary interface, such as [hashtable], PowerShell suports index notation and dot notation interchangeably (e.g., @{ Foo = 42 }['Foo'] or @{ Foo = 42 }.Foo). Commented Jun 21 at 19:59

1 Answer 1

4

What happens is that indexing ([ ] index operator) works on objects that implement an indexer, and the default individual output from ConvertFrom-Json is a PSCustomObject (a custom object type in PowerShell). The properties of these objects are accessed via dot-notation by default which explains why $jsonContent.$key notation works fine. However, indexing would work by accessing the object's property collection, which does implement Item[string]:

$json = '{ "mykey": "myvalue" }' | ConvertFrom-Json
$key = 'mykey'
$json.psobject.Properties[$key].Value # myvalue

Perhaps, given the context of your question, you're likely coming from a different programming language and very likely you were expecting the output to be a dictionary type, which is totally possible if you're using PowerShell 7+ where you can tell ConvertFrom-Json that you want a dictionary type as output:

$json = '{ "mykey": "myvalue" }' | ConvertFrom-Json -AsHashtable
$key = 'mykey'
$json[$key] # myvalue

However, in Windows PowerShell 5.1 you're quite limited, you could achieve something similar by relying on the behind the scenes serializer used in this version:

Add-Type -AssemblyName System.Web.Extensions

$serializer = [Web.Script.Serialization.JavaScriptSerializer]::new()
$json = $serializer.Deserialize('{ "mykey": "myvalue" }', [hashtable])
$key = 'mykey'
$json[$key] # myvalue
Sign up to request clarification or add additional context in comments.

1 Comment

Needless to say, this question has led me to the question behind: "*why can't I access the properties of PS(Custom)Objects throught bracket notation?". If there would be a PowerShell implementation similar to dictionaries (see: #20591), dynamically setting NoteProperties would easier and getting them would be safer...

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.