Monitoraggio della disponibilità degli host su Powershell

Buon pomeriggio a tutti, voglio condividere una semplice istruzione "Come smettere di pingare manualmente un decina di host. Senza registrazione e SMS!".

Monitoraggio della disponibilità degli host su PowershellDalle 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:

Monitoraggio della disponibilità degli host su Powershell

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?

Monitoraggio della disponibilità degli host su Powershell

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 offensivo

Aggiungiamo 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.

Monitoraggio della disponibilità degli host su Powershell

$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…

Monitoraggio della disponibilità degli host su Powershell
E aggiungiamo un pulsante, così avremo la possibilità di aggiornare i dati.

Monitoraggio della disponibilità degli host su 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 = "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)

Monitoraggio della disponibilità degli host su Powershell

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:

Monitoraggio della disponibilità degli host su 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
	}

Aggiungiamo uno spazio per visualizzare l'orario dell'ultima verifica, perché è comodo, e aggiungiamo un po' di azione al clic del pulsante.

Monitoraggio della disponibilità degli host su 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 
	})

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.

L'ultima versione dello script su GitHub

Fonte: habr.com

Acquista hosting affidabile per siti web con protezione DDoS, VPS VDS server 🔥 Acquista hosting affidabile per siti web con protezione DDoS, VPS VDS server | ProHoster