I am attempting to use netstat -bano
and collect the output in PowerShell for some very specific reporting requirements.
I have working regex that should be able to parse this output no problem, but since the output appears on multiple lines, the regex isn't being processed correctly
here's a screenshot of how it comes out of netstat
desired output is something like this (all on one line):
TCP 0.0.0.0:135 0.0.0.0:0 LISTENING 1092 RpcSs [svchost.exe] TCP 0.0.0.0:445 0.0.0.0:0 LISTENING 4 Can not obtain ownership information TCP 0.0.0.0:623 0.0.0.0:0 LISTENING 7404 [LMS.exe] TCP 0.0.0.0:3389 0.0.0.0:0 LISTENING 1224 TermService [svchost.exe]
the use of tools outside of Windows isn't possible, so I'm confined to common tools.
Using Get-Process
matching on PID also won't work, as it hides sub process information under svchost and lsass. netstat
with a -b
is perfect because it shows both svchost.exe
and the process that utilizes the port
I've scoured the internet to find a viable solution but most end in a different resolution
EDIT**here is my final script using input from you guys
$data = (netstat -bano |select -skip 4 | Out-String) -replace '(?m)^ (TCP|UDP)', '$1' -replace '\r?\n\s+([^\[])', "`t`$1" -replace '\r?\n\s+\[', "`t[" -split "`n"
[regex]$regex = '(?<protocol>TCP|UDP)\s+(?<address>\d+.\d+.\d+.\d+|\[::\]|\[::1\]):(?<port>\d+).+(?<state>LISTENING|\*:\*)\s+(?<pid>\d+)\s+(?<service>Can not obtain ownership information|\[\w+.exe\]|\w+\s+\[\w+.exe\])'
$output = @()
$data | foreach {
$_ -match $regex
$outputobj = @{
protocol = [string]$matches.protocol
address = [string]$matches.address -replace '\[::\]','[..]' -replace '\[::1\]','[..1]'
port = [int]$matches.port
state = [string]$matches.state -replace "\*:\*",'NA'
pid = [int]$matches.pid
service = ([string]$matches.service -replace 'Can not obtain ownership information','[System' -split '.*\[')[1] -replace '\]',''
subservice = ([string]$matches.service -replace 'Can not obtain ownership information','' -split '\[.*\]')[0]
}
$output += New-Object -TypeName PSobject -Property $outputobj
}
$output |select address,port,protocol,pid,state,service,subservice
I would probably do something like this:
mangle the output into a single string:
netstat -bano | Out-String
remove indention of the lines beginning with UDP or TCP to make them distinguishable from the other lines:
-replace '(?m)^ (TCP|UDP)', '$1'
join all indented lines that don't begin with a square bracket to the line preceding them:
-replace '\r?\n\s+([^\[])', "`t`$1"
join all indented lines that do begin with a square bracket to the line preceding them:
-replace '\r?\n\s+\[', "`t["
Complete statement:
(netstat -bano | Out-String) -replace '(?m)^ (TCP|UDP)', '$1' -replace '\r?\n\s+([^\[])', "`t`$1" -replace '\r?\n\s+\[', "`t["