jsonstringpowershellherestring

PowerShell Here-String to Json


I'm attempting to convert a PowerShell Here-String to a Json file. This is a sample size of what I need to convert. I will be needing to convert a few dozen override files that can be quite long and doing this manually is not how I want to accomplish this.

$a = @'
override['abc_os_config']['local_administrators']['default_administrators']['abc.com'] = %w {}
override['abc_os_config']['local_administrators']['default_administrators']['devad.abc.com'] = %w {}
override['abc_os_config']['local_administrators']['default_administrators']['qad.abc.com'] = %w {}
override['CIS_Remediation_Windows']['security_options']['lanman_authentication_level'] = 3
'@

$b = $a.Replace('override', '').Replace("'", '').Replace('[', '\').Replace(']', '').Replace(' =',':')

$b.Split('\') | ConvertTo-Json -Depth 100

What is generated:

[
  "",
  "abc_os_config",
  "local_administrators",
  "default_administrators",
  "abc.com: %w {}\n",
  "abc_os_config",
  "local_administrators",
  "default_administrators",
  "devad.abc.com: %w {}\n",
  "abc_os_config",
  "local_administrators",
  "default_administrators",
  "qad.abc.com: %w {}\n",
  "CIS_Remediation_Windows",
  "security_options",
  "lanman_authentication_level: 3"
]

What should be generated:

{
  "abc_os_config": {
    "local_administrators": {
      "default_administrators": {
        "abc.com": "%w {}",
        "devad.abc.com": "%w {}",
        "qad.abc.com": "%w {}"
      }
    }
  },
  "CIS_Remediation_Windows": {
    "security_options": {
      "lanman_authentication_level": "3"
    }
  }
}

Solution

  • Here is a solution using my function Set-TreeValue, after some preprocessing of the original data:

    # Create sample input
    $a = @'
    override['abc_os_config']['local_administrators']['default_administrators']['abc.com'] = %w {}
    override['abc_os_config']['local_administrators']['default_administrators']['devad.abc.com'] = %w {}
    override['abc_os_config']['local_administrators']['default_administrators']['qad.abc.com'] = %w {}
    override['CIS_Remediation_Windows']['security_options']['lanman_authentication_level'] = 3
    '@ 
    
    # Split input text into an array of lines
    $textLines = $a -split '\r?\n'
    
    # Create an ordered hashtable
    $result = [ordered] @{}
    
    foreach( $line in $textLines ) {
        # Split current line into path and value
        $path, $value = $line -split "'\]\s*=\s*"
    
        # Remove unwanted stuff from the path
        $path = $path -replace "override\['"
        
        # Add current value to the tree, creating any nested hashtables as necessary
        Set-TreeValue -HashTable $result -Path $path -Value $value -PathSeparator "'\]\['"
    }
    
    # Specify a large enough depth as default value of 2 would skip deeper nested data
    $result | ConvertTo-Json -Depth 99
    

    Output:

    {
      "abc_os_config": {
        "local_administrators": {
          "default_administrators": {
            "abc.com": "%w {}",
            "devad.abc.com": "%w {}",
            "qad.abc.com": "%w {}"
          }
        }
      },
      "CIS_Remediation_Windows": {
        "security_options": {
          "lanman_authentication_level": "3"
        }
      }
    }
    

    How each line is processed:

    E. g. taking the line

    override['abc_os_config']['local_administrators']['default_administrators']['abc.com'] = %w {}