Buon pomeriggio a tutti, voglio condividere una semplice istruzione "Come smettere di pingare manualmente un decina di host. Senza registrazione e SMS!".
Dalle vastità di Internet
Importante: non sono un programmatore né un amministratore di sistema, ma mi trovo a lavorare contemporaneamente con un ampio insieme server di servizi e questo script l'ho scritto per il mio personale comfort.
Tutti coloro a cui potrebbe essere utile sono invitati a continuare a leggere.
Perché PowershellHo esperienza nella scrittura di semplici programmi in Python, ma questo richiede un interprete installato o i diritti per eseguire file .exe, cosa che, nell'ambito 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
Penso che non ci sia contraddizione in questo, altrimenti tutti continuerebbero a usare client di posta della console e non sarebbe apparso il GUI nei sistemi *nix.
Poiché nella mia vita quotidiana utilizzo Powershell in modo piuttosto primitivo, all'inizio ho cercato di capire se è possibile integrarlo con un GUI. Si scopre che è 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 nella intestazione
$main_form.Width = 300 #Larghezza della finestra
$main_form.Height = 200 #Altezza della finestra
$main_form.AutoSize = $true #Consentiamo di ridimensionarsi automaticamente, se necessario
$main_form.ShowDialog() #Chiamiamo la "finestra"
Aggiungiamo a questo un elemento di output e otteniamo una semplice finestra di Windows, una tautologia?

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 attraverso le proprietà
$main_form.Text ='Links up' #Nome nella intestazione
$main_form.Width = 300 #Larghezza della finestra
$main_form.Height = 200 #Altezza della finestra
$main_form.AutoSize = $true #Diamo la possibilità di cambiare dimensione 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 qualsiasi altra variabile in Powershell
$Label.Text = "Ciao! Sono una finestra di Windows elementare, e tu cosa hai raggiunto?" #Testo visualizzato
$Label.Location = New-Object System.Drawing.Point(10,65) #Posizione dell'oggetto all'interno del modulo in orizzontale e verticale (x,y)
$Label.AutoSize = $true
$main_form.Controls.Add($Label) #Aggiungiamo l'oggetto creato al modulo, in modo che non si perda durante l'esecuzione dello script
$main_form.ShowDialog() #Mostriamo la finestra elementare in modo offensivoAggiungiamo dinamicità
Così lo strumento con cui ho "pingato Yandex" e montato *.iso ha ottenuto un'interfaccia GUI separata, ma non è sufficiente. In modo simile, è possibile visualizzare informazioni sulla disponibilità, ma per il monitoraggio dovrò riavviare lo script ogni volta.
Per prima cosa 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 del tutto logico
$PictureBox.width = 10
$PictureBox.height = 10
$PictureBox.location = New-Object System.Drawing.Point(178,12)
#Qui passiamo al sodo, associamo l'immagine da visualizzare al risultato del controllo di accessibilità del nodo usando il cmdlet
#<b>test-connection</b>, dove:
#-Count - trasmette il numero di richieste
#-computer - IP o nome di dominio per la richiesta
#-quiet - per farci restituzire solo un valore Booleano
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
$main_form.Controls.Add($PictureBox)
Di nuovo i nostri DNS fanno i capricci…

E aggiungiamo un pulsante, così avremo la possibilità di aggiornare i dati.

$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 click del pulsante per indirizzare ciascun 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)

