1

I'm trying to create a JSON object in PowerShell so I can use it in a python script. I've had mixed results, I'm trying to compress this into one command so I can just run in from my python script

ForEach ($disk in (Get-Partition).DiskNumber | select -Unique | Sort-Object)`
{ConvertTo-Json @{$disk.ToString()=`
ForEach ($part in (Get-Partition -DiskNumber $disk).PartitionNumber | Sort-Object)`
{@{$disk.ToString()=Get-Partition -DiskNumber $disk -PartitionNumber $part | `
ForEach-Object {ConvertTo-Json @{PartitionNumber=$_.PartitionNumber;DriveLetter=$_.DriveLetter;Offset=$_.Offset`
}}}}}}

This is the output I get:

{
    "0":  [
              {
                  "1":  "{\r\n    \"DriveLetter\":  null,\r\n    \"Offset\":  17408,\r\n    \"PartitionNumber\":  1\r\n}"
              },
              {
                  "2":  "{\r\n    \"DriveLetter\":  \"F\",\r\n    \"Offset\":  135266304,\r\n    \"PartitionNumber\":  2\r\n}"
              }
          ]
}
{
    "1":  [
              {
                  "1":  "{\r\n    \"DriveLetter\":  null,\r\n    \"Offset\":  1048576,\r\n    \"PartitionNumber\":  1\r\n}"
              },
              {
                  "2":  "{\r\n    \"DriveLetter\":  null,\r\n    \"Offset\":  315621376,\r\n    \"PartitionNumber\":  2\r\n}"
              },
              {
                  "3":  "{\r\n    \"DriveLetter\":  null,\r\n    \"Offset\":  419430400,\r\n    \"PartitionNumber\":  3\r\n}"
              },
              {
                  "4":  "{\r\n    \"DriveLetter\":  \"C\",\r\n    \"Offset\":  553648128,\r\n    \"PartitionNumber\":  4\r\n}"
              }
          ]
}
{
    "2":  [
              {
                  "1":  "{\r\n    \"DriveLetter\":  null,\r\n    \"Offset\":  17408,\r\n    \"PartitionNumber\":  1\r\n}"
              },
              {
                  "2":  "{\r\n    \"DriveLetter\":  \"D\",\r\n    \"Offset\":  135266304,\r\n    \"PartitionNumber\":  2\r\n}"
              }
          ]
}

The problem is that ConvertTo-Json creates a list/array inside the first key and a dictionary for each object inside that list, is there any way to overcome this? The newline characters I can remove so that's not a big issue. Here's how I want it to look:

{
        "0":
            "1":  {"DriveLetter": null, "Offset": 17408, "PartitionNumber": 1},
            "2":  {"DriveLetter": "F", "Offset": 135266304, "PartitionNumber": 2}
    }
    {
        "1":
            "1":  {"DriveLetter": null, "Offset": 1048576, "PartitionNumber":  1},
            "2":  {"DriveLetter": null, "Offset": 315621376, "PartitionNumber":  2},
            "3":  {"DriveLetter": null, "Offset": 419430400, "PartitionNumber":  3},
            "4":  {"DriveLetter": "C", "Offset": 553648128, "PartitionNumber":  4}
    }
    {
        "2": 
            "1":  {"DriveLetter": null, "Offset": 17408, "PartitionNumber": 1},
            "2":  {"DriveLetter": "D", "Offset": 135266304, "PartitionNumber": 2}
    }
1
  • 1
    That is the correct output though, the output you desire here isn't even proper JSON syntax. Commented May 7, 2016 at 6:59

1 Answer 1

5

There are currently 3 issues with your code.

First, you call ConvertTo-Json (at least) twice - once on the inner Partition hashtable and then again on the outer hashtable.

Second, you haven't specified the Depth, meaning that the inner dictionaries will be collapsed.

Lastly, you should use the partition number $part as the key of the second level of dictionaries if you want the output you describe:

foreach ($disk in (Get-Partition).DiskNumber | select -Unique | Sort-Object){
  ConvertTo-Json -Depth 3 @{
    "$disk" = foreach ($part in (Get-Partition -DiskNumber $disk).PartitionNumber | Sort-Object){
      @{
        "$part" = Get-Partition -DiskNumber $disk -PartitionNumber $part | ForEach-Object {
          @{
            PartitionNumber = $_.PartitionNumber;
            DriveLetter     = $_.DriveLetter;
            Offset          = $_.Offset
          }
        }
      }
    }
  }
}

The above will produce n discrete JSON structures for n disks.


Move ConvertTo-Json outside the entire expression if you want a single structure with the disk array as the root object:

ConvertTo-Json -Depth 4 @(foreach ($disk in (Get-Partition).DiskNumber | select -Unique | Sort-Object){
  @{
    "$disk" = foreach ($part in (Get-Partition -DiskNumber $disk).PartitionNumber | Sort-Object){
      @{
        "$part" = Get-Partition -DiskNumber $disk -PartitionNumber $part | ForEach-Object {
          @{
            PartitionNumber = $_.PartitionNumber;
            DriveLetter     = $_.DriveLetter;
            Offset          = $_.Offset
          }
        }
      }
    }
  }
})
Sign up to request clarification or add additional context in comments.

1 Comment

Great thanks that did the trick, I couldn't understand what -depth was used for, could have saved me some time.

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.