Search code examples
jsonpowershellconvertfrom-json

Powershell Access Nested Object in JSON after using ConvertFrom-Json


I've been able to parse some JSON succesfully up to a point but cannot access a specific object:

My overall code:

$myFile = Get-Content -Raw -Path UKStore.json | ConvertFrom-Json

$counter = 0
foreach ($link in $myFile.links)
{
    Write-Host $link.id "and" $link.name
    Write-Host $link.default_sku
    $counter+=1

}

Write-Host $counter
Read-Host -Prompt "Press Enter to exit"

Now, what I get for each iteration is something like this below. So, line 1 is great and is outputting what I need but line 2 needs to be processed further:

EP9000-NPEE00001_00-GCRASHBAND000001 and Crash Bandicoot®

@{amortizeFlag=False; bundleExclusiveFlag=False; chargeImmediatelyFlag=False; charge_type_id=0; credit_card_required_flag=0; defaultSku=True; display_price=£3.99; eligibilities=System.Object[]; entitlements=System.Object[]; id=EP9000-NPEE00001_00-GCRASHBAND000001-EE03; is_original=False; name=Full Game; platforms=System.Object[]; price=399; rewards=System.Object[]; seasonPassExclusiveFlag=False; skuAvailabilityOverrideFlag=False; sku_type=0; type=standard}

I simply cannot, no matter what notation I try get access to the properties in "$link.default_sku" I'm clearly not connecting something right in my brain but I feel that:

$link.default_sku.display_price

Should give me the value £3.99 from the above object but instead I get nothing returned at all. Any help to get through this mental blockage would be great.

Went a level higher for Format-Custom

$link | Format-Custom

Output:

class PSCustomObject
    {
      bucket = games
      container_type = product
      content_type = 1
      default_sku = @{amortizeFlag=False; bundleExclusiveFlag=False; chargeImmediatelyFlag=False; charge_type_id=0;
      credit_card_required_flag=0; defaultSku=True; display_price=£24.99; eligibilities=System.Object[];
      entitlements=System.Object[]; id=EP2595-CUSA07370_00-0001000100010001-E001; is_original=False; name=Full Game;
      platforms=System.Object[]; price=2499; rewards=System.Object[]; seasonPassExclusiveFlag=False;
      skuAvailabilityOverrideFlag=False; sku_type=0; type=standard}
      gameContentTypesList =
      game_contentType = Full Game
      id = EP2595-CUSA07370_00-0001000100010001
      images =
      name = Past Cure™
      playable_platform = PS4™
      provider_name = Phantom 8 Studio UG
      release_date =
        class DateTime
        {
          Date =
            class DateTime
            {
              Date =
                class DateTime
                {
                  Date =
                    class DateTime
                    {
                      Date =
                        class DateTime
                        {
                          Date = 23/02/2018 00:00:00
                          Day = 23
                          DayOfWeek = Friday
                          DayOfYear = 54
                          Hour = 0
                          Kind = Utc
                          Millisecond = 0
                          Minute = 0
                          Month = 2
                          Second = 0
                          Ticks = 636549408000000000
                          TimeOfDay = 00:00:00
                          Year = 2018
                          DateTime = 23 February 2018 00:00:00
                        }
                      Day = 23
                      DayOfWeek = Friday
                      DayOfYear = 54
                      Hour = 0
                      Kind = Utc
                      Millisecond = 0
                      Minute = 0
                      Month = 2
                      Second = 0
                      Ticks = 636549408000000000
                      TimeOfDay =
                        class TimeSpan
                        {
                          Ticks = 0
                          Days = 0
                          Hours = 0
                          Milliseconds = 0
                          Minutes = 0
                          Seconds = 0
                          TotalDays = 0
                          TotalHours = 0
                          TotalMilliseconds = 0
                          TotalMinutes = 0
                          TotalSeconds = 0
                        }
                      Year = 2018
                      DateTime = 23 February 2018 00:00:00
                    }
                  Day = 23
                  DayOfWeek = Friday
                  DayOfYear = 54
                  Hour = 0
                  Kind = Utc
                  Millisecond = 0
                  Minute = 0
                  Month = 2
                  Second = 0
                  Ticks = 636549408000000000
                  TimeOfDay =
                    class TimeSpan
                    {
                      Ticks = 0
                      Days = 0
                      Hours = 0
                      Milliseconds = 0
                      Minutes = 0
                      Seconds = 0
                      TotalDays = 0
                      TotalHours = 0
                      TotalMilliseconds = 0
                      TotalMinutes = 0
                      TotalSeconds = 0
                    }
                  Year = 2018
                  DateTime = 23 February 2018 00:00:00
                }
              Day = 23
              DayOfWeek = Friday
              DayOfYear = 54
              Hour = 0
              Kind = Utc
              Millisecond = 0
              Minute = 0
              Month = 2
              Second = 0
              Ticks = 636549408000000000
              TimeOfDay =
                class TimeSpan
                {
                  Ticks = 0
                  Days = 0
                  Hours = 0
                  Milliseconds = 0
                  Minutes = 0
                  Seconds = 0
                  TotalDays = 0
                  TotalHours = 0
                  TotalMilliseconds = 0
                  TotalMinutes = 0
                  TotalSeconds = 0
                }
              Year = 2018
              DateTime = 23 February 2018 00:00:00
            }
          Day = 23
          DayOfWeek = Friday
          DayOfYear = 54
          Hour = 0
          Kind = Utc
          Millisecond = 0
          Minute = 0
          Month = 2
          Second = 0
          Ticks = 636549408000000000
          TimeOfDay =
            class TimeSpan
            {
              Ticks = 0
              Days = 0
              Hours = 0
              Milliseconds = 0
              Minutes = 0
              Seconds = 0
              TotalDays = 0
              TotalHours = 0
              TotalMilliseconds = 0
              TotalMinutes = 0
              TotalSeconds = 0
            }
          Year = 2018
          DateTime = 23 February 2018 00:00:00
        }
      restricted = False
      revision = 15
      short_name = Past Cure™
      timestamp = 1648353047000
      top_category = downloadable_game
      url = https://store.playstation.com/store/api/chihiro/00_09_000/container/GB/en/999/EP2595-CUSA07370_00-0001000100010
      001/1648353047
    }

Solution

  • $link.default_sku contains a string, not a nested object, and that's why $link.default_sku.display_price doesn't work.

    That string happens to be the stringification of a nested [pscsutomobject], such as you would get with string interpolation (e.g., "$([pscustomobject] @{ foo=1; bar =2 })" or - most likely in this case - when the default recursion depth of 2 is exceeded during creation of JSON text using ConvertTo-Json, a common and regrettable pitfall - see this post.

    You have two options:

    • Fix the problem at the source, by passing a -Depth argument that is sufficiently high to ConvertTo-Json to prevent truncation when the UKStore.json file is created.

    • If that is not an option, you'll have to do text parsing to extract the value of interest from the string. Note, however, that this isn't generally robust, because the stringification format of [pscustomobject]s is meant for the human observer, not for programmatic processing. Notably, quotation marks around string values with spaces are lost:

      # -> '£24.99'
      $link.default_sku -replace '(?s).+\bdisplay_price=([^;]+).+', '$1'