Sunday, August 16, 2020

PowerShell: Reading, Modifying, and Saving Json Files

In the previous blog entry, PowerShell: Converting Json-Formatted Strings to/from Json-Objects and Json-Object Depth, it was shown how to correctly create Json-objects from Json-formatted strings and how to create Json-formatted strings from Json-objects by taking into account the depth of the underlying Json-object being manipulated. This post expands on the manipulation of Json-object with PowerShell by demonstrating how to:

  • read a Json-formatted string from a file
  • convert the Json-formatted string to a Json-object
  • modify the Json-object
  • covert the Json-object to a Json-formatted string
  • save the Json-formatted string to a file
The code used to perform the above tasks is as follows:

[string] $sourceWindowsVmTemplateFilename = 'Template2019.json'
[string] $destinationWindowsVmTemplateFilename =
    'TemplateAnyWindowsVM.json'
[string] $content =
     Get-Content -Raw -Path $sourceWindowsVmTemplateFilename
[int] $depth = Get-Depth $content
[PSCustomObject] $jsonObject = $content | 
                                 ConvertFrom-Json

if ($jsonObject.resources.properties.
      storageProfile.imageReference.sku -ne $windowsSku)
{
    $jsonObject.resources.properties.
        storageProfile.imageReference.sku = $windowsSku
    $jsonObject |
        ConvertTo-Json -Depth $depth |
        Set-Content $destinationWindowsVmTemplateFilename
}

The Json file is read by the Get-Content cmdlet where the -Raw command-line option causes the entire file to be read as a single string:

[string] $content = 
  Get-Content -Raw -Path $sourceWindowsVmTemplateFilename

A culled version of the Json identifies the Windows Sku is as follows:

<#
  "resources": [
  {
    {
      "properties": {
        "storageProfile": {
          "imageReference": {
             "sku": "2012-R2-Datacenter",
#>

Based on the pseudo-Json above the sku is accessible as follows:

resources.properties.storageProfile.imageReference.sku


The Json object's sku property is checked with an if statement and assigned as follows:

if ($jsonObject.resources.properties.
      storageProfile.imageReference.sku -ne $windowsSku)
{
  $jsonObject.resources.properties.
      storageProfile.imageReference.sku = $windowsSku

The Json-object's depth is computed as follows by using the Get-Depth method and the conversion from Json-object to Json-string is performed using the ConvertTo-Json cmdlet and its -Depth parameter:

[int] $depth = Get-Depth $content
$jsonObject | ConvertTo-Json -Depth $depth

The Json-formatted string is committed to a file using the Set-Content cmdlet:
    Set-Content $destinationWindowsVmTemplateFilename

The Json data being manipulated is based off of a real world situation where Azure virtual machines were being created as the host for specific versions of SharePoint on-prem. The Json-formatted string read from a file will be an Azure Resource Manager (ARM) template file used in the creating of a new virtual machine image for a standard Azure Windows SKU. Assigning the SKU will be the modification made to the Json-object which the supported SKUs are:
  • 2012-R2-Datacenter
  • 2016-Datacenter
  • 2019-Datacenter

The Window's SKU returned is simply a string that depends on the version of SharePoint to be installed on the virtual machine (SharePoint 2013, SharePoint 2016 or SharePoint 2019). The function used to return the appropriate Windows SKU is Get-WindowsSku:

function Get-WindowsSku()
{
  param (
    [ValidateSet(2013, 2016, 2019)]
    [Parameter(Mandatory)]
    [int] $sharePointVersionYear
  )

  [string] $sku

  switch($sharePointVersionYear){
    2013 { $sku = '2012-R2-Datacenter'}
    2016 { $sku = '2016-Datacenter'}
    2019 { $sku = '2019-Datacenter'}
  }

  return $sku
}





No comments :

Post a Comment