JSON Serialization/Deserialization in PowerShell

Since PowerShell is based on .NET and makes it easy to access .NET functionality, PowerShell can use JSON serializer that comes with .NET.  The follow snippet of code shows how to deserialize a JSON string into an XML object and then how to take an XML object and serialize it to JSON:

Add-Type -Assembly System.ServiceModel.Web,System.Runtime.Serialization
 
function Convert-JsonToXml([string]$json)
{
    $bytes = [byte[]][char[]]$json
    $quotas = [System.Xml.XmlDictionaryReaderQuotas]::Max
    $jsonReader = [System.Runtime.Serialization.Json.JsonReaderWriterFactory]::CreateJsonReader($bytes,$quotas)
    try
    {
        $xml = new-object System.Xml.XmlDocument
 
        $xml.Load($jsonReader)
        $xml
    }
    finally
    {
        $jsonReader.Close()
    }
}
 
function Convert-XmlToJson([xml]$xml)
{
    $memStream = new-object System.IO.MemoryStream
    $jsonWriter = [System.Runtime.Serialization.Json.JsonReaderWriterFactory]::CreateJsonWriter($memStream)
    try
    {
        $xml.Save($jsonWriter)
        $bytes = $memStream.ToArray()
        [System.Text.Encoding]::UTF8.GetString($bytes,0,$bytes.Length)
    }
    finally
    {
        $jsonWriter.Close()
    }
}
 
$str = '{"fname":"John", "lname":"Doe", "age":42, "addr":{"city":"Gotham", "street1":"123 Guano Way", "state":"NY"}}'
 
$xml = Convert-JsonToXml $str
$xml.root.fname
$xml.root.lname
 
$json = Convert-XmlToJson $xml
$json

Note that this does require .NET 3.5.  However it serves to show that when you’re looking for some functionality, if you can’t find it in cmdlet or module form first, check the .NET framework next.  You would be surprised what kind of cool functionality you can find in there.  There’s a bit more to this story.  You can use the WCF DataContractJsonSerializer to bypass XML and directly serialize/deserialize .NET types.  I can’t take credit for this idea though – that was Jaykul’s.

This entry was posted in PowerShell 2.0. Bookmark the permalink.

9 Responses to JSON Serialization/Deserialization in PowerShell

  1. Mitch R. says:

    Hi Keith! I realize that this is a pretty old blog post, but I just came across it and seem to get a weird result. When I try to run the Convert-JSONtoXML function against a variable which has JSON data, all that is returned is the root namespace:

    PS C:\Users\m> Convert-JsonToXml($json)

    root
    —-
    root

    PS C:\Users\Administrator> $json
    {
    “images”: [
    {
    “status”: “SAVING”,
    “updated”: “2012-08-15T17:10:39Z”,
    “links”: ” “,
    “id”: “xxx”,
    “name”: “xxx”,
    “created”: “2012-08-15T17:10:39Z”,
    “minDisk”: 40,
    “server”: “xxx”,
    “progress”: 25,
    “minRam”: 1024,
    “metadata”: “xxx”
    },

    The JSON variable content is massive, so I didn’t put all of it here, but have you seen any output like this before? I’m a little too new to the whole JSON/XML conversation to be able to figure this out, and was hoping to find someone who’d solved this one. Essentially, I’m trying to get this massive list of JSON data into a format where I can play with the output a bit.

    Many thanks up front for any time you can spare!

    • rkeithhill says:

      Hi Mitch,

      What you’re seeing is just the way PowerShell displays an XML doc by default e.g.:

      2> $xml = [xml]'<a><b><c/></b></a>'
      3> $xml
      
      doc
      ---
      doc

      Try this looking at the xml like so:

      7> $xml.InnerXml
      <a><b></b></a></pre>
      
      If you happen to be running the PowerShell Community Extensions then run the xml through the Format-Xml cmdlet e.g.:
      
      
      8> $xml | Format-Xml
        <a>
          <b>
            <c/>
          </b>
        </a>
      </pre
  2. bunyk says:

    Please use tags [ sourcecode language = ], and your code will be easier to copy:

    Add-Type -Assembly System.ServiceModel.Web,System.Runtime.Serialization
    

    And thank you for your post.

  3. bunyk says:

    Also, how to serialize powershell objects into JSON? For example result Get-EventLog command?

    • rkeithhill says:

      If you have PowerShell v3 or later, use the ConvertTo-Json command.

      Get-EventLog Application -EntryType Error | select -First 10 | ConvertTo-Json

      • bunyk says:

        Yeah, thats very nice cmdlet, but I had requirement to support also v2 😦 . In the end I decided to use simple string formatting, because the structure of final JSON is known.

  4. joel says:

    What about UTF8-Support? When I Try to Use it, with those german “ü” it doesnt work… Where can i set the Encoding?

Leave a reply to rkeithhill Cancel reply