Ответ JosefZ прекрасно объясняет вашу проблему. Вы используете регулярное выражение, и оно делает именно то, о чем вы его просили, возможно, заменяя больше, чем вы ожидали.
Примечание: вы просите netstat
отображает исполняемый файл, участвующий в создании каждого соединения или порта прослушивания
с переключателем b. Однако вы отбрасываете это с помощью select-string
поскольку этот процесс появляется в отдельной строке после других данных. Это не конец света, но потому что вы можете использовать такие вещи, как -Context
of Select-String
чтобы получить это, но это нужно будет рассмотреть более внимательно в другой раз.
Я хотел бы предложить другие предложения относительно того, что вы можете сделать в этой ситуации.
Использование других инструментов, к сожалению, невозможно, поэтому я ограничен использованием встроенных инструментов Windows.
Забавно, у вас есть хотя бы Windows 8? Если вы это сделаете, вы можете просто использовать командлет Get-NetTCPConnection
, который по сути является netstat
в форме объекта.
Таким образом, вы можете сделать это, что должно получить ту же информацию без хлопот
get-nettcpconnection | select local*,remote*,state,@{Name="Process";Expression={(Get-Process -Id $_.OwningProcess).ProcessName}}
У вас нет 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
}
}
Если бы вы были ограничены 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"
Последний оператор select
гарантирует порядок свойств, который в противном случае был бы перемешан, и является функциональным эквивалентом [ordered]
order ]
Так что это даст вам вывод, как это ...
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
Затем вы можете обращаться с ними так же, как с любым объектом и фильтром PowerShell, по своему усмотрению или выводом в CSV или с тем, что вам нужно сделать. Это структурировано сейчас.
В зависимости от вашей версии PowerShell вы также можете использовать Convert-FromString
который принимает однострочные строки и также преобразует их в объекты. Что-то еще, чтобы искать.