1

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"
    }
  }
}
Keith
  • 689
  • 10
  • 27
  • Is the here-string one you construct manually, or are you getting that from some external system? In other words, can you change the input format, or is it important to be able to parse the exact input you've shown? – Mathias R. Jessen Nov 02 '22 at 14:37
  • I'm getting the format from a different .rb file. That is the reason why I want to convert from the format listed so I can just copy/paste to convert. – Keith Nov 02 '22 at 14:41

1 Answers1

1

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 {}
  • Split current line into path and value:
    $path = "override['abc_os_config']['local_administrators']['default_administrators']['abc.com"
    $value = "%w {}"
    
  • Remove unwanted stuff from the path:
    $path = "abc_os_config']['local_administrators']['default_administrators']['abc.com" 
    
  • In Set-TreeValue:
    • Split path into components, using '][' as separator (backslash-escaped because the function expects a RegEx)
      abc_os_config
      local_administrators
      default_administrators
      abc.com
      
    • Create any nested hashtable(s) and assign the value
zett42
  • 25,437
  • 3
  • 35
  • 72