Buon pomeriggio a tutti, voglio condividere una semplice guida su "Come smettere di pingare manualmente un numero di host. Senza registrazione e SMS!".
Dai misteri di Internet
Importante: non sono un programmatore né un amministratore di sistema, ma devo lavorare contemporaneamente con un ampio insieme server di servizi e ho scritto questo script per la mia comodità.
A chiunque possa esserne interessato, vi invito a proseguire.
Perché PowershellHo esperienza nella scrittura di semplici programmi in Python, ma richiede un interprete installato o i diritti per eseguire .exe, il che, nel contesto del mio lavoro, non è sempre possibile. Tuttavia, uno script in Powershell trova più facilmente la possibilità di essere eseguito.
Non tutti amano la console/il terminale
Credo che non ci sia contraddizione, altrimenti tutti userebbero client di posta via console e non ci sarebbe stata l’introduzione di GUI nei sistemi *nix.
Poiché nella vita di tutti i giorni utilizzo Powershell in un modo piuttosto primitivo, all’inizio ho cercato di capire se fosse possibile aggiungere un'interfaccia GUI. A quanto pare, è possibile, e anche piuttosto semplice:

Add-Type -assembly System.Windows.Forms #Colleghiamo la libreria
$main_form = New-Object System.Windows.Forms.Form #Creiamo un oggetto con la nostra "finestra"
#Impostiamo i parametri
$main_form.Text ='Links up' #Nome nel titolo
$main_form.Width = 300 #Larghezza della finestra
$main_form.Height = 200 #Altezza della finestra
$main_form.AutoSize = $true #Consentiamo di ridimensionarsi autonomamente, se necessario
$main_form.ShowDialog() #Mostriamo la "finestra"
Aggiungiamo a questo elemento un output e otteniamo una finestra Windows elementare, tautologia?.

Add-Type -assembly System.Windows.Forms #Colleghiamo la libreria
$main_form = New-Object System.Windows.Forms.Form #Creiamo una variabile con la nostra "finestra"
#Impostiamo i parametri della finestra
$main_form.Text ='Links up' #Nome nella barra del titolo
$main_form.Width = 300 #Larghezza della finestra
$main_form.Height = 200 #Altezza della finestra
$main_form.AutoSize = $true #Consentiamo la ridimensionamento automatico quando necessario
$Label = New-Object System.Windows.Forms.Label #Tutti gli elementi della finestra saranno assegnati a variabili, ma in realtà sono oggetti, come qualsiasi altra variabile in Powershell
$Label.Text = "Ciao! Sono una finestra Windows elementare, e tu che cosa hai raggiunto?" #Testo visualizzato
$Label.Location = New-Object System.Drawing.Point(10,65) #Posizione dell'oggetto all'interno della finestra in orizzontale e verticale (x,y)
$Label.AutoSize = $true
$main_form.Controls.Add($Label) #Aggiungiamo l'oggetto creato alla finestra, affinché non si perda durante l'esecuzione dello script
$main_form.ShowDialog() #Chiamiamo l'elemento della finestra elementareAggiungiamo dinamicità
Quindi, lo strumento con cui ho "pingato Yandex" e montato *.iso ha acquisito un'interfaccia grafica dedicata, ma non basta. In questo modo è possibile visualizzare le informazioni sulla disponibilità, ma per il monitoraggio dovrò riavviare lo script ogni volta.
Per cominciare, disegniamo due icone e aggiungiamo la possibilità di visualizzare immagini.

$PictureBox = New-Object system.Windows.Forms.PictureBox #L'oggetto per la visualizzazione delle immagini ha un nome piuttosto logico
$PictureBox.width = 10
$PictureBox.height = 10
$PictureBox.location = New-Object System.Drawing.Point(178,12)
#Qui entriamo nel vivo collegando l'immagine da visualizzare al risultato del test di accessibilità del nodo utilizzando il cmdlet
#<b>test-connection</b>, dove:
#-Count - specifica il numero di richieste
#-computer - IP o nome di dominio per la richiesta
#-quiet - per ricevere solo un valore booleano
if ((test-connection -Count 1 -computer ya.ru -quiet) -eq $True) {
$PictureBox.imageLocation = "C:Testyes.png" #L'oggetto si riferisce all'immagine corrispondente
}
Else {
$PictureBox.imageLocation = "C:Testno.png" #L'oggetto si riferisce all'immagine corrispondente
}
$PictureBox.SizeMode = [System.Windows.Forms.PictureBoxSizeMode]::zoom
$main_form.Controls.Add($PictureBox)
I nostri DNS stanno di nuovo dando problemi…

Aggiungiamo anche un pulsante per avere la possibilità di aggiornare le letture.

$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 = "Ricarica"
# Colleghiamo l'evento di clic del pulsante all'ogni PictureBox secondo la logica precedentemente descritta
$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)

