A resposta do JosefZ explica perfeitamente o seu problema. Você está usando o regex e está fazendo exatamente o que você está pedindo para fazer, talvez substituindo mais do que o esperado.
Uma nota secundária é que você está pedindo netstat
a
displays the executable involved in creating each connection or listening port
com o comutador b. No entanto, você está descartando isso com select-string
, pois esse processo aparece em sua própria linha após os outros dados. Esse não é o fim do mundo, mas porque você pode usar coisas como -Context
de Select-String
para conseguir isso, mas isso terá que ser examinado mais de perto em outro momento.
Eu gostaria de oferecer outras sugestões sobre o que você pode fazer nessa situação.
Using other tools is unfortunately not possible so I'm limited to using built-in Windows tools.
Coisa engraçada sobre isso, você tem pelo menos o Windows 8? Se preferir, use o cmdlet Get-NetTCPConnection
que é essencialmente netstat
em forma de objeto.
Então você pode fazer isso, o que deve te dar a mesma informação sem o incômodo
get-nettcpconnection | select local*,remote*,state,@{Name="Process";Expression={(Get-Process -Id $_.OwningProcess).ProcessName}}
Não tem o Windows 8+? Bem, então poderíamos melhorar seu script de análise. Dar um passo além para criar um objeto evitará problemas com a correspondência de expressões regulares.
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
}
}
Se você estivesse limitado ao PowerShell v2, precisaria alterar o psobject e os casts ordenados
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"
A última instrução select
garante a ordem da propriedade, que seria embaralhada de outra forma, e é o equivalente funcional a [ordered]
Então isso te renderá assim ...
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
Que você pode tratar como qualquer outro objeto do PowerShell e filtrar como quiser ou enviar para o CSV ou o que for necessário. Está estruturado agora.
Dependendo da sua versão do PowerShell, você também pode usar Convert-FromString
, que utiliza strings de linha única e as converte em objetos também. Algo mais para procurar.