Ottimo, ora in produzione!?
Scrivendo manualmente circa una mezza dozzina di host, ho improvvisamente capito una cosa: questo progetto terminerà, gli host cambieranno e dovrò modificare lo script ogni volta. Da un lato non è un grosso problema, è una soluzione per il mio amato io. Dall'altro lato, guardate cosa ne viene fuori:
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 suoi parametri tramite parametri
$main_form.Text ='Links up' #Nome nella intestazione
$main_form.Width = 300 #Larghezza della finestra
$main_form.Height = 200 #Altezza della finestra
$main_form.AutoSize = $true #Consentiamo di adattare automaticamente le dimensioni se necessario
$Label = New-Object System.Windows.Forms.Label #Tutti gli elementi della finestra saranno memorizzati in variabili, ma in realtà sono oggetti, come qualsiasi altra variabile in Powershell
$Label.Text = "ya.ru ............................" #Testo visualizzato
$Label.Location = New-Object System.Drawing.Point(15,10) #Posizione dell'oggetto all'interno della finestra in orizzontale e verticale (x,y)
$Label.AutoSize = $true
$Label1 = New-Object System.Windows.Forms.Label #Tutti gli elementi della finestra saranno memorizzati in variabili, ma in realtà sono oggetti, come qualsiasi altra variabile 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 della finestra in orizzontale e verticale (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 #L'oggetto per visualizzare immagini ha un nome piuttosto logico
$PictureBox.width = 10
$PictureBox.height = 10
#Qui passiamo al sodo collegando l'immagine visualizzata al risultato del controllo della disponibilità del nodo utilizzando il cmdlet
#<b>test-connection</b>, dove:
#-Count - trasmette il numero di richieste
#-computer - IP o nome di dominio per la richiesta
#-quiet - affinché ci restituisca 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 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
$PictureBox1 = New-Object system.Windows.Forms.PictureBox #L'oggetto per la visualizzazione delle immagini si chiama logicamente
$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 si riferisce all'immagine corrispondente
}
Else {
$PictureBox1.imageLocation = "C:Testno.png" #L'oggetto si riferisce all'immagine corrispondente
}
$PictureBox1.SizeMode = [System.Windows.Forms.PictureBoxSizeMode]::zoom
$PictureBox2 = New-Object system.Windows.Forms.PictureBox #L'oggetto per la visualizzazione delle immagini si chiama logicamente
$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 si riferisce all'immagine corrispondente
}
Else {
$PictureBox2.imageLocation = "C:Testno.png" #L'oggetto si riferisce all'immagine corrispondente
}
$PictureBox2.SizeMode = [System.Windows.Forms.PictureBoxSizeMode]::zoom
$PictureBox3 = New-Object system.Windows.Forms.PictureBox #L'oggetto per la visualizzazione delle immagini si chiama logicamente
$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 si riferisce all'immagine corrispondente
}
Else {
$PictureBox3.imageLocation = "C:Testno.png" #L'oggetto si riferisce all'immagine corrispondente
}
$PictureBox3.SizeMode = [System.Windows.Forms.PictureBoxSizeMode]::zoom
$PictureBox4 = New-Object system.Windows.Forms.PictureBox #L'oggetto per la visualizzazione delle immagini si chiama logicamente
$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 si riferisce all'immagine corrispondente
}
Else {
$PictureBox4.imageLocation = "C:Testno.png" #L'oggetto si riferisce all'immagine corrispondente
}
$PictureBox1.SizeMode = [System.Windows.Forms.PictureBoxSizeMode]::zoom
$PictureBox5 = New-Object system.Windows.Forms.PictureBox #L'oggetto per la visualizzazione delle immagini si chiama logicamente
$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 si riferisce all'immagine corrispondente
}
Else {
$PictureBox5.imageLocation = "C:Testno.png" #L'oggetto si riferisce 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 l'evento di clic del pulsante a ciascun PictureBox in base alla 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() #Richiamato un elemento elementare della finestra
Anche mantenendo la pulizia e seguendo la struttura, le modifiche periodiche non saranno delle più piacevoli.
Iniziamo estraendo il controllo della disponibilità in una funzione separata e il percorso della directory in una variabile separata:
$script_path = "C:TestPS ping"
#Passiamo alla funzione l'oggetto PictureBox già creato e l'indirizzo IP da controllare.
#In uscita cambierà l'immagine visualizzata.
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 dell'host in un file esterno path.txt, registrandoli nel formato «ip/host-nome-funzionale/», e nel documento li accetteremo in array. Faremo anche il calcolo della posizione in 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'orario dell'ultima verifica, perché è comodo, e aggiungiamo un po' di 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 funzione di errore che, alla rilevazione di un host non disponibile, comunica non solo cambiando l'indicatore, ma anche emettendo un suono dagli altoparlanti.
Add-Type -AssemblyName System.Speech
$voice = New-Object System.Speech.Synthesis.SpeechSynthesizer
$voice.Rate = 5
$voice.Speak("Attenzione! Attenzione! Host sotto attacco!")
Quindi, dopo alcuni abbellimenti e una sistemazione per renderlo più leggibile e comodo, è venuto fuori 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
#Passiamo alla funzione con l'oggetto PictureBox già creato e l'indirizzo IP da controllare.
#In output 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 barra del titolo
$main_form.Width = 300 #Larghezza della finestra
$main_form.Height = 200 #Altezza della finestra
$main_form.AutoSize = $true #Facciamo in modo che possa ridimensionarsi autonomamente, se necessario
$main_form.TopMost = $true #Questa è una cosa molto importante, permette di mantenere 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, o meglio, il numero di righe
$i = 0
#Dopo dichiariamo gli array che saranno necessari
$ip = @() #array di ip
$capt = @() #array di descrizioni
$Labels =@() #array di Label
$PictureBoxs =@() #array di 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 il 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 il 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 #Facciamo "passo" lungo l'asse Y
$Labels += $label_obj #Aggiungiamo il Label creato all'array generale
$PictureBoxs += $PictureBox_obj #Aggiungiamo il PictureBox creato all'array generale
$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 l'evento di clic al pulsante per ogni PictureBox secondo la logica già 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()
Postfazione
Spero che questo tutorial possa essere utile a qualcuno. Se hai fatto qualcosa di simile sin dalla culla, ti faccio i miei complimenti, io non l'ho fatto. Ma sono pronto ad ascoltare i tuoi commenti e suggerimenti.
È stato un piacere per me scavare e raccogliere questo piccolo strumento utile per la vita quotidiana. Ho in programma di implementare l'aggiunta e la rimozione di nodi dall'interfaccia grafica, così come di realizzare quella funzionalità che avrebbe dovuto essere implementata per prima, l'aggiornamento automatico degli stati senza la necessità di premere il pulsante e per evitare che 'powershell.exe' si blocchi.
