Powershell один-лайнер, щоб показати процес на тій же лінії, що і порт, використовуючи питання netstat


3

Спочатку я просто хочу переконатися, що користувач 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)";     }

Приклад виводу:

TCP 0.0.0.0:135 0.0.0.0:0 LISTENING svchost
TCP 0.0.0.0: Системна система5 0.0.0.0 6.3
TCP 0.0.0.0:623 0.0.0.0 named LISTENING LMS

Порт, який він змінює, є 445, але я поняття не маю, чому він змінюється тільки в тому випадку, коли інші порти працюють за призначенням. Чому скрипт змінює 445 на "System System5"?

На жаль, використання інших інструментів неможливе, тому я обмежуюся вбудованими інструментами Windows.


Будь ласка редагувати питання і забезпечити вихід сировини з netstat -bano|select-string 'LISTENING|UDP'
DavidPostill

Відповіді:


3

$p могло бути щось подібне TCP 0.0.0.0:445 0.0.0.0:0 LISTENING 4 і $nar[-1] - рядок 4 тому -replace оператора все 4 s:

TCP 0.0.0.0:445 0.0.0.0:0 LISTENING 4
            ↑↑                      ↑

Сила замінила тільки останнє входження $nar[-1] використання кінець рядка якір (втік $ ):

$p -replace "$($nar[-1])`$","$ppath $pname"

Читайте також відповідь Matt на Заміна останнього входження підрядка в рядку на stackoverflow.

До речі:

  • $ppath не визначено ...
  • … І netstat -ano має бути достатньо (зверніть увагу на це -b опція може зайняти багато часу і не пройде, якщо ви не матимете достатніх дозволів).

Ви знайшли проблему напевно. Я також запропонував пропозиції щодо цього питання, якщо вам цікаво.
Matt

3

Відповідь Йозефза чудово пояснює вашу проблему. Ви використовуєте регулярний вираз, і він робить саме те, що ви просите його зробити, можливо, замінивши більше, ніж ви очікували.

Примітка про те, що ви просите 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 який приймає рядки рядків і перетворює їх на об'єкти. Щось ще шукати.


Це було дуже корисно. Дякую тобі за допомогу.
Ric

Ваше рішення було б ідеальним, але здається, що це вимагає принаймні Powershell 3 або 4. При запуску на машині Windows 7 вона відразу помилки. Чи можна вносити будь-які зміни, щоб уникнути цього? Помилка "Неможливо знайти тип [замовив]: переконайтеся, що завантажена збірка, що містить цей тип."
Ric

1
Ці виклики викличуть питання так. Простий у зверненні, хоча. Я додаду вам швидке оновлення.
Matt

Відомо, що інформація про процес не доступна у Windows 2012 (без R2). Швидше за все, він також не доступний у Windows 8.0.
Thorarin

0

Більш простий ...

filter timestamp {"$(Get-Date -Format G): $_"};netstat -abno 1 | Select-String -Context 0,1 -Pattern LISTENING|timestamp
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.