Meraviglioso, ora in produzione!?
Scrivendo manualmente circa una dozzina di host, ho improvvisamente capito una cosa: questo progetto finirà, gli host cambieranno e dovrò ogni volta modificare lo script. Da un lato niente di grave, è pur sempre una soluzione per me. Dall'altro lato, date un'occhiata a cosa sta uscendo:
Uno spettacolo non per i deboli di cuore.
Add-Type -assembly System.Windows.Forms #Colleghiamo la libreria
$main_form = New-Object System.Windows.Forms.Form #Creiamo una variabile per la nostra "finestra"
#Impostiamo i parametri per essa
$main_form.Text ='Links up' #Nome nel titolo
$main_form.Width = 300 #Larghezza della finestra
$main_form.Height = 200 #Altezza della finestra
$main_form.AutoSize = $true #Consenti di ridimensionarsi automaticamente, se necessario
$Label = New-Object System.Windows.Forms.Label #Tutti gli elementi del modulo saranno memorizzati in variabili, ma in realtà sono oggetti, come tutte le altre variabili in Powershell
$Label.Text = "ya.ru ............................" #Testo visualizzato
$Label.Location = New-Object System.Drawing.Point(15,10) #Posizione dell'oggetto all'interno del modulo orizzontalmente e verticalmente (x,y)
$Label.AutoSize = $true
$Label1 = New-Object System.Windows.Forms.Label #Tutti gli elementi del modulo saranno memorizzati in variabili, ma in realtà sono oggetti, come tutte le altre variabili in Powershell
$Label1.Text = "8.8.8.8 ............................" #Testo visualizzato DNS di Google
$Label1.Location = New-Object System.Drawing.Point(15,30) #Posizione dell'oggetto all'interno del modulo orizzontalmente e verticalmente (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 #Oggetto per la visualizzazione delle immagini, logicamente chiamato
$PictureBox.width = 10
$PictureBox.height = 10
#Qui passiamo alla parte pratica collegando l'immagine visualizzata al risultato della verifica di accessibilità del nodo utilizzando il cmdlet
#<b>test-connection</b>, dove:
#-Count - passa il numero di richieste
#-computer - IP o nome di dominio per la richiesta
#-quiet - per ricevere solo un valore booleano
$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" #L'oggetto accede all'immagine corrispondente
}
Else {
$PictureBox.imageLocation = "C:Testno.png" #L'oggetto accede all'immagine corrispondente
}
$PictureBox.SizeMode = [System.Windows.Forms.PictureBoxSizeMode]::zoom
$PictureBox1 = New-Object system.Windows.Forms.PictureBox #L'oggetto per visualizzare le immagini si chiama in modo logico
$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" #L'oggetto accede all'immagine corrispondente
}
Else {
$PictureBox1.imageLocation = "C:Testno.png" #L'oggetto accede all'immagine corrispondente
}
$PictureBox1.SizeMode = [System.Windows.Forms.PictureBoxSizeMode]::zoom
$PictureBox2 = New-Object system.Windows.Forms.PictureBox #L'oggetto per visualizzare le immagini si chiama in modo logico
$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" #L'oggetto accede all'immagine corrispondente
}
Else {
$PictureBox2.imageLocation = "C:Testno.png" #L'oggetto accede all'immagine corrispondente
}
$PictureBox2.SizeMode = [System.Windows.Forms.PictureBoxSizeMode]::zoom
$PictureBox3 = New-Object system.Windows.Forms.PictureBox #L'oggetto per visualizzare le immagini si chiama in modo logico
$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" #L'oggetto accede all'immagine corrispondente
}
Else {
$PictureBox3.imageLocation = "C:Testno.png" #L'oggetto accede all'immagine corrispondente
}
$PictureBox3.SizeMode = [System.Windows.Forms.PictureBoxSizeMode]::zoom
$PictureBox4 = New-Object system.Windows.Forms.PictureBox #L'oggetto per visualizzare le immagini si chiama in modo logico
$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" #L'oggetto accede all'immagine corrispondente
}
Else {
$PictureBox4.imageLocation = "C:Testno.png" #L'oggetto accede all'immagine corrispondente
}
$PictureBox1.SizeMode = [System.Windows.Forms.PictureBoxSizeMode]::zoom
$PictureBox5 = New-Object system.Windows.Forms.PictureBox #L'oggetto per visualizzare le immagini si chiama in modo logico
$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" #L'oggetto accede all'immagine corrispondente
}
Else {
$PictureBox5.imageLocation = "C:Testno.png" #L'oggetto accede all'immagine corrispondente
}
$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 = "Ricarica"
# Colleghiamo all'evento di pressione del pulsante l'accesso a ciascun PictureBox secondo la logica descritta in precedenza
$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) #aggiungiamo l'oggetto creato al modulo, affinché non venga perso durante l'esecuzione dello script
$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() #Chiamiamo la finestra di dialogo elementare
Anche mantenendo la pulizia e rispettando la struttura, la revisione periodica provocherà sensazioni spiacevoli.
Per iniziare, separiamo il controllo della disponibilità in una funzione e il percorso della directory in una variabile:
$script_path = "C:TestPS ping"
#Trasferiamo nella funzione l'oggetto PictureBox già creato e l'indirizzo IP che deve essere verificato.
#In uscita cambierà l'immagine caricata.
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"}
}
Estraiamo i dati sull'host in un file esterno path.txt, registrandoli nel formato «ip/host-nome-funzionale/», e nel documento li accetteremo in array. Inoltre, rendiamo il calcolo della posizione Y più automatizzato. Tutto ciò ci permette di creare Label e checkbox chiamando la funzione:

