Created
April 27, 2020 16:01
-
-
Save daniel0x00/129368961c2b194a12cf8213171ab684 to your computer and use it in GitHub Desktop.
Converts PowerShell PoshNmap JSON output into a pipeline-enabled one with some other improvements
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-ScanResult { | |
# Parse an output of PoshNmap by @JustinGrote | |
# Author: Daniel Ferreira (@daniel0x00) | |
# License: BSD 3-Clause | |
<# | |
.SYNOPSIS | |
Parse and improve the JSON output of PoshNmap. | |
.EXAMPLE | |
Invoke-Nmap 40.100.12.0/24 -OutFormat JSON -ArgumentList '--top-ports=10' | ConvertFrom-Json | ConvertTo-ScanResult -ScannerLocation internet-australia | ConvertTo-Json -Depth 10 | |
.PARAMETER ScannerLocation | |
String. Represents the location of the scanner. It will be included in the output JSON. | |
Default: internet | |
.PARAMETER ScannerHostname | |
String. Represents the name of the scanner. It will be included in the output JSON. | |
Default: $env:COMPUTERNAME | |
#> | |
[CmdletBinding()] | |
[OutputType([PSCustomObject])] | |
param( | |
[Parameter(Position=0, Mandatory=$true, ValueFromPipeline=$true)] | |
[PSCustomObject] $InputObject, | |
[Parameter(Position=1, Mandatory=$false, ValueFromPipeline=$false)] | |
[string] $ScannerLocation='internet', | |
[Parameter(Position=2, Mandatory=$false, ValueFromPipeline=$false)] | |
[string] $ScannerHostname=$env:COMPUTERNAME | |
) | |
process { | |
# Prepare the array of results. | |
# Check if array is null, so there were no hosts up. Force results to output rest of metadata: | |
$ScanResults = $InputObject.nmaprun.host | |
$ScanResultsCount = $ScanResults.Length | |
if ($null -eq $ScanResults) { $ScanResults = 1 } | |
# Make global data of the scan request available 'per output record': | |
$ScanInfo = [PSCustomObject]@{ | |
info = $InputObject.nmaprun.scaninfo | |
command = $InputObject.nmaprun.args | |
target = [string](([regex]::Match($InputObject.nmaprun.args,'\s(?<target>[\d\-\./]+).?$')).groups['target'].value) | |
results = $ScanResultsCount | |
scanner = [PSCustomObject]@{ | |
hostname = $ScannerHostname | |
location = $ScannerLocation | |
} | |
} | |
# Output: | |
$ScanResults | ForEach-Object { | |
# Build summary: | |
$Summary = [PSCustomObject]@{ | |
tcp = [PSCustomObject]@{ | |
open = ($_.ports.port.foreach({$_.where({$_.protocol -eq 'tcp' -and $_.state.state -eq 'open'})})).portid -join '/' | |
closed = ($_.ports.port.foreach({$_.where({$_.protocol -eq 'tcp' -and $_.state.state -notmatch 'open'})})).portid -join '/' | |
} | |
udp = [PSCustomObject]@{ | |
open = ($_.ports.port.foreach({$_.where({$_.protocol -eq 'udp' -and $_.state.state -eq 'open'})})).portid -join '/' | |
closed = ($_.ports.port.foreach({$_.where({$_.protocol -eq 'udp' -and $_.state.state -notmatch 'open'})})).portid -join '/' | |
} | |
} | |
# Output: | |
$_ | Select-Object *, @{n='scan';e={$ScanInfo}}, @{n='summary';e={$Summary}} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment