03/09/2009

Riavviare e controllare lo stato di un servizio Windows

A cura di Efran Cobisi
Tag: Nessun tag disponibile.


Windows PowerShell dispone di un ottimo arsenale di cmdlet e funzionalità per gestire servizi Windows; non solo esistono comandi per interagire con lo stato di un determinato servizio (avvio, arresto, pausa) ma la shell, mettendo a disposizione la completa integrazione con il framework Microsoft .NET, consente la manipolazione degli oggetti managed ritornati dai vari cmdlet.

Chi tra i lettori ha mai amministrato IIS da riga di comando, ad esempio, sicuramente ricorderà l'utility IISReset.exe; questo tool consente di effettuare diverse operazioni con il servizio di Internet Information Services, tra cui procederne al riavvio. La compattezza del comando e la semplicità d’uso ne fanno sicuramente un tool molto utilizzato tra gli amministratori di sistema.
Nel prosieguo di questo snippet cercheremo di creare uno script che sostituisca IISReset e consenta di gestire qualsiasi altro servizio con la stessa praticità.

Ecco l’utilizzo più semplice di IISReset, il riavvio di IIS (curioso, vero?):


10# IISReset
Attempting stop...
Internet services successfully stopped
Attempting start...
Internet services successfully restarted

L’approccio adottato da PowerShell, d’altra parte, ne rivela la struttura marcatamente ad oggetti sottostante e consente un utilizzo molto più preciso degli strumenti di controllo e gestione dei servizi messi a disposizione dal sistema operativo.
Se esaminassimo il codice sorgente della funzionalità del riavvio di IIS presente in IISReset vedremmo che esistono tre blocchi principali; il primo acquisisce un riferimento al servizio W3SVC, il secondo effettua lo STOP (se necessario) ed il terzo impartisce il comando di START.

Ora, premesso che la discussione è valida per qualsiasi altro servizio Windows, proviamo a ricreare quanto descritto con PowerShell. Per prima cosa utilizziamo il cmdlet Get-Service per ottenere un oggetto in grado di gestire per noi il servizio che ci interessa; nel nostro caso richiediamo il servizio W3SVC, ovvero IIS.

$w3svc = (Get-Service W3SVC)

Ottenuto il nuovo oggetto nella variabile $w3svc possiamo ora utilizzarne proprietà e metodi. La proprietà Status, ad esempio, ritorna lo stato del servizio, secondo i valori contemplati dall’enumerazione ServiceControllerStatus:

  • ContinuePending
  • Paused
  • PausePending
  • Running
  • StartPending
  • Stopped
  • StopPending

Due metodi, poi, consentono di arrestare ed avviare il servizio; si tratta, rispettivamente, del metodo Stop() e Start(). L’impiego di questi metodi è banale e potremmo pensare, giunti a questo punto, che per riavviare il nostro servizio sia sufficiente eseguire quanto segue:

$w3svc.Stop() $w3svc.Start()

Provandoci, vi accorgerete molto probabilmente che questo blocco genera nella maggior parte dei casi degli errori e non produce gli effetti desiderati. Perché? Continuate a leggere per scoprirlo (oppure fate una donazione a powershell.it, vi manderemo la risposta via email se preferite)!

I messaggi di controllo (START, STOP, etc.) inviati ai servizi utilizzano infatti un’interfaccia di gestione presente all’interno di Windows, chiamata SCM (Service Control Manager); l’elaborazione di tali messaggi è asincrona e si rivela perciò necessario attenderne l’espletamento prima di procedere oltre con ulteriori messaggi, che verrebbero altrimenti scartati. Il metodo WaitForStatus() ci viene allora in aiuto, consentendoci di interrompere l’elaborazione del nostro codice fino al raggiungimento dello stato richiesto (è anche possibile specificare un timeout).

Ecco, quindi, come possiamo completare il nostro snippet di riavvio, con tanto di funzione richiamabile in stile Verb-Noun:

function Restart-Service($serviceName = $( throw 'Nome del servizio obbligatorio' )) { $service = (Get-Service $serviceName) if ($service.Status -ne 'Stopped') { $service.Stop() $service.WaitForStatus('Stopped') } $service.Start() $service.WaitForStatus('Running') }

Richiamabile, naturalmente, con il solito one liner:

Restart-Service W3SVC
Commenti

Nessun commento disponibile.