#создаем описательную линию, на вход идут: объект 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
}
Aggiungiamo uno spazio per visualizzare l'ora dell'ultima verifica, perché è comodo, e completiamo leggermente l'azione al clic del pulsante.

$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
})
Ho anche aggiunto una piccola funzionalità che, quando rileva un host non disponibile, non solo cambia l'indicatore, ma grida anche dagli altoparlanti.
Add-Type -AssemblyName System.Speech
$voice = New-Object System.Speech.Synthesis.SpeechSynthesizer
$voice.Rate = 5
$voice.Speak("Attenzione! Attenzione! Il sistema è sotto attacco!")
Dopo alcuni abbellimenti e sistemazioni per renderlo leggibile e comodo, è venuto così:
Codice completo dello script
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
#Spostiamo nella funzione già creata l'oggetto PictureBox e l'indirizzo IP da controllare.
#In uscita cambia l'immagine caricata.
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("Errore! Host " + $path_ip + ", non disponibile!")
}
}
#creiamo una linea descrittiva, in ingresso: oggetto Label, indirizzo IP, descrizione e posizione sull'asse 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
}
#creiamo un indicatore per la linea descrittiva, in ingresso: oggetto PictureBox, indirizzo IP e posizione sull'asse 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
}
$main_form = New-Object System.Windows.Forms.Form
$main_form.Text ='Collegamenti attivi' #Nome nella intestazione
$main_form.Width = 300 #Larghezza della finestra
$main_form.Height = 200 #Altezza della finestra
$main_form.AutoSize = $true #Rendiamo la dimensione del modulo adattabile
$main_form.TopMost = $true #Questa è un'opzione molto importante, consente di tenere la finestra sopra le altre
$line = Get-content -LiteralPath $script_path"path.txt" #estraiamo i dati sugli host necessari
$len = $line.Length #calcoliamo la lunghezza, precisamente l'array delle lunghezze di ogni riga
$i = 0
#dichiarare arrays necessari per il seguito
$ip = @() #array ip
$capt = @() #array descrizione
$Labels =@() #array Label
$PictureBoxs =@() #array PictureBox
while($i -lt $len){
$f = $line[$i].IndexOf("/") #calcoliamo la posizione di inizio della descrizione
$l = $line[$i].LastIndexOf("/") #calcoliamo la posizione di fine della descrizione
$ip += $line[$i].Substring(0,$f) #estraiamo l'ip
$capt += $line[$i].Substring($f+1,$l-$f-1) #estraiamo la descrizione
#creiamo un campo Label
Create_line -label ($label_obj = New-Object System.Windows.Forms.Label) -path_ip $ip[$i] -caption $capt[$i] -top $label_from_top
#creiamo un campo PictureBox
Create_link -PictureBox ($PictureBox_obj = New-Object system.Windows.Forms.PictureBox) -path_ip $ip[$i] -top $label_from_top
$label_from_top += 15 #incrementiamo l'asse Y
$Labels += $label_obj #inseriamo il Label creato nell'array totale
$PictureBoxs += $PictureBox_obj #inseriamo il PictureBox creato nell'array totale
$main_form.Controls.Add($Labels[$i])
$main_form.Controls.Add($PictureBoxs[$i])
$i +=1
}
#questo campo mostra l'ultimo tempo di controllo
$Label0 = New-Object System.Windows.Forms.Label
$Label0.Text = Get-Date
$Label0.Location = New-Object System.Drawing.Point(80,180)
$Label0.AutoSize = $true
# Colleghiamo un evento di pressione del pulsante per ciascun PictureBox secondo la logica precedentemente descritta
$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 = "Ricarica"
$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()
Epifania
Spero che questo tutorial sia utile a qualcuno. Se siete già esperti in materia, vi faccio i complimenti, io non lo sono. Ma sono pronto ad ascoltare i vostri commenti e suggerimenti.
È stato piacevole per me esplorare e assemblare questa piccola, ma utile utility. Ho in programma di implementare anche l'aggiunta e la rimozione di nodi tramite GUI, oltre a realizzare ciò che doveva essere fatto per primo: l'aggiornamento automatico degli stati senza la necessità di premere un pulsante, affinché non blocchi 'powershell.exe'.
