Skip to content

Instantly share code, notes, and snippets.

@daniel0x00
Last active December 26, 2020 12:19
Show Gist options
  • Save daniel0x00/4e57d9a6c71399697d34e0d82d25e63f to your computer and use it in GitHub Desktop.
Save daniel0x00/4e57d9a6c71399697d34e0d82d25e63f to your computer and use it in GitHub Desktop.
Converts a JSON object into a dot.notation array
function ConvertTo-DotNotation {
# Converts a JSON object into a dot.notation array
# Author: Daniel Ferreira (@daniel0x00)
# License: BSD 3-Clause
# TODO: Support for Dictionary object.
# In the meantime, Dictionaries must be casted into PSCustomObject like this: [PSCustomObject][Hashtable]$object
<#
.SYNOPSIS
Converts a JSON object into a dot.notation array. It is required to first convert the json string into a PSCustomObject.
.EXAMPLE
@'
{
"nmaprun": {
"scanner": "nmap",
"args": "./nmap -T4 -F --open -oX - --stats-every 200ms 10.0.0.0/24",
"start": "1587811935",
"version": "7.80",
"scaninfo": {
"type": "syn",
"protocol": "tcp",
"numservices": "100",
},
"host": [
{
"starttime": "1587811936",
"endtime": "1587811940",
"status": {
"state": "up",
"reason": "echo-reply",
"reason_ttl": "247"
}
}
]
}
}
'@ | ConvertFrom-Json | ConvertTo-DotNotation
# Result:
nmaprun.scanner=nmap
nmaprun.args=./nmap -T4 -F --open -oX - --stats-every 200ms 10.0.0.0/24
nmaprun.start=1587811935
nmaprun.version=7.80
nmaprun.scaninfo.type=syn
nmaprun.scaninfo.protocol=tcp
nmaprun.scaninfo.numservices=100
nmaprun.host.1.starttime=1587811936
nmaprun.host.1.endtime=1587811940
nmaprun.host.1.status.state=up
nmaprun.host.1.status.reason=echo-reply
nmaprun.host.1.status.reason_ttl=247
.PARAMETER InputObject
PSCustomObject. Mandatory. Pipeline enabled.
The input JSON passed as PSCustomObject.
#>
[CmdletBinding()]
[OutputType([System.Array])]
param(
[Parameter(Position=0, Mandatory=$true, ValueFromPipeline=$true)]
[PSCustomObject] $InputObject,
[Parameter(Position=1, Mandatory=$false, ValueFromPipeline=$false)]
[string] $Parent=''
)
begin { $name = ''; }
process {
foreach ($item in $InputObject.PSObject.Properties) {
$name += "$Parent$($item.Name)"
# Match everything but objects
if (($item.TypeNameOfValue -notmatch 'Object') -and ($item.TypeNameOfValue -notmatch 'Microsoft.PowerShell') -and ($item.TypeNameOfValue -notmatch 'Selected.System')) {
# Match string array:
if ($item.TypeNameOfValue -match 'String\[\]$') {
# Output:
if ($item.Value.Length -eq 1) {
"{0}={1}" -f $name, $item.Value[0] -replace ' ','__' -replace ',','___'
#$output
$name = ''
}
else {
for ($x=0; $x -lt $item.Value.Length; $x++) {
"{0}={1}" -f "$name.$($x+1)", $item.Value[$x] -replace ' ','__' -replace ',','___'
#$output
}
$name = ''
}
}
# Match any other type of object that can be converted into text:
else {
# Output:
"{0}={1}" -f $name, $item.Value -replace ' ','__' -replace ',','___'
#$output
$name = ''
}
}
# Match null values:
elseif (($null -eq $item.Value) -or ($item.Value.Count -eq 0)) {
# Output:
"{0}=null" -f $name
$name = ''
}
# Match array:
elseif ($item.TypeNameOfValue -match 'Object\[\]') {
# Output:
$objectType = $item.Value[0].GetType()
if ($objectType -match 'Object') {
$Parent = $name
for ($x=0; $x -lt $item.Value.Length; $x++) {
#$name = "$Parent.$($x+1)."
#$child = $item.Value[$x]
ConvertTo-DotNotation -Input ($item.Value[$x]) -Parent ("$Parent.$($x+1).")
}
$Parent = $Parent -replace '\.\w+$','.' -replace ($name -replace '\.[\d]+\.',''),''
$name = ''
}
else {
if ($item.Value.Length -eq 1) {
"{0}={1}" -f $name, $item.Value[0] -replace ' ','__' -replace ',','___'
#$output
$name = ''
}
else {
for ($x=0; $x -lt $item.Value.Length; $x++) {
"{0}={1}" -f "$name.$($x+1)", $item.Value[$x] -replace ' ','__' -replace ',','___'
#$output
}
$name = ''
}
}
}
# Match objects:
else {
ConvertTo-DotNotation -Input $item.Value -Parent "$name."
$name = ''
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment