Övervakning av tillgänglighet för värdar på Powershell

Hej alla, jag vill dela med mig av en enkel guide "Hur man kan sluta pinga ett dussin värdar manuellt. Utan registrering och SMS!".

Övervakning av tillgänglighet för värdar på PowershellFrån Internets värld

Det är viktigt: jag är ingen programmerare eller systemadministratör, men jag arbetar ofta med ett stort antal servrar och tjänster och det här skriptet skrev jag för min egen bekvämlighet.

För alla som kan ha nytta av detta, är ni välkomna att läsa vidare.

Varför PowershellJag har erfarenhet av att skriva enkla program i Python, men det kräver antingen installerad tolk eller rätt att köra .exe, vilket inte alltid är möjligt i mitt arbete. Men skript i Powershell går oftare att köra.

Inte alla gillar konsolen/terminalen

Jag tror inte det finns någon motsättning här, annars skulle alla fortfarande använda konsolbaserade e-postklienter och GUI skulle inte ha dykt upp i *nix-system.

Eftersom jag ofta måste använda Powershell ganska grundläggande, försökte jag först förstå om man kan koppla GUIs till det. Det visade sig vara möjligt och dessutom ganska enkelt:

Övervakning av tillgänglighet för värdar på Powershell

Add-Type -assembly System.Windows.Forms # Anslut biblioteket
$main_form = New-Object System.Windows.Forms.Form # Skapa ett objekt för vårt "fönster"

# Ange dess parametrar
$main_form.Text ='Links up' # Namn i rubriken
$main_form.Width = 300 # Fönstrets bredd
$main_form.Height = 200 # Fönstrets höjd
$main_form.AutoSize = $true # Ge det möjlighet att ändra storlek automatiskt vid behov
$main_form.ShowDialog() # Kalla på "fönstret"

Vi lägger till en utdataelement och får ett elementärt Windows-fönster, tautologi?

Övervakning av tillgänglighet för värdar på Powershell

Add-Type -assembly System.Windows.Forms #Anslut biblioteket

$main_form = New-Object System.Windows.Forms.Form #Skapa en variabel för vårt "fönster"

#Sätt dess parametrar genom parametrarna
$main_form.Text ='Links up' #Namn i rubriken
$main_form.Width = 300 #Fönstrets bredd
$main_form.Height = 200 #Fönstrets höjd
$main_form.AutoSize = $true #Låt det justera storleken automatiskt vid behov

$Label = New-Object System.Windows.Forms.Label #Alla formulärelement kommer att lagras i variabler, men de är faktiskt objekt, precis som andra variabler i Powershell
$Label.Text = "Hej! Jag är ett enkelt Windows-fönster, vad har du åstadkommit?" #Visad text
$Label.Location  = New-Object System.Drawing.Point(10,65) #Objektets läge i fönstret horisontellt och vertikalt (x,y)
$Label.AutoSize = $true 

$main_form.Controls.Add($Label) #Lägg till det skapade objektet till fönstret så att det inte försvinner under körningen av skriptet

$main_form.ShowDialog() #Visa det elementära fönstret

Låt oss lägga till lite dynamik

Det verktyg jag "pingade Yandex" och monterade *.iso har fått ett separat GUI, men det är inte tillräckligt. På liknande sätt kan man visa information om tillgänglighet, men för övervakning måste skriptet startas om varje gång.

Först ska vi rita två ikoner och lägga till möjlighet att visa bilder.

Övervakning av tillgänglighet för värdar på Powershell

$PictureBox = New-Object system.Windows.Forms.PictureBox # Objektet för att visa bilder kallas helt logiskt
$PictureBox.width = 10
$PictureBox.height = 10
$PictureBox.location = New-Object System.Drawing.Point(178,12)

# Här går vi direkt till saken, vi kopplar den bild som ska visas till resultatet av kontrollen av nodens tillgänglighet med hjälp av cmdlet
#<b>test-connection</b>, där:
#-Count - anger antal förfrågningar
#-computer - IP eller domännamn för förfrågan
#-quiet - så att vi bara får tillbaka ett Booleskt värde
if ((test-connection -Count 1 -computer ya.ru -quiet) -eq $True) {
	$PictureBox.imageLocation = "C:Testyes.png" # Objektet refererar till den aktuella bilden 
}
Else {
	$PictureBox.imageLocation = "C:Testno.png" # Objektet refererar till den aktuella bilden 
}
$PictureBox.SizeMode = [System.Windows.Forms.PictureBoxSizeMode]::zoom

$main_form.Controls.Add($PictureBox)

Återigen strular våra DNS:er...

Övervakning av tillgänglighet för värdar på Powershell
Och vi lägger till en knapp för att kunna uppdatera värdena.

Övervakning av tillgänglighet för värdar på Powershell

$Button = New-Object System.Windows.Forms.Button
$Button.Location = New-Object System.Drawing.Size(100,150) 
$Button.Size = New-Object System.Drawing.Size(80,30)
$Button.Text = "Ladda om"

# Koppla ett händelse till knapptryckningen för varje PictureBox enligt den tidigare beskrivna logiken
$Button.Add_Click({ 
	if ((Test-Connection -Count 1 -computer ya.ru -quiet) -eq $True)
		{$PictureBox.imageLocation	= "C:Testyes.png"}
	Else {$PictureBox.imageLocation	= "C:Testno.png"}
	  
	if ((Test-Connection -Count 1 -computer 8.8.8.8 -quiet) -eq $True)
		{$PictureBox1.imageLocation	= "C:Testyes.png"}
	Else {$PictureBox1.imageLocation	= "C:Testno.png"}
 	})

$main_form.Controls.Add($Button)

Övervakning av tillgänglighet för värdar på Powershell

Underbart, dags för produktion!?

Genom att manuellt skriva in ungefär ett halvdussin värdar insåg jag plötsligt en sak — detta projekt kommer att ta slut, värdarna kommer att ändras och jag måste alltid justera skriptet. Å ena sidan är det ingen fara, det är ju en lösning för mig själv. Å andra sidan, titta på vad som händer:

En syn som inte är för de svaga av hjärtat

Add-Type -assembly System.Windows.Forms #Anslut biblioteket

$main_form = New-Object System.Windows.Forms.Form #Skapa en variabel med vårt "fönster"

#Ställ in parametrarna för det genom parametrarna
$main_form.Text ='Links up' #Namnet i rubriken
$main_form.Width = 300 #Fönstrets bredd
$main_form.Height = 200 #Fönstrets höjd
$main_form.AutoSize = $true #Tillåt att det justerar storlek automatiskt vid behov

$Label = New-Object System.Windows.Forms.Label #Alla formulärkomponenter kommer att sparas i variabler, men i verkligheten är dessa objekt, precis som andra variabler i Powershell
$Label.Text = "ya.ru		............................" #Text som visas
$Label.Location  = New-Object System.Drawing.Point(15,10) #Objektets position inom formuläret horisontellt och vertikalt (x,y)
$Label.AutoSize = $true 

$Label1 = New-Object System.Windows.Forms.Label #Alla formulärkomponenter kommer att sparas i variabler, men i verkligheten är dessa objekt, precis som andra variabler i Powershell
$Label1.Text = "8.8.8.8		............................" #Text som visas googles DNS-uppsättning
$Label1.Location  = New-Object System.Drawing.Point(15,30) #Objektets position inom formuläret horisontellt och vertikalt (x,y)
$Label1.AutoSize = $true 

$Label2 = New-Object System.Windows.Forms.Label
$Label2.Text = "192.168.x.x	............................"
$Label2.Location  = New-Object System.Drawing.Point(15,50)
$Label2.AutoSize = $true

$Label3 = New-Object System.Windows.Forms.Label
$Label3.Text = "192.168.x.x	............................"
$Label3.Location  = New-Object System.Drawing.Point(15,70)
$Label3.AutoSize = $true

$Label4 = New-Object System.Windows.Forms.Label
$Label4.Text = "10.0.x.x	 ............................"
$Label4.Location  = New-Object System.Drawing.Point(15,90)
$Label4.AutoSize = $true

$Label5 = New-Object System.Windows.Forms.Label
$Label5.Text = "162.102.x.x	 ............................"
$Label5.Location  = New-Object System.Drawing.Point(15,110)
$Label5.AutoSize = $true

$PictureBox = New-Object system.Windows.Forms.PictureBox #Objektet för att visa bilder har givetvis ett logiskt namn
$PictureBox.width = 10
$PictureBox.height = 10

#Här går vi till verket, kopplar bilden som ska visas till resultatet av kontrollen av tillgängligheten av noden med hjälp av kommandot<b>test-connection</b>, där:
#-Count - skickar antalet förfrågningar
#-computer - IP-adress eller domännamn för förfrågan
#-quiet - så att vi endast får tillbaka ett Boolean-värde
$PictureBox.location = New-Object System.Drawing.Point(235,12)
if ((test-connection -Count 1 -computer ya.ru -quiet) -eq $True) {
	$PictureBox.imageLocation = "C:Testyes.png" #Objektet refererar till motsvarande bild
}
Else {
	$PictureBox.imageLocation = "C:Testno.png" #Objektet refererar till motsvarande bild
}
$PictureBox.SizeMode = [System.Windows.Forms.PictureBoxSizeMode]::zoom

$PictureBox1 = New-Object system.Windows.Forms.PictureBox #Objektet för att visa bilder har en logisk namn
$PictureBox1.width = 10
$PictureBox1.height = 10
$PictureBox1.location = New-Object System.Drawing.Point(235,32)
if ((test-connection -Count 1 -computer 8.8.8.8 -quiet) -eq $True) {
	$PictureBox1.imageLocation = "C:Testyes.png" #Objektet refererar till motsvarande bild
}
Else {
	$PictureBox1.imageLocation = "C:Testno.png" #Objektet refererar till motsvarande bild
}
$PictureBox1.SizeMode = [System.Windows.Forms.PictureBoxSizeMode]::zoom

$PictureBox2 = New-Object system.Windows.Forms.PictureBox #Objektet för att visa bilder har en logisk namn
$PictureBox2.width = 10
$PictureBox2.height = 10
$PictureBox2.location = New-Object System.Drawing.Point(235,52)
if ((test-connection -Count 1 -computer 192.168.x.x -quiet) -eq $True) {
	$PictureBox2.imageLocation = "C:Testyes.png" #Objektet refererar till motsvarande bild
}
Else {
	$PictureBox2.imageLocation = "C:Testno.png" #Objektet refererar till motsvarande bild
}
$PictureBox2.SizeMode = [System.Windows.Forms.PictureBoxSizeMode]::zoom

$PictureBox3 = New-Object system.Windows.Forms.PictureBox #Objektet för att visa bilder har en logisk namn
$PictureBox3.width = 10
$PictureBox3.height = 10
$PictureBox3.location = New-Object System.Drawing.Point(235,72)
if ((test-connection -Count 1 -computer 192.168.x.x -quiet) -eq $True) {
	$PictureBox3.imageLocation = "C:Testyes.png" #Objektet refererar till motsvarande bild
}
Else {
	$PictureBox3.imageLocation = "C:Testno.png" #Objektet refererar till motsvarande bild
}
$PictureBox3.SizeMode = [System.Windows.Forms.PictureBoxSizeMode]::zoom

$PictureBox4 = New-Object system.Windows.Forms.PictureBox #Objektet för att visa bilder har en logisk namn
$PictureBox4.width = 10
$PictureBox4.height = 10
$PictureBox4.location = New-Object System.Drawing.Point(235,92)
if ((test-connection -Count 1 -computer 10.0.x.x -quiet) -eq $True) {
	$PictureBox4.imageLocation = "C:Testyes.png" #Objektet refererar till motsvarande bild
}
Else {
	$PictureBox4.imageLocation = "C:Testno.png" #Objektet refererar till motsvarande bild
}
$PictureBox1.SizeMode = [System.Windows.Forms.PictureBoxSizeMode]::zoom

$PictureBox5 = New-Object system.Windows.Forms.PictureBox #Objektet för att visa bilder har en logisk namn
$PictureBox5.width = 10
$PictureBox5.height = 10
$PictureBox5.location = New-Object System.Drawing.Point(235,112)
if ((test-connection -Count 1 -computer 162.102.x.x -quiet) -eq $True) {
	$PictureBox5.imageLocation = "C:Testyes.png" #Objektet refererar till motsvarande bild
	}
Else {
	$PictureBox5.imageLocation = "C:Testno.png" #Objektet refererar till motsvarande bild
	}
$PictureBox5.SizeMode = [System.Windows.Forms.PictureBoxSizeMode]::zoom

$Button = New-Object System.Windows.Forms.Button
$Button.Location = New-Object System.Drawing.Size(100,150) 
$Button.Size = New-Object System.Drawing.Size(80,30)
$Button.Text = "Ladda om"

# Kopplar ett klickhändelse till att uppdatera varje PictureBox enligt den tidigare beskrivna logiken
$Button.Add_Click({ 
	if ((Test-Connection -Count 1 -computer ya.ru -quiet) -eq $True)
		{$PictureBox.imageLocation	= "C:Testyes.png"}
	Else {$PictureBox.imageLocation	= "C:Testno.png"}
	  
	if ((Test-Connection -Count 1 -computer 8.8.8.8 -quiet) -eq $True)
		{$PictureBox1.imageLocation	= "C:Testyes.png"}
	Else {$PictureBox1.imageLocation	= "C:Testno.png"}

	if ((Test-Connection -Count 1 -computer 192.168.x.x -quiet) -eq $True)
		{$PictureBox2.imageLocation	= "C:Testyes.png"}
	Else {$PictureBox2.imageLocation	= "C:Testno.png"}

	if ((Test-Connection -Count 1 -computer 192.168.x.x -quiet) -eq $True)
		{$PictureBox3.imageLocation	= "C:Testyes.png"}
	Else {$PictureBox3.imageLocation	= "C:Testno.png"}

	if ((Test-Connection -Count 1 -computer 10.0.x.x -quiet) -eq $True)
		{$PictureBox4.imageLocation	= "C:Testyes.png"}
	Else {$PictureBox4.imageLocation	= "C:Testno.png"}

	if ((Test-Connection -Count 1 -computer 162.102.x.x -quiet) -eq $True)
		{$PictureBox5.imageLocation	= "C:Testyes.png"}
	Else {$PictureBox5.imageLocation	= "C:Testno.png"}
	})

$main_form.Controls.Add($Label) #lägg till det skapade objektet i formuläret så att det inte går förlorat vid skriptets körning
$main_form.Controls.Add($Label1)
$main_form.Controls.Add($Label2)
$main_form.Controls.Add($Label3)
$main_form.Controls.Add($Label4)
$main_form.Controls.Add($Label5)
$main_form.Controls.Add($PictureBox)
$main_form.Controls.Add($PictureBox1)
$main_form.Controls.Add($PictureBox2)
$main_form.Controls.Add($PictureBox3)
$main_form.Controls.Add($PictureBox4)
$main_form.Controls.Add($PictureBox5)
$main_form.Controls.Add($Button)

$main_form.ShowDialog() #Visar ett grundläggande fönster

Även om man håller ordning och följer strukturen kommer periodisk redigering att skapa en obehaglig känsla.

Först tar vi ut tillgänglighetstestet i en separat funktion, och sökvägen till katalogen i en separat variabel:

$script_path	= "C:TestPS ping"

#Flytta till funktionen den redan skapade PictureBox-objektet och IP-adressen som ska kontrolleras.
#Det kommer att ändra den laddade bilden vid utgången.
function get_status($PictureBox,$path_ip) {
	if ((Test-Connection -Count 1 -computer $path_ip -quiet) -eq $True)
		{$PictureBox.imageLocation	= $script_path + "yes.png"}
	Else {$PictureBox.imageLocation	= $script_path + "no.png"} 
	}

Vi flyttar informationen om värden tillbaka till en extern fil path.txt, som sparas i formatet „ip/host-funktionsnamn/”, och i dokumentet tar vi emot dem i matriser. Vi gör även beräkningen av Y-positionen mer automatiserad. Detta ger oss möjlighet att skapa Label och checkboxar genom att kalla på funktionen:

Övervakning av tillgänglighet för värdar på Powershell

#создаем описательную линию, на вход идут: объект Label, IP-адресс, описание и позиция по оси Y
Function Create_line($label,$path_ip,$caption, $top){ 
	$label.Location = New-Object System.Drawing.Point(1, $top)
	$label.text = $path_ip+$caption
	$label.font = $font
	$Label.AutoSize = $true
	}
#создаем индикатор для описательной линию, на вход идут: объект PictureBox, IP-адресс и позиция по оси Y
Function Create_link($PictureBox,$path_ip, $top){ 
	$PictureBox.width	= 10
	$PictureBox.height	= 10
	$PictureBox.location	= New-Object System.Drawing.Point(210,$top)
	get_status -PictureBox $PictureBox -path_ip $path_ip
	$PictureBox.SizeMode	= [System.Windows.Forms.PictureBoxSizeMode]::zoom
	}

$line = Get-content -LiteralPath $script_path"path.txt" #вытаскиваем данные о необходимых хостах
$len = $line.Length	#вычисляем длину, а точнее массив длин каждой строки

$i = 0

#далее объявляем массивы которые понадобятся дальше
$ip = @()	#массив ip
$capt = @()	#массив описания
$Labels =@()	#массив Label
$PictureBoxs =@()	#массив PictureBox

while($i -lt $len){
	$f = $line[$i].IndexOf("/") #вычисляем позицию начала описания
	$l = $line[$i].LastIndexOf("/")	#вычисляем позицию конца описания
	$ip += $line[$i].Substring(0,$f)	#вытаскиваем ip
	$capt += $line[$i].Substring($f+1,$l-$f-1)	#вытаскиваем описание

	#создаем поле Label
	Create_line -label ($label_obj = New-Object System.Windows.Forms.Label) -path_ip $ip[$i] -caption $capt[$i] -top $label_from_top
	#создаем поле PictureBox
	Create_link -PictureBox ($PictureBox_obj = New-Object system.Windows.Forms.PictureBox) -path_ip $ip[$i] -top $label_from_top

	$label_from_top += 15	#делаем "шаг" по оси Y

	$Labels	+= $label_obj	#вносим созданный Label в общий массив
	$PictureBoxs	+= $PictureBox_obj	#вносим созданный PictureBox в общий массив
	$main_form.Controls.Add($Labels[$i])
	$main_form.Controls.Add($PictureBoxs[$i])
	$i	+=1
	}

Vi lägger till en plats för att visa tidpunkten för den senaste kontrollen, eftersom det är praktiskt, och vi lägger till lite mer åtgärd när knappen trycks.

Övervakning av tillgänglighet för värdar på Powershell

$Label0	= New-Object System.Windows.Forms.Label
$Label0.Text	= Get-Date
$Label0.Location	= New-Object System.Drawing.Point(80,180)
$Label0.AutoSize	= $true
$main_form.Controls.Add($Label0)
$Button.Add_Click({ 
	while($i -lt $len){
		get_status -PictureBox $PictureBoxs[$i] -path_ip $ip[$i]
		$i +=1
		}
	$Label0.Text	= Get-Date 
	})

Och jag har också lagt till en liten funktionalitet som, när otillgänglig värd upptäcks, rapporterar det inte bara genom att ändra indikatorn, utan också skriker från högtalarna.

Add-Type -AssemblyName System.Speech
$voice	= New-Object System.Speech.Synthesis.SpeechSynthesizer
$voice.Rate	= 5
$voice.Speak("Varning! Varning! Basen är under attack!")

Så efter några dekoreringar och anpassningar till en läsbar och bekväm form ser det ut så här:

Fullständig kod för skriptet

Add-Type -AssemblyName System.Speech
Add-Type -assembly System.Windows.Forms

$script_path	= "C:PS ping"
$label_from_top	= 10
$voice	= New-Object System.Speech.Synthesis.SpeechSynthesizer
$voice.Rate	= 5

# Flyttar till funktionen den redan skapade PictureBox objekt och IP-adressen som ska kontrolleras.
# Utgången ändrar den laddade bilden.
function get_status($PictureBox,$path_ip) {
	if ((Test-Connection -Count 1 -computer $path_ip -quiet) -eq $True) {
		$PictureBox.imageLocation	= $script_path + "yes.png"
		}
	Else {
		$PictureBox.imageLocation	= $script_path + "no.png"
		$voice.Speak("Fel! Värd " + $path_ip + ", otillgänglig!")
		}
	}

# Skapar en beskrivande rad, argument: Label objekt, IP-adress, beskrivning och position på Y-axeln
Function Create_line($label,$path_ip,$caption, $top){ 
	$label.Location	= New-Object System.Drawing.Point(1, $top)
	$label.text	= $path_ip+$caption
	$label.font	= $font
	$Label.AutoSize	= $true
	}

# Skapar en indikator för den beskrivande raden, argument: PictureBox objekt, IP-adress och position på Y-axeln
Function Create_link($PictureBox,$path_ip, $top){ 
	$PictureBox.width	= 10
	$PictureBox.height	= 10
	$PictureBox.location	= New-Object System.Drawing.Point(210,$top)
	get_status -PictureBox $PictureBox -path_ip $path_ip
	$PictureBox.SizeMode	= [System.Windows.Forms.PictureBoxSizeMode]::zoom
	}

$main_form	= New-Object System.Windows.Forms.Form
$main_form.Text ='Länkar uppe' #Titel i fönstret
$main_form.Width = 300 #Fönstrets bredd
$main_form.Height = 200 #Fönstrets höjd
$main_form.AutoSize = $true #Ger möjlighet att ändra storlek automatiskt om det behövs
$main_form.TopMost	= $true #Detta är mycket viktigt, det gör att fönstret hålls över andra

$line = Get-content -LiteralPath $script_path"path.txt" #Hämtar data om nödvändiga värdar
$len = $line.Length	#Beräknar längden, snarare, en array av längder för varje rad

$i = 0

#Deklarerar arrayer som behövs senare
$ip	= @()	#array för ip
$capt	= @()	#array för beskrivning
$Labels	=@()	#array för Label
$PictureBoxs	=@()	#array för PictureBox

while($i -lt $len){
	$f	= $line[$i].IndexOf("/") #Beräknar positionen för början av beskrivningen
	$l	= $line[$i].LastIndexOf("/")	#Beräknar positionen för slutet av beskrivningen
	$ip	+= $line[$i].Substring(0,$f)	#Hämtar ip
	$capt	+= $line[$i].Substring($f+1,$l-$f-1)	#Hämtar beskrivning

	#Skapar Label fält
	Create_line -label ($label_obj = New-Object System.Windows.Forms.Label) -path_ip $ip[$i] -caption $capt[$i] -top $label_from_top
	#Skapar PictureBox fält
	Create_link -PictureBox ($PictureBox_obj = New-Object system.Windows.Forms.PictureBox) -path_ip $ip[$i] -top $label_from_top

	$label_from_top	+= 15	#Ökar "steg" på Y-axeln

	$Labels	+= $label_obj	#Lägg till den skapade Label i den totala arrayen
	$PictureBoxs	+= $PictureBox_obj	#Lägg till den skapade PictureBox i den totala arrayen
	$main_form.Controls.Add($Labels[$i])
	$main_form.Controls.Add($PictureBoxs[$i])
	$i	+=1
}

#Detta fält visar den senaste tidpunkten för kontroll
$Label0	= New-Object System.Windows.Forms.Label
$Label0.Text	= Get-Date
$Label0.Location	= New-Object System.Drawing.Point(80,180)
$Label0.AutoSize	= $true


# Kopplar en händelse för att klicka på varje PictureBox enligt den tidigare beskrivna logiken
$Button	= New-Object System.Windows.Forms.Button
$Button.Location	= New-Object System.Drawing.Size(100,200)
$Button.Size	= New-Object System.Drawing.Size(80,30)
$Button.Text	= "Ladda om"

$Button.Add_Click({ 
	while($i -lt $len){
		get_status -PictureBox $PictureBoxs[$i] -path_ip $ip[$i]
		$i	+=1
		}
	$i	= 0
	$Label0.Text	= Get-Date 
})

$main_form.Controls.Add($Button)
$main_form.Controls.Add($Label0)

$main_form.ShowDialog()

Epilog

Jag hoppas att denna handledning är till nytta för någon. Om du har gjort detta nästan från början, gratulerar jag dig, jag har inte. Men jag är öppen för dina kommentarer och förslag.

Det var trevligt för mig att utforska och samla ihop ett sådant litet, men nyttigt verktyg. Jag planerar också att implementera tillägg och borttagning av noder från GUI, samt att göra det som skulle ha genomförts från början, automatisk uppdatering av status utan att behöva 'klicka' på knappen, och för att det inte ska hänga 'powershell.exe'.

Den senaste versionen av skriptet på GitHub

Källa: habr.com

Köp pålitlig webbhotell med DDoS-skydd, VPS VDS-servrar 🔥 Köp pålitlig webbhotell med DDoS-skydd, VPS VDS-servrar | ProHoster