在 powershell 中展平 netstat 命令输出
Posted
技术标签:
【中文标题】在 powershell 中展平 netstat 命令输出【英文标题】:Flatten netstat command output in powershell 【发布时间】:2019-05-07 10:43:17 【问题描述】:我正在尝试使用 netstat -bano
并在 PowerShell 中收集输出以满足一些非常具体的报告要求。
我有工作的正则表达式,应该能够解析这个输出没有问题,但是由于输出出现在多行上,正则表达式没有被正确处理
这是 netstat 的截图
期望的输出是这样的(全部在一行上):
TCP 0.0.0.0:135 0.0.0.0:0 监听 1092 RpcSs [svchost.exe] TCP 0.0.0.0:445 0.0.0.0:0 LISTENING 4 无法获取所有权信息 TCP 0.0.0.0:623 0.0.0.0:0 监听 7404 [LMS.exe] TCP 0.0.0.0:3389 0.0.0.0:0 监听 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
【问题讨论】:
屏幕截图并不总是有帮助;能否将netstat
的输出重定向到一个文件,并将内容作为代码粘贴到问题中?
我有工作的正则表达式,应该能够解析这个输出没问题。它在哪里?您是否使用单行模式(?s)
之类的标志
从搜索“netstat powershell”gallery.technet.microsoft.com/scriptcenter/…
我建议使用 Kory 评论中的链接,但在这里...(netstat -bano) -join "`n" -split "(?= \w\wP\s+(?:\d+\.|\[::))"|%$_ -replace "`n",' ' -replace '\s2,',','|convertfrom-csv
@KoryGill 你是对的,它没有考虑任何实际的 IPv6 地址(除了 [::])。确实如此,而且总体上效果更好:(netstat -bano | Select -skip 2) -join "`n" -split "(?= [TU][CD]P\s+(?:\d+\.|\[\w*:\w*:))"|%$_.trim() -replace "`n",' ' -replace '\s2,',','|convertfrom-csv
【参考方案1】:
在 TheMadTechnician 的基础上,我发现了一些破坏他输出的案例。具体来说:netstat 有时会跳过列;当友好的应用程序名称和可执行文件都在不同的行上输出时,它会破坏 CSV 格式。这是他/她的代码的更新版本,以将这些部分考虑在内:
$netstat = (netstat -abn | Select -skip 2) -replace "Address\s2,State", "Address,State,Application" -join "`n" `
-split "(?= [TU][CD]P\s+(?:\d+\.|\[\w*:\w*:))" | %
$_.trim() -replace "`n",' ' `
-replace '\*\:\*', '*:*,' `
-replace '\s2,', ',' `
-replace '(.*?),(.*?),(.*?),(.*?),(.*?),', '$1,$2,$3,$4,$5 '
| `
ConvertFrom-Csv
【讨论】:
【参考方案2】:我可能会这样做:
将输出拆分为单个字符串:
netstat -bano | Out-String
删除以 UDP 或 TCP 开头的行的缩进,使它们与其他行区分开来:
-replace '(?m)^ (TCP|UDP)', '$1'
将所有不以方括号开头的缩进行连接到它们之前的行:
-replace '\r?\n\s+([^\[])', "`t`$1"
将所有以方括号开头的缩进行连接到它们之前的行:
-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["
【讨论】:
谢谢!这个答案让我最接近。我唯一添加的是在换行符上拆分,以便我可以获取输出并创建一个对象【参考方案3】:您可以加入 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 '\s2,',',' |
ConvertFrom-Csv
# Filter the results for TCP connections and pipe the results to Format-Table
$Netstat | Where $_.Proto -eq 'TCP' | Format-Table
【讨论】:
以上是关于在 powershell 中展平 netstat 命令输出的主要内容,如果未能解决你的问题,请参考以下文章