Windows PowerShellLavorare senza script

Don Jones

In qualsiasi occasione in cui ho modo di illustrare l'utilizzo di Windows PowerShell, durante una conferenza, nel newsgroup pubblico dedicato a Windows PowerShell o sul mio sito, mi imbatto continuamente in amministratori che confessano di voler "attendere ancora un po'" prima di imparare a utilizzare Windows PowerShell. Perché? La ragione più comune avanzata a sostegno di questa decisione è che

non dispongono del tempo materiale sufficiente per imparare a scrivere script.

È un sentimento comune. Gli amministratori sono in effetti una categoria perennemente occupata e spesso, proprio in virtù della mancanza di tempo libero, sono riluttanti ad apprendere l'utilizzo di una nuova tecnologia. Tuttavia è necessario che gli amministratori guardino avanti, apprendano l'utilizzo di nuovo software, come Windows Vista®, Windows Server® 2008 ed Exchange Server 2007, in modo da poter stare al passo con tutte le tecnologie che rivestono un'importanza critica per lo svolgimento del relativo lavoro. Windows PowerShell™ è una parte chiave di queste tecnologie.

Un altro motivo citato dagli amministratori a sostegno della decisione di rinunciare a imparare a scrivere script in Windows PowerShell è "la paura di diventare programmatori". Sotto questo aspetto, il presente articolo può rivelarsi particolarmente utile per tutti gli amministratori "afflitti" da questa paura. Si potrebbe rimanere piacevolmente sorpresi nello scoprire gli eccezionali risultati che è possibile ottenere con Windows PowerShell, senza scrivere il benché minimo frammento di codice.

Introduzione alla pipeline

In passato ho già parlato della pipeline orientata a oggetti, estremamente flessibile e potente utilizzata in Windows PowerShell. Anche se l'espressione "orientata a oggetti" potrebbe far sospettare che mi stia dirigendo verso un terreno proprio dei programmatori, nel corso dell'articolo si scoprirà che non è affatto così. Una delle caratteristiche della pipeline che preferisco è rappresentata dal fatto che è possibile utilizzarla in modo interattivo. Consente di ottenere risultati immediati e di perfezionarli con facilità in base alle esigenze. Si supponga, ad esempio, che sia necessario eseguire un inventario dello spazio disponibile su disco per diversi computer remoti. Si supponga inoltre che i nomi di tali computer siano elencati in un file di testo denominato C:\Computers.txt. Si tratta di un normale file di testo con un nome di computer per riga: nulla a che vedere con le complessità insite nella gestione di un database.

Per cominciare, mi limiterò a verificare se è possibile recuperare le informazioni dal computer locale. Dopotutto, se è possibile effettuare questa attività su un singolo computer, l'esecuzione della stessa attività su più computer dovrebbe essere piuttosto semplice. Inoltre questa attività non implica alcun lavoro di script. Tutte le operazioni verranno eseguite in modo interattivo nella shell e i risultati verranno restituiti immediatamente dopo aver premuto il tasto Invio.

Di seguito è riportato un suggerimento su questo tipo di attività. Per eseguire un inventario delle informazioni di gestione da computer remoti, è probabile che si utilizzi Strumentazione gestione Windows® (WMI). Ai fini dell'esempio, si supponga di utilizzare WMI. Accedo quindi a Live Search e immetto come termine di ricerca "windows wmi free disk space". Vengono visualizzati diversi risultati con la frase "Win32_LogicalDisk". Questa ha tutta l'apparenza di essere una classe WMI e potrebbe essere proprio la classe che sto cercando. Ignoro quindi tutti gli altri risultati della ricerca e immetto "Win32_LogicalDisk" come nuovo termine di ricerca; il risultato restituito fa riferimento a una pagina della documentazione di Win32_LogicalDisk sul sito MSDN® (msdn2.microsoft.com/aa394173.aspx). Accedo quindi a tale pagina e scopro che una delle proprietà per questa classe è FreeSpace. Sembra promettente!

Individuazione di un cmdlet

Per il passaggio successivo è necessario individuare un cmdlet che consenta di recuperare automaticamente le proprietà di una classe WMI. Uno degli aspetti più interessanti di Windows PowerShell è la disponibilità di straordinarie funzionalità di individuazione automatica integrate, vale a dire che la stessa shell aiuta a scoprire le proprie capacità. Immetto quindi Help *wmi* per individuare informazioni sull'utilizzo di WMI all'interno della shell. I risultati, illustrati nella Figura 1, sono l'alias Gwmi e il cmdlet a cui fa riferimento, Get-WMIObject. In sostanza, sono disponibili due modi per accedere alla stessa funzionalità che è possibile utilizzare indifferentemente. Poiché consentono di eseguire la stessa operazione, utilizzerò l'alias più breve, Gwmi:

Figura 1 Informazioni della shell sull'utilizzo di WMI

Figura 1** Informazioni della shell sull'utilizzo di WMI **(Fare clic sull'immagine per ingrandirla)

PS C:\> gwmi win32_logicaldisk

Per la gioia degli amministratori a corto di tempo, in Windows PowerShell non viene rilevata alcuna distinzione tra maiuscole e minuscole.

I risultati del comando, illustrati nella Figura 2, includono tutte le cinque unità locali e le relative proprietà FreeSpace, elencate in byte. Per ciascuna di queste unità viene inoltre riportata la proprietà DriveType e sul computer locale vengono visualizzati i valori 2, 3 e 5.

Figura 2 Tutte le unità locali e le relative proprietà FreeSpace

Figura 2** Tutte le unità locali e le relative proprietà FreeSpace **(Fare clic sull'immagine per ingrandirla)

Cmdlet del mese

È possibile che si sia utilizzato Get-Content per leggere il contenuto di un file di testo. Questo cmdlet considera ciascuna riga del file come oggetto [string], passando tali oggetti alla pipeline in modo che possano essere utilizzati da altri cmdlet. Tuttavia, Get-Content è dotato di numerose opzioni che garantiscono un maggiore livello di flessibilità: il parametro –readCount, ad esempio, consente di specificare quanti oggetti [string] passare contemporaneamente alla pipeline (l'impostazione predefinita prevede che vengano passati tutti gli oggetti), mentre il parametro –totalCount controlla il numero totale di righe lette dal file. Entrambi questi parametri risultano utili per l'utilizzo di file di grandi dimensioni per i quali, per motivi di prestazioni, è opportuno non elaborare l'intero file tutto in una volta.

Ecco un altro suggerimento. Il parametro –encoding consente di leggere in modo corretto un'ampia gamma di tipi di codifica di file, tra cui Unicode, ASCII, UTF7, UTF8 e molti altri. Per un elenco completo dei tipi di codifica supportati, eseguire help gc (gc è un alias per Get-Content).

Ridefinizione dei dati

A questo punto ho davanti due problemi. Innanzitutto, non sono interessato a tutte le altre proprietà: mi interessa solo FreeSpace. Secondo, il mio obiettivo non è ottenere informazioni sulla quantità di spazio disponibile per unità ottiche, unità rimovibili o unità di rete; sono interessato solo alle unità disco rigido locali. A tal fine, la proprietà DriveType può risultare utile per operare una distinzione tra i diversi tipi di unità restituiti. Accedo di nuovo al browser Web e noto che la documentazione contiene una tabella in cui viene spiegato il significato dei diversi valori di DriveType. Le sole unità a cui sono interessato solo quelle a cui è associata la proprietà DriveType con valore 3, che indica che l'unità è un disco rigido locale. Non avendo mai eseguito questa operazione in precedenza, decido di verificare se il comando Gwmi è in grado di eseguire automaticamente operazioni di filtraggio. Se si esegue Help Gwmi –full, sarà possibile ottenere informazioni dettagliate sulla modalità di funzionamento del comando, inclusi diversi esempi. Nell'elenco delle informazioni restituite noto un parametro che sembra particolarmente utile, –filter, quindi decido di provare a eseguirlo:

gwmi win32_logicaldisk -filter "drivetype = 3"

Operazione riuscita! Il mio elenco di unità ora contiene solo dischi rigidi locali. Il secondo problema è pertanto risolto; ora è necessario risolvere il primo, ovvero liberarsi di tutte le proprietà non rilevanti ai fini dell'esempio.

Eseguo Get-Command per elencare tutti i cmdlet di Windows PowerShell e l'occhio si posa casualmente su Select-Object. La descrizione suggerisce che consente di selezionare proprietà specifiche di un oggetto o insieme di oggetti. Provo pertanto a utilizzare questo cmdlet:

gwmi win32_logicaldisk -filter "drivetype = 3" | select freespace

Inviando i risultati di Gwmi a Select (l'alias per Select-Object), otterrò esattamente la proprietà che mi interessa. Però i risultati non sono affatto "intuitivi": è stato restituito semplicemente un elenco di numeri. Accedo di nuovo alla documentazione e scopro che la proprietà DeviceID contiene la lettera di unità. Modifico rapidamente il comando e provo di nuovo:

gwmi win32_logicaldisk -filter "drivetype = 3" | select deviceid,freespace

Perfetto! Poiché vengono elencate solo due proprietà, la shell è in grado di inserire le informazioni in una tabella molto razionale. Nell'articolo del prossimo mese illustrerò i casi in cui Windows PowerShell sceglie di utilizzare elenchi e tabelle.

Calcolo

Ho recuperato informazioni sulla quantità di spazio disponibile, ma tali dati sono espressi in byte anziché in megabyte o gigabyte. Probabilmente, ai fini dell'esempio, più che la proprietà FreeSpace può risultare particolarmente utile un valore calcolato dalla proprietà FreeSpace. Il cmdlet ForEach-Object (o uno dei relativi alias, come %) può rivelarsi utile. Questo cmdlet consente di utilizzare una variabile speciale, $_, per fare riferimento al disco logico corrente e di accedere alle singole proprietà di ciascun disco ed effettuare alcuni calcoli matematici. Di seguito viene riportato il comando modificato:

gwmi win32_logicaldisk -filter "drivetype = 3" | % { $_.deviceid; $_.freespace/1GB }

La modifica del comando prevede semplicemente la rimozione di Select e la relativa sostituzione con l'alias per ForEach-Object (%). Indico a ForEach-Object il tipo di operazione da eseguire con ciascuna classe Win32_LogicalDisk restituita, ovvero utilizzare la proprietà DeviceID e dividere la proprietà FreeSpace per un gigabyte (Windows PowerShell è in grado di riconoscere unità di misura come KB, MB e GB). Pertanto il mio risultato verrà restituito in gigabyte.

Più computer

A questo punto, dato l'esito positivo dell'operazione per un singolo computer, è giunto il momento di verificare se si riesce a ottenere lo stesso risultato su più sistemi. So come ottenere il contenuto di un file di testo. Si tratta di un'operazione che riporta indietro nel tempo, all'epoca di MS-DOS®. Per eseguirla, occorre infatti utilizzare il comando Type che in Windows PowerShell è un alias per Get-Content:

Type c:\computers.txt

Lo scopo ora consiste nell'eseguire il comando WMI utilizzato in precedenza per ciascun computer. Anche in questo caso occorre fare ricorso all'ormai noto cmdlet ForEach-Object. A questo punto non resta che esaminare l'ultimo comando:

type c:\computers.txt | % { $_; 
gwmi –computername $_ win32_logicaldisk -filter "drivetype=3" | % { $_.deviceid; $_.freespace/1GB} }

Orribile, vero? L'utilizzo esclusivo di alias anziché di nomi di cmdlet rende la lettura di questo codice piuttosto difficoltosa. Tuttavia, andando avanti si scoprirà che è abbastanza semplice da decifrare:

  • Inizio digitando il contenuto del file di testo.
  • Invio tale contenuto a ForEach-Object.
  • ForEach-Object restituisce, utilizzando la variabile $_, l'elemento corrente, ovvero il nome del computer corrente.
  • ForEach-Object quindi esegue il comando WMI, che include un'altra chiamata a ForEach-Object.

L'espansione dei nomi di alias in nomi di cmdlet potrebbe essere di aiuto. Anche in questo caso viene utilizzato lo stesso comando, ma questa volta ho digitato i nomi completi dei cmdlet e ho suddiviso il comando in singole righe in modo da semplificare l'analisi di ciascuna sezione:

Get-Content C:\Computers.txt | 
ForEach-Object { 
 $_; Get-WMIObject –computername $_ 
Win32_LogicalDisk -filter "DriveType=3" | 
 ForEach-Object { 
 $_.DeviceID; $_.FreeSpace/1GB
 }
}

I risultati, magari non eleganti ma molto funzionali, sono illustrati nella Figura 3.

Figura 3 Risultati finali

Figura 3** Risultati finali **(Fare clic sull'immagine per ingrandirla)

Conclusione: gli script non sono necessari

L'obiettivo di questa presentazione è dimostrare che è possibile utilizzare Windows PowerShell senza alcun lavoro di script. Con pochi esempi, come quello riportato in questo articolo, più un minimo di esplorazione di Windows PowerShell, sarà possibile individuare alcune delle informazioni necessarie per eseguire tutte le attività desiderate.

La conclusione è che l'uso di Windows PowerShell è destinato a diffondersi. Perché non iniziare ad apprenderne le basi fin da subito? Tra qualche tempo è probabile che sembrerà impossibile farne a meno, ma ora di certo non è il termine "script" che può impedire di approfondire l'argomento Windows PowerShell.

Don Jones è il guru degli script di SAPIEN Technologies e istruttore per ScriptingTraining.com. È possibile contattare Don sul suo sito Web, ScriptingAnswers.com.

© 2008 Microsoft Corporation e CMP Media, LLC. Tutti i diritti riservati. È vietata la riproduzione completa o parziale senza autorizzazione.