weird powershell bug with printing variables and json?

This topic contains 6 replies, has 3 voices, and was last updated by Profile photo of js js 1 week ago.

  • Author
    Posts
  • #73139
    Profile photo of js
    js
    Participant

    When I run this in a powershell script, $data2 prints out nothing (and I can't pipe it to where, etc). But if I copy and paste it to the prompt, it works fine (or I run it in another script):

    $data1 = (Get-Content ./file1.json | ConvertFrom-Json).data1
    $data1
    
    $data2 = (Get-Content ./file2.json | ConvertFrom-Json).data2
    $data2

    file1.json contains:

    {
        "data1": [
          {
            "value1": 6
          }
        ]
    }

    file2.json contains:

    {
        "data2": [
          {
            "value2": 12
          }
        ]
    }

    script output:

    value1
    ------
         6
          
    
    
    
  • #73163
    Profile photo of Dirk
    Dirk
    Participant

    Yes, this is a weird one I have stumbled across myself, too. It has something to do with how the PowerShell formatting system works under the hood. (see here for more info
    How PowerShell Formatting and Outputting REALLY works):
    You can get around it by piping your output to Out-Host or Out-Default.

    $data1 = (Get-Content c:\users\dirk_bremen\desktop\file1.json | ConvertFrom-Json).data1
    $data1 | Out-Host
    
    $data2 = (Get-Content c:\users\dirk_bremen\desktop\file2.json | ConvertFrom-Json).data2
    $data2
  • #73175
    Profile photo of js
    js
    Participant

    I think this is a simpler version of it. Apparently you can't output or process more than once type of object in the same script:

    $var1 = New-Object PSObject -Prop @{data1=6}
    $var1
    $var2 = New-Object PSObject -Prop @{data2=12}
    $var2
    
    
    data1
    ------
    6
  • #73178
    Profile photo of Curtis Smith
    Curtis Smith
    Participant
    $var1 = New-Object PSObject -Prop @{data1=6}
    $var1 | Out-Host
    $var2 = New-Object PSObject -Prop @{data2=12}
    $var2 | Out-Host
    
    • #73198
      Profile photo of js
      js
      Participant

      Here's a weirder example. Powershell just seems to keep a list of properties for each script, and only lets those out:

      $var1 = New-Object PSObject -prop @{data1=6;data3=5}
      $var1
      $var2 = New-Object PSObject -prop @{data2=12;data3=6}
      $var2
      
      
      data1 data3
      ----- -----
          6     5
                6
  • #73204
    Profile photo of Curtis Smith
    Curtis Smith
    Participant

    You should really take a look at the link Dirk provided.

    $var1 = New-Object PSObject -prop @{data1=6;data3=5}
    $var2 = New-Object PSObject -prop @{data2=12;data3=6}
    
    Write-Host "Both Objects as a collection to Out-Host" -ForegroundColor Green
    $var1, $var2 | Out-Host
    
    Write-Host "Individual Objects to Out-Host" -ForegroundColor Green
    $var1 | Out-Host
    $var2 | Out-Host
    
    Write-Host "Both Objects as a collection to Format Table" -ForegroundColor Green
    $var1, $var2 | Format-Table
    
    Write-Host "Both Objects as a collection to Format List" -ForegroundColor Green
    $var1, $var2 | Format-List

    Results

    Both Objects as a collection to Out-Host
    data3 data1
    ----- -----
        5     6
        6      
    
    Individual Objects to Out-Host
    data3 data1
    ----- -----
        5     6
    
    data2 data3
    ----- -----
       12     6
    
    Both Objects as a collection to Format Table
    data3 data1
    ----- -----
        5     6
        6      
    
    Both Objects as a collection to Format List
    data3 : 5
    data1 : 6
    
    data2 : 12
    data3 : 6

    Quote from the page at the link provided by Dirk.
    "Now, if there is not a registered view for a datatype, then Out-Default looks at the FIRST OBJECT IN THE STREAM to determine how many properties the object has 5 or more properties, it send the ENTIRE STREAM to Format-List, otherwise it sends the ENTIRE STREAM to Format-Table. When it sends the stream to Format-Table, that command needs to generate columns. It does this by looking at the properties of the FIRST OBJECT – those become the columns. If the first Object has 2 properties, you'll get a 2 column table even if all the other objects in the stream have 10 properties."

    • #73208
      Profile photo of js
      js
      Participant

      Thanks for the quote. I didn't know format-table was involved. I skimmed that page, but I didn't notice that section.

      You can also rename one of the properties:

      $var1 = New-Object PSObject -prop @{data1=6;data3=5}
      $var1
      $var2 = New-Object PSObject -prop @{data2=12;data3=6}
      $var2 | select @{name='data1'; expression = {$_.data2}},data3
      
      
      data3 data1
      ----- -----
          5     6
          6    12

You must be logged in to reply to this topic.