Відповідь Йозефза чудово пояснює вашу проблему. Ви використовуєте регулярний вираз, і він робить саме те, що ви просите його зробити, можливо, замінивши більше, ніж ви очікували.
Примітка про те, що ви просите netstat
до
відображає виконуваний файл, який бере участь у створенні кожного з'єднання або порту прослуховування
за допомогою перемикача b. Проте ви знижуєте це з select-string
оскільки цей процес з'являється на його власному рядку після інших даних. Це не кінець світу, а тому, що ви можете використовувати подібні речі -Context
з Select-String
щоб отримати це, але це буде потрібно розглядати більш тісно в інший час.
Я хотів би запропонувати інші пропозиції щодо того, що ви можете зробити в цій ситуації.
На жаль, використання інших інструментів неможливе, тому я обмежуюся вбудованими інструментами Windows.
Цікаво, що у вас є, принаймні, Windows 8? Якщо ви це зробите, ви можете просто використовувати Get-NetTCPConnection
cmdlet, який є по суті 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]
Так що буде чистий ви вихід, як це ...
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
який приймає рядки рядків і перетворює їх на об'єкти. Щось ще шукати.
netstat -bano|select-string 'LISTENING|UDP'