Väikesed asjad võrgus

Vahel on just väikesed asjad need, mis teevad elu mugavaks. Serverite peal on mul sageli läinud vaja kahte asja:

  • vahel on vaja võrgust otsida seadmeid ilma et teaks, millisel IP aadressil nad vastavad
  • serveris on sageli vaja vaadata, mitmel kasutajal on lahti sessioon serveri teenusega.

Esimese asja puhul tuleb seadmeid otsida pimesi.  Ehk siis lihtsaim viis on IP-vahemik läbi pingida ja vaadata, mis IP-d vastavad.  Nendest tuleb siis välja filtreerida kõik, mille kohta on teada, et mis asi seda IP-d kasutab.  Seda filtreerimist tuleb ise ja käsitsi teha, aga vahemiku läbipingimist on võimalik automatiseerida ja lihtsutada. Nimelt saame siin kasutada Powershelli oskust võtta mingist hulgast ükshaaval elemendid ning seejärel igaühega neist midagi teha.  Näiteks:

1..10 | foreach-object { ping 192.168.3.$_}

Nüüd võiks veel teha seda, et pingitakse üks, mitte neli korda ja siis võiks välja tuua ainult need read, kus on näha vaid need IP-d, mis pingimisele vastavad:

90..100 | % { ping /n 1 192.168.3.$_ | Select-String "TTL"}

#requires -Version 2.0
Test-Connection -ComputerName (1..10 | % {"192.168.3.$_"}) -Count 1 -ea SilentlyContinue

#Requires -Modules NetTCPIP
192..203 | ForEach-Object { Test-NetConnection 192.168.3.$_ } |
  Where-Object {$_.PingSucceeded} |
  Select-Object -ExpandProperty ComputerName

Meeldival kombel jäävad ekraanile vaid need read, kus seade on vastanud.  Lisaks on kogu skript võimalik soovi korral kirjutada ühele reale ja on piisavalt lühike.  Samuti saab tulemust kohe edasi anda mingile järgmisele korraldusele …

Kui sihtmärke on palju, siis saab neid taustal paralleelselt pingida:

$myJob = Test-Connection (1..254 | foreach {"192.168.1.$_"}) -Count 1 -AsJob

Wait-Job $myJob |
  Receive-Job | 
  Where-Object {$_.StatusCode -eq 0} |
  Select-Object -ExpandProperty Address

Vajadus teise tegevuse järele tuleb serverites enamasti siis, kui oleks vaja teenus ajutiselt seisma panna või uuesti käivitada, aga kasutajad on veel serveris sees.  Võtame näiteks meiliserveri ja vaatame, kas seal on palju IMAP-SSL ühendusi:

netstat –n | select-string ":993 "

Kui pole vaja teada, et kust täpselt ühendused tulevad, on vaja teada vaid ühenduste arvu, siis loeme tagastatud read üle:

netstat –n | select-string ":993 " | measure-object

Või näiteks oleks vaja teada, et kas server ikka kuulab ettenähtud pordi peal:

netstat –an | select-string "listening" | select-string ":993 "

Windows Server 2012 (tegelikult ka Windows 8) peal on asi natuke lihtsam ja teksti seest asju otsima ei pea:

#Requires -Version 3
#Requires -Modules NetTCPIP

Get-NetTCPConnection -LocalPort 993
Get-NetTCPConnection -LocalPort 993 | Measure-Object
Get-NetTCPConnection -LocalPort 993 -State Listen

Kui on võimalik kasutada Powershell 5.0 võimalusi, siis saab samuti lihtsamalt. Nimelt võib teksti konvertida massiiviks, kasutades käsku ConvertFrom-String:

#Requires -Version 5
netstat -n |
  Select-Object -Skip 4 |
  ConvertFrom-String -PropertyNames Empty, Protocol, LocalAddress, RemoteAddress, State |
  Where-Object RemoteAddress -like "*:443"

Ent kujutame ette, et meil on serveris mitu erinevat veebiserveri rakendust ja me tahame teada, et kes täpselt kuulab parajasti konkreetsel pordil. Siin Server 2012 käsud ja Powershell 5 ei aita, kuna see ei näita porti kasutavat protsessi:

netstat –abon | Select-String -Pattern ":8080 " –Context 0,1

Ülaltoodud näide võtab programmi Netstat poolt väljastatud ridadest kaasa kõik, millel on tekst “:8080 ” ja lisab sellele leitud reale järgneva rea.  Sellelt leiame vastava protsessi nime, mis porti kasutab (selle eest hoolitses programmi Netstat käsurea võti “-b”, mis muuhulgas vajab süsteemiülema õigusi).  Eelduseks on see, et samal ajal ei ole kliendid nimetatud porti veel ühendust teinud.  Kui on, siis saame ülearustest ridadest lahti järgmiselt:

netstat –abon |
  select-string ":8080 " –context 0,1 |
  where-object {$_.line -like "*listening*"}

Jällegi on positiivne, et kõik mahub vajadusel ühele käsureale või sagedasemal kasutamisel võib ülaltoodu vormistada funktsiooniks (või paariks). Ülaltoodud näites vajaminevatest süsteemiülema õigustest saaks lahti (nagu ka käsu Select-String atribuudist -Context), kui jätta programmil Netstat ära käsureavõti “-b”.  Ainult et siis saame pordil kuulava protsessi tuvastada vaid “Process ID” järgi, mis tuleks omakorda sööta ette käsule Get-Process:

Get-Process -Id 3927

Ja selleks et nimetatud number leitud realt kätte saada, tuleb natuke tegeleda tekstitöötlusega, mida otse käsurealt on natuke ebamugav teha:

$protsess = netstat –aon |
  select-string ":8080 " |
  select-string "listening" |
  select-object -first 1
get-process -Id ($protsess.tostring().split(" ")[-1])

Ülaltoodud näites me muudame käsu select-string poolt leitud info objekti tekstiks, lõikame selle tühikute kohalt eraldi tükkideks ning tekkivast hulgast valime viimase teksti, mis juhtumisi ongi protsessi number. Juhuks kui sama protsess kuulab mitme IP peal, jätab neljas rida (üleval näites) neist järgi vaid ühe (esimese, mille Netstat raporteerib).

Advertisements