将Powerstat中的netstat命令输出变平

时间:2018-12-05 19:32:22

标签: powershell parsing windows-10 netstat

我正在尝试使用netstat -bano并在PowerShell中收集输出以满足某些非常特定的报告要求。

我有正常的正则表达式,应该可以解析此输出,但是由于输出出现在多行中,因此正则表达式未得到正确处理

下面是有关netstat的截图

sample output

所需的输出是这样的(全部在一行上):

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]

无法在Windows之外使用工具,因此我只能使用常见的工具。

在PID上使用Get-Process匹配也不起作用,因为它将子进程信息隐藏在svchost和lsass下。与netstat一起使用的-b是完美的,因为它同时显示了svchost.exe和使用端口的过程

我搜寻了互联网以找到可行的解决方案,但大多数解决方案都以不同的分辨率解决

编辑**这是我最后的脚本,使用你们的输入

$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

2 个答案:

答案 0 :(得分:1)

我可能会做这样的事情:

  1. 将输出分解为单个字符串:

    netstat -bano | Out-String
    
  2. 删除以UDP或TCP开头的行的缩进,以使其与其他行区别开来:

    -replace '(?m)^  (TCP|UDP)', '$1'
    
  3. 将所有不以方括号开头的缩进线连接到其前一行:

    -replace '\r?\n\s+([^\[])', "`t`$1"
    
  4. 将所有以方括号开头的缩进线连接到其前一行:

    -replace '\r?\n\s+\[', "`t["
    

完整的语句:

(netstat -bano | Out-String) -replace '(?m)^  (TCP|UDP)', '$1' -replace '\r?\n\s+([^\[])', "`t`$1" -replace '\r?\n\s+\[', "`t["

答案 1 :(得分:0)

您可以将netstat的输出加入,以使其成为一个大的多行字符串,然后将其拆分为以空格开头,后跟TCP或UDP,后跟IP地址的行(以删除具有以下内容的应用程序的误报: “ TCP跟踪器”之类的名称)。然后从该行的开头或结尾处修剪所有空格,用逗号替换存在两个或多个空格的任何位置,然后将结果推送到ConvertFrom-Csv以创建对象。通过此操作,您可以进行过滤,分组或仅通过管道传输到Format-Table来查看结果。

$Netstat = (netstat -bano | Select -skip 2) -join "`n" -split "(?= [TU][CD]P\s+(?:\d+\.|\[\w*:\w*:))" | 
    ForEach-Object {$_.trim() -replace "`n",' ' -replace '\s{2,}',','} |
    ConvertFrom-Csv
# Filter the results for TCP connections and pipe the results to Format-Table
$Netstat | Where {$_.Proto -eq 'TCP'} | Format-Table