Last active
July 27, 2021 14:56
-
-
Save daniel0x00/15f8871f2c0aca803e7f60ae0a1f42c1 to your computer and use it in GitHub Desktop.
PowerShell function that converts a PowerShell Object into a DotNotation object
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
function ConvertTo-DotNotation { | |
# PowerShell cmdlet that converts a PowerShell/JSON object into a dot.notation array. | |
# For Splunk use cases, this cmdlet enables data to be TERM() and PREFIX() ready. | |
# Author: Daniel Ferreira (@daniel0x00) | |
# License: BSD 3-Clause | |
# Source: https://gist.github.com/daniel0x00/15f8871f2c0aca803e7f60ae0a1f42c1 | |
# Note: any improvement opportunity to make this function "a 1-liner" producing same results is very welcomed. | |
# 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 | |
.EXAMPLE | |
Resolve-DnsName -Name splunk.com | Select-Object *, @{n='dotnotation';e={$_ | ConvertTo-DotNotation}} | ConvertTo-Json | |
# Result: | |
[ | |
{ | |
"Address": "52.5.196.118", | |
"IPAddress": "52.5.196.118", | |
"QueryType": 1, | |
"IP4Address": "52.5.196.118", | |
"Name": "splunk.com", | |
"Type": 1, | |
"CharacterSet": 1, | |
"Section": 1, | |
"DataLength": 4, | |
"TTL": 18, | |
"dotnotation": [ | |
"Address=52.5.196.118", | |
"IPAddress=52.5.196.118", | |
"QueryType=A", | |
"IP4Address=52.5.196.118", | |
"Name=splunk.com", | |
"Type=A", | |
"CharacterSet=Unicode", | |
"Section=Answer", | |
"DataLength=4", | |
"TTL=18" | |
] | |
}, | |
{ | |
"Address": "35.153.82.195", | |
"IPAddress": "35.153.82.195", | |
"QueryType": 1, | |
"IP4Address": "35.153.82.195", | |
"Name": "splunk.com", | |
"Type": 1, | |
"CharacterSet": 1, | |
"Section": 1, | |
"DataLength": 4, | |
"TTL": 18, | |
"dotnotation": [ | |
"Address=35.153.82.195", | |
"IPAddress=35.153.82.195", | |
"QueryType=A", | |
"IP4Address=35.153.82.195", | |
"Name=splunk.com", | |
"Type=A", | |
"CharacterSet=Unicode", | |
"Section=Answer", | |
"DataLength=4", | |
"TTL=18" | |
] | |
} | |
] | |
.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