Ric*_*Ric 4 script powershell netstat
首先,我只想确保用户 Erik Bitemo 获得了我在这里使用的原始代码的信任。输出是我正在寻找的一个例外:其中一个端口消失并且“System System5”出现在它的位置,我无法弄清楚为什么会发生这种情况。
目标:在同一行上显示所有 TCP(侦听)和 UDP 端口以及与每个端口关联的进程。
正在使用的一种衬垫:
$nets = netstat -bano|select-string 'LISTENING|UDP'; foreach ($n in $nets) { $p = $n -replace ' +',' '; $nar = $p.Split(' '); $pname = $(Get-Process -id $nar[-1]).ProcessName; $n -replace "$($nar[-1])","$($ppath) $($pname)"; }
Run Code Online (Sandbox Code Playgroud)
示例输出:
TCP 0.0.0.0:135 0.0.0.0:0 LISTENING svchost
TCP 0.0.0.0: System System5 0.0.0.0:0 LISTENING System
TCP 0.0.0.0:623 0.0.0.0:0 LISTENING LMS
它更改的端口是 445,但我不知道为什么当其余端口按预期工作时它只更改那个端口。为什么脚本将 445 更改为“System System5”?
不幸的是,无法使用其他工具,因此我只能使用内置的 Windows 工具。
JosefZ 的回答完美地解释了您的问题。您正在使用正则表达式,它正在做您要求它做的事情,只是可能替换的内容超出了您的预期。
A面值得注意的是,你问netstat到
显示创建每个连接或侦听端口所涉及的可执行文件
用 b 开关。但是,select-string由于该过程在其他数据之后出现在自己的行上,因此您将其删除。那不是世界末日,而是因为您可以使用-Contextof 之类的东西Select-String来实现它,但这必须在下一次更仔细地研究。
我想就您在这种情况下可以做什么提供其他建议。
不幸的是,无法使用其他工具,因此我只能使用内置的 Windows 工具。
有趣的是,你至少有 Windows 8 吗?如果你这样做,你可以只使用Get-NetTCPConnection本质上netstat是对象形式的cmdlet 。
所以你可以这样做,这应该可以让你轻松获得相同的信息
get-nettcpconnection | select local*,remote*,state,@{Name="Process";Expression={(Get-Process -Id $_.OwningProcess).ProcessName}}
Run Code Online (Sandbox Code Playgroud)
没有 Windows 8+?那么我们可以改进您的解析脚本。更进一步创建对象将防止正则表达式匹配问题。
netstat -ano | Where-Object{$_ -match 'LISTENING|UDP'} | ForEach-Object{
$split = $_.Trim() -split "\s+"
[pscustomobject][ordered]@{
"Proto" = $split[0]
"Local Address" = $split[1]
"Foreign Address" = $split[2]
# Some might not have a state. Check to see if the last element is a number. If it is ignore it
"State" = if($split[3] -notmatch "\d+"){$split[3]}else{""}
# The last element in every case will be a PID
"Process Name" = $(Get-Process -Id $split[-1]).ProcessName
}
}
Run Code Online (Sandbox Code Playgroud)
如果您仅限于 PowerShell v2,则需要更改 psobject 和有序转换
netstat -ano | Where-Object{$_ -match 'LISTENING|UDP'} | ForEach-Object{
$split = $_.Trim() -split "\s+"
New-Object -Type pscustomobject -Property @{
"Proto" = $split[0]
"Local Address" = $split[1]
"Foreign Address" = $split[2]
# Some might not have a state. Check to see if the last element is a number. If it is ignore it
"State" = if($split[3] -notmatch "\d+"){$split[3]}else{""}
# The last element in every case will be a PID
"Process Name" = $(Get-Process -Id $split[-1]).ProcessName
}
} | Select "Proto", "Local Address", "Foreign Address", "State", "Process Name"
Run Code Online (Sandbox Code Playgroud)
最后一条select语句保证了属性顺序,否则会被打乱,并且在功能上等同于[ordered]
所以这会让你像这样输出......
Proto Local Address Foreign Address State Process Name
----- ------------- --------------- ----- ------------
TCP 0.0.0.0:135 0.0.0.0:0 LISTENING svchost
TCP 0.0.0.0:445 0.0.0.0:0 LISTENING System
TCP 0.0.0.0:1279 0.0.0.0:0 LISTENING PlexDlnaServer
TCP 0.0.0.0:2869 0.0.0.0:0 LISTENING System
Run Code Online (Sandbox Code Playgroud)
然后你可以像对待任何 PowerShell 对象一样对待它,并在你认为合适或输出到 CSV 或任何你需要做的事情时进行过滤。它现在是结构化的。
根据您的 PowerShell 版本,您还可以使用Convert-FromStringwhich 接受单行字符串并将它们转换为对象。还有什么要查的。
$p可能类似于TCP 0.0.0.0:445 0.0.0.0:0 LISTENING 4and$nar[-1]是字符串,4所以-replace运算符接受所有 4s:
TCP 0.0.0.0:445 0.0.0.0:0 LISTENING 4\n \xe2\x86\x91\xe2\x86\x91 \xe2\x86\x91\nRun Code Online (Sandbox Code Playgroud)\n\n强制仅替换最后一次出现的$nar[-1]使用行尾锚点(转义$):
$p -replace "$($nar[-1])`$","$ppath $pname"\nRun Code Online (Sandbox Code Playgroud)\n\n另请阅读 Matt 在 stackoverflow 上对替换字符串中最后出现的子字符串的回答。
\n\n顺便提一句:
\n\n$ppath未定义\xe2\x80\xa6netstat -ano应该足够了(请注意,该-b选项可能很耗时,并且除非您有足够的权限,否则将会失败)。| 归档时间: |
|
| 查看次数: |
16338 次 |
| 最近记录: |