Indice dei contenuti
Questo articolo ha lo scopo di illustrare il funzionamento di RunningLow, un semplice script PowerShell che ho realizzato con l'intento di dotare i miei server Windows di uno strumento in grado di avvisarmi quando lo spazio libero residuo sui vari Hard-Disk locali e di rete scende sotto al livello di guardia.
Chiunque lavori abitualmente con macchine Windows fisiche e/o virtualizzate conosce benissimo l'importanza di avere costantemente sotto controllo questa informazione: un server che finisce lo spazio va rapidamente incontro a problemi bloccanti e cessa di funzionare correttamente, stante l'impossibilità di svolgere la maggior parte delle operazioni basate su I/O: creare file temporanei, memorizzare informazioni, svolgere le periodiche attività di manutenzione, backup e aggiornamento, creare o aggiornare sessioni web - se queste vengono gestite tramite file - e così via. La faccenda è ancora più grave quando i server in questione ospitano servizi DBMS come MySQL o MS-SQL, dove l'impossibilità di utilizzare il FileSystem può tradursi nella perdita di consistenza di indici, integrità dei dati contenuti nelle varie tabelle e altre spiacevolissime situazioni.
Lo scopo primario di RunningLow è prevenire tutto questo: lo script è infatti in grado di controllare uno o più drive locali e/o di rete verificando che lo spazio libero non sia sceso al di sotto di una quota preimpostata e, in caso affermativo, inviare un avviso tramite e-mail a uno o più indirizzi. L'idea non è certo originale: esistono decine di strumenti di amministrazione e applicativi specifici che sono in grado di svolgere queste operazioni: persino CCleaner della Piriform - sebbene soltanto nella versione PRO - può essere configurato in modo da inviare avvisi. Al tempo stesso, se non volete spendere altri soldi in licenze o se non avete voglia di appesantire il vostro sistema con un agent perennemente attivo, potreste apprezzare l'economicità e le performance di questa semplice e leggera alternativa.
Il Codice Sorgente
Ecco il codice sorgente della prima - e ad oggi più recente - versione di RunningLow:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 |
# Drives to check: set to $null or empty to check all local (non-network) drives # $drives = @("C","D"); $drives = $null; # The minimum disk size to check for raising the warning $minSize = 20GB; # SMTP configuration: username, password & so on $email_password = "yourpassword"; $email_smtp_host = "smtp.yourdomain.com"; $email_smtp_port = 25; $email_smtp_SSL = 0; if ($drives -eq $null -Or $drives -lt 1) { $localVolumes = Get-WMIObject win32_volume; $drives = @(); foreach ($vol in $localVolumes) { if ($vol.DriveType -eq 3 -And $vol.DriveLetter -ne $null ) { $drives += $vol.DriveLetter[0]; } } } foreach ($d in $drives) { Write-Host ("`r`n"); Write-Host ("Checking drive " + $d + " ..."); $disk = Get-PSDrive $d; if ($disk.Free -lt $minSize) { Write-Host ("Drive " + $d + " has less than " + $minSize ` + " bytes free (" + $disk.free + "): sending e-mail..."); $message = new-object Net.Mail.MailMessage; $message.From = $email_from_address; foreach ($to in $email_to_addressArray) { $message.To.Add($to); } $message.Subject = ("[RunningLow] WARNING: " + $env:computername + " drive " + $d); $message.Subject += (" has less than " + $minSize + " bytes free "); $message.Subject += ("(" + $disk.Free + ")"); $message.Body = "Hello there, `r`n`r`n"; $message.Body += "this is an automatic e-mail message "; $message.Body += "sent by RunningLow Powershell script "; $message.Body += ("to inform you that " + $env:computername + " drive " + $d + " "); $message.Body += "is running low on free space. `r`n`r`n"; $message.Body += "--------------------------------------------------------------"; $message.Body += "`r`n"; $message.Body += ("Machine HostName: " + $env:computername + " `r`n"); $message.Body += "Machine IP Address(es): "; $ipAddresses = Get-NetIPAddress -AddressFamily IPv4; foreach ($ip in $ipAddresses) { if ($ip.IPAddress -like "127.0.0.1") { continue; } $message.Body += ($ip.IPAddress + " "); } $message.Body += "`r`n"; $message.Body += ("Used space on drive " + $d + ": " + $disk.Used + " bytes. `r`n"); $message.Body += ("Free space on drive " + $d + ": " + $disk.Free + " bytes. `r`n"); $message.Body += "--------------------------------------------------------------"; $message.Body += "`r`n`r`n"; $message.Body += "This warning will fire when the free space is lower "; $message.Body += ("than " + $minSize + " bytes `r`n`r`n"); $message.Body += "Sincerely, `r`n`r`n"; $message.Body += "-- `r`n"; $message.Body += "RunningLow`r`n"; $message.Body += "https://www.ryadel.com/RunningLow"; $smtp = new-object Net.Mail.SmtpClient($email_smtp_host, $email_smtp_port); $smtp.EnableSSL = $email_smtp_SSL; $smtp.Credentials = New-Object System.Net.NetworkCredential($email_username, $email_password); $smtp.send($message); $message.Dispose(); write-host "... E-Mail sent!" ; } else { Write-Host ("Drive " + $d + " has more than " + $minSize + " bytes free: nothing to do."); } } |
E' sufficiente effettuare il copia/incolla del codice di cui sopra, salvarlo in un file denominato RunningLow.ps1 (o qualsiasi altro nome) e il gioco è fatto. In alternativa è anche possibile scaricare l'ultima versione dalla pagina ufficiale del progetto su GitHub.
Configurazione
Le prime righe dello script riguardano le varie opzioni di configurazione possibili, che ciascun amministratore dovrà modificare sulla base delle proprie esigenze e adattare al proprio contesto di utilizzo. L'opzione più importante è senza dubbio quella che riguarda i drive che dovranno essere oggetto del controllo: come si può vedere osservando il codice, è possibile sia indicare un array di lettere di unità corrispondenti ai dischi da controllare - locali o di rete, a patto che i drive di rete siano stati mappati in modo permanente su lettere di unità locali - sia indicare un valore null o empty: in questo secondo caso, lo script svolgerà il controllo su tutti i dischi locali.
I commenti inseriti all'interno del codice dovrebbero essere più che sufficienti a guidare chiunque nel resto della configurazione: in ogni caso, chiunque abbia bisogno di ulteriore assistenza può scrivere la sua domanda nella sezione commenti di questo articolo: farò del mio meglio per rispondere.
Test
Una volta terminata la configurazione, è opportuno effettuare un paio di test per assicurarci che lo script funzioni correttamente. Come ben sa chiunque lavori abitualmente con PowerShell lo script può essere lanciato in due modi, tramite il Prompt dei Comandi di Windows:
1 |
> powershell -executionpolicy bypass -File RunningLow.ps1 |
... o mediante un Prompt Powershell:
1 |
> .\RunningLow.ps1 |
Lo script, una volta eseguito, dovrebbe mostrare a schermo il seguente risultato:
L'assenza di "righe rosse" è sufficiente a indicarci che tutto è andato per il meglio.
Invio E-Mail
Assodato che lo script viene eseguito correttamente, è opportuno verificare anche il funzionamento della funzionalità di invio e-mail. Il modo migliore per farlo è modificare temporaneamente il valore della variabile $minSize all'interno dello script, impostando un valore eccezionalmente alto (ad es. 5TB) così da essere certi che il controllo di spazio in esaurimento darà esito positivo, provocando l'invio della e-mail. Se tutto andrà correttamente, dovremmo vedere un riscontro a schermo analogo a quello mostrato all'interno dello screenshot seguente:
A questo punto non ci resta che controllare il nostro client di posta e assicurarci di ricevere l'alert: non appena avremo verificato anche quest'ultimo punto potremo essere certi che lo script funziona correttamente.
Installazione
Ovviamente lo script non è pensato per essere lanciato manualmente dall'operatore, ma per essere eseguito automaticamente e a intervalli regolari. Il modo migliore per ottenere questo è creare un'apposita entry nel Task Scheduler di Windows, noto in italiano come Operazioni Pianificate.
IMPORTANTE: nella configurazione Generale del task, assicuratevi di impostare le opzioni Esegui indipendentemente dalla connessione dell'utente ed Esegui con i privilegi più elevati, altrimenti lo script verrà eseguito solo nel caso in cui esista una sessione utente attiva.
Nell'esempio di seguito, ho configurato RunningLow in modo che venga eseguito ogni giorno alle ore 12:00:
Nella finestra dedicata all'inserimento di una nuova azione è possibile inserire il comando di esecuzione dello script in vari modi: in una singola riga, dividendo eseguibile ( powershell ) e parametri ( -executionpolicy bypass -File RunningLow.ps1 ). E' inoltre importantissimo specificare la directory di esecuzione, cosa che nel nostro caso è ben poco opzionale in quanto abbiamo necessità di puntare a uno script che si trova in una cartella specifica: in alternativa, il percorso completo del file RunningLow.ps1 può essere specificato anche nei parametri, nel seguente modo:
1 |
> powershell -executionpolicy bypass -File "C:\<path>\<to>\RunningLow.ps1" |
Una volta completata l'installazione, è fortemente consigliabile effettuare un secondo e ulteriore test - comprensivo di invio di e-mail - per assicurarsi che non vi siano regole di firewall o restrizioni particolari che possano ostacolare l'esecuzione dello script e/o l'invio degli avvisi.
Per il momento è tutto: mi auguro sinceramente che questo script possa aiutarvi a tenere sotto controllo i vostri server Windows!
Link Utili
- Repository ufficiale di RunningLow su GitHub.
Buongiorno, sarebbe possibile avere i valori espressi in Gigabyte?
Se si, in che modo?
Ringrazio anticipatamente.