Windows PowerShellRiflessioni sulla pipeline

Don Jones

Molto è stato detto a proposito del perché Windows PowerShell sia diverso, nuovo e interessante, malgrado sia basato su concetti di interfaccia della riga di comando in circolazione da decenni, principalmente sui sistemi operativi basati su UNIX e Linux. Tuttavia, la terminologia comune che Windows PowerShell condivide con i suoi predecessori può portare

a trascurare le reali caratteristiche di flessibilità ed esclusività di Windows PowerShell nonché la notevole idoneità per un ambiente Windows®.

Una delle funzionalità più discusse di Windows PowerShell è la pipeline, che però, sfortunatamente, è anche una di quelle meno capite. Ciò è dovuto all'uso di una terminologia definita nel corso dei primi anni '70 per rappresentare funzionalità completamente diverse e meno efficaci.

Origine delle pipe

Una delle prime shell UNIX mai create è stata la shell Thompson, che era molto primitiva e presentava solo i più elementari elementi del linguaggio di script senza variabili. L'impostazione della shell era volutamente modesta in quanto l'unica funzione che doveva svolgere era quella di eseguire programmi. Tuttavia, essa ha introdotto un concetto chiave che ha contribuito a migliorare le altre shell di quel tempo: le pipe. Grazie all'utilizzo dei simboli < e >, era possibile indicare alla shell di reindirizzare l'input e l'output da e verso diversi comandi. Un utente era così in grado, ad esempio, di reindirizzare l'output di un comando su un file.

Questa sintassi è stata successivamente ampliata in modo che l'output di un comando potesse anche essere reindirizzato all'input di un altro comando, consentendo di concatenare lunghe sequenze di comandi per svolgere operazioni più complicate. Con la versione 4 della shell, il carattere di linea verticale "|" è stato adottato per il piping diventando così noto come il carattere pipe. Perfino le prima versioni di MS-DOS® hanno implementato il piping di base per mezzo di questi caratteri, consentendo, ad esempio, di reindirizzare l'output del comando Type nell'input del comando More per visualizzare lunghi file di testo una pagina alla volta.

Anche se quando venne rilasciata la versione 6 di UNIX nel 1975, la shell di Thompson era ampiamente considerata come inadeguata, il concetto di pipe si radicò a fondo tra gli sviluppatori di shell e gli utenti e venne portato avanti in varie tecnologie tuttora in uso.

Piping del testo

Una limitazione di quasi tutte le shell è la natura intrinsecamente basata sul testo. Nei sistemi operativi basati su UNIX questa di fatto non è una limitazione, ma rispecchia piuttosto il tipo di funzionamento del sistema operativo stesso. Quasi tutte le risorse in UNIX possono essere rappresentate come un file di qualche tipo, il che significa che la possibilità di reindirizzare il testo da un comando a un altro offre un notevole grado di potenza e flessibilità.

Tuttavia, il testo costituisce una limitazione nel momento in cui è necessario passare alle informazioni di gestione. Ad esempio, se dovessi presentare un elenco dei servizi in esecuzione su un computer Windows, la cosa diventerebbe certamente più chiara. Probabilmente, inserirei il nome del servizio nella prima colonna e la relativa modalità di avvio nella seconda. L'efficace cervello umano analizzerebbe o convertirebbe in modo trasparente e immediato il testo visualizzato in informazioni significative con cui sarebbe possibile lavorare. I computer, però, non sono così intelligenti: per fare in modo che un computer svolga un'operazione utile con un tale elenco, sarebbe necessario indicargli che la prima colonna è composta di caratteri da 1 a 20, mentre i caratteri da 22 fino a 40 denotano la seconda e così via.

Per lungo tempo, questo tipo di analisi dei file di testo ha rappresentato l'unico modo per gli amministratori di concatenare insieme più comandi. Infatti, i linguaggi di script quali VBScript e Perl si distinguono nella manipolazione delle stringhe principalmente perché devono essere in grado di accettare output di testo da un programma o da un comando per poi analizzarlo e tradurlo in dati utili per svolgere attività successive. Ad esempio, mi è capitato di scrivere processi VBScript che accettavano l'output di testo del comando Dir, lo analizzavano per individuare nomi di file e date, quindi spostavano i file inutilizzati in una posizione di archivio. L'analisi delle stringhe è estremamente difficile a causa delle eccezioni, variazioni nell'input dei dati, che si verificano quasi sempre, imponendo di rivedere la logica nello script per gestire tutte le combinazioni possibili.

Come forma di script amministrativo o di automazione in un ambiente Windows, l'analisi delle stringhe si rivela meno utile. La ragione è che Windows stesso non memorizza molte informazioni in un formato di testo di facile accesso. Vengono invece utilizzati archivi centrati sui dati, quali Active Directory®, il Registro di sistema di Windows e l'archivio certificati, in modo che i creatori di script debbano utilizzare dapprima uno strumento per creare un qualsiasi tipo di output del testo e in seguito uno script per analizzare questo testo da utilizzare successivamente.

Gli oggetti sono più semplici

Le cose per gli sviluppatori di software Windows sono sempre state un po' più semplici. Inizialmente, Microsoft ha sviluppato COM appositamente per rappresentare i complessi funzionamenti interni di Windows in un una modalità più facile da utilizzare. Attualmente, Microsoft® .NET Framework svolge lo stesso compito: rappresenta il funzionamento interno del software in una modalità standardizzata.

Genericamente, entrambi COM e .NET espongono gli elementi sotto forma di oggetti. Uno sviluppatore di software potrebbe obiettare a questa semplificazione, ma ai fini della nostra discussione, un semplice termine è sufficiente. Tutti questi oggetti prevedono membri di diverso tipo. Per i nostri scopi, le proprietà e i metodi degli oggetti costituiscono l'aspetto più interessante. Una proprietà descrive sostanzialmente un oggetto oppure modifica l'oggetto o il relativo comportamento. Ad esempio, un oggetto servizio può avere una proprietà che contiene il nome del servizio e un'altra proprietà che contiene la modalità di avvio del servizio. I metodi indicano a un oggetto di fare qualcosa. Un oggetto servizio potrebbe comprendere metodi chiamati Stop, Start, Pause e Resume, ad esempio, per rappresentare le diverse operazioni che può svolgere.

Da un punto di vista della programmazione o degli script, il riferimento ai membri di un oggetto avviene per mezzo di una notazione puntata. Gli oggetti vengono spesso assegnati a variabili, fornendo un metodo per manipolare fisicamente l'oggetto. Ad esempio, se alla variabile $service è assegnato un servizio, è possibile interrompere tale servizio mediante la sintassi $service.Stop. Allo stesso modo è possibile recuperare il nome visualizzato del servizio visualizzando $service.Name.

Oggetti nella pipe

Poiché Windows è un sistema operativo grande e complesso e poiché non memorizza i propri dati di gestione nelle rappresentazioni in stile testo, le precedenti tecniche della shell non sono assolutamente adeguate. Ad esempio, supponiamo di avere uno strumento della riga di comando di nome SvcList.exe che produce un elenco formattato di servizi e delle relative modalità di avvio. Nella shell della riga di comando di Windows, che tiene saldamente le proprie radici nella più che decennale shell del DOS, posso fare qualcosa di simile a quanto riportato di seguito:

SvcList.exe | MyScript.vbs 

Questa istruzione recupera un elenco di servizi e lo reindirizza su un file VBScript. A questo punto si potrebbe scrivere un file VBScript per analizzare l'elenco formattato e svolgere l'operazione desiderata, magari estrarre tutti i servizi con la modalità di avvio Disattivato. Quest'attività richiederebbe molto tempo. Fondamentalmente, il problema è che l'output di SvcList.exe è specifico in quanto non condivide un formato comune che può essere facilmente sfruttato da altri comandi.

Gli oggetti, tuttavia, sono in grado di fornire questo formato comune e questa è la ragione per cui la pipeline di Windows PowerShell funziona con interi oggetti, non solo con il testo. Quando si esegue un cmdlet del tipo Get-WMIObject, si produce un gruppo o insieme, alla maniera dei programmatori, di oggetti. Ciascun oggetto è dotato di proprietà e metodi che ne consentono la manipolazione. Se gli oggetti vengono reindirizzati verso il cmdlet Where-Object, è possibile filtrarli in modo da visualizzare solo quelli desiderati. Where-Object non deve analizzare alcun testo perché in realtà riceve oggetti. Ad esempio:

Get-WMIObject Win32_Service | Where-Object {$_.StartMode -eq “Disabled” }

Oppure, se si preferisce la sintassi più breve disponibile tramite alias:

gwmi Win32_Service | where {$_.StartMode -eq “Disabled” }

L'aspetto interessante è che Windows PowerShell passa sempre gli oggetti alla pipeline. È solo alla fine della pipeline, dove non c'è altro a cui passare gli oggetti, che la shell genera una rappresentazione di testo degli oggetti utilizzando le relative regole di formattazione incorporate. Si prenda, ad esempio, in considerazione quanto segue:

Gwmi Win32_Service | where {$_.StartName –eq “LocalSystem” } | select Name,StartMode

Questa serie di tre cmdlet recupera tutti i servizi dal computer locale, filtra tutti quelli che non utilizzano l'account LocalSystem per accedere, quindi passa il resto al cmdlet Select-Object che invia in output solo le due proprietà, Name e StartMode, che ho chiesto di selezionare. Il risultato è un semplice report di servizi che accedono in qualità di LocalSystem, magari a fini del controllo della protezione.

Poiché tutti i cmdlet condividono un formato dati comune, gli oggetti, sono in grado di condividere reciprocamente dati senza alcuna complicata analisi di stringhe. Inoltre, poiché Windows PowerShell è in grado di creare una rappresentazione testuale di un oggetto, la fine di questa pipe è certamente un output di testo leggibile. Nella Figura 1 è illustrato un esempio dell'output prodotto.

Figura 1 Output di testo prodotto da una serie di cmdlet reindirizzati passati con gli oggetti

Figura 1** Output di testo prodotto da una serie di cmdlet reindirizzati passati con gli oggetti **

L'entusiasmo suscitato dalle pipe

La ragione dell'efficacia del piping in Windows PowerShell è che tutto al suo interno è un oggetto, completo di proprietà e metodi che è possibile utilizzare. Anche un file di testo è tecnicamente un insieme di oggetti stringa, in cui ciascuna riga funge da oggetto stringa univoco e indipendente. Creare, ad esempio, con Blocco Note un file di testo di nome C:\Computers.txt. Riempire il file con testo, quindi procedere come segue in Windows PowerShell:

Get-Content C:\Computers.txt | Select-Object Length | Format-List

Oppure, anche qui, se si preferisce digitare di meno, è possibile utilizzare gli alias:

gc C:\Computers.txt | select Length | fl

Questo codice fornisce un elenco che indica la lunghezza di ogni riga del file di testo, in caratteri. Get-Content recupera gli oggetti stringa dal file, Select-Object estrae proprietà Lenght di ciascuno, quindi Format-List crea il gradevole output di testo leggibile. Anche se non è uno strumento amministrativo di grande utilità pratica, illustra con semplicità che in Windows PowerShell anche una riga di testo è un oggetto.

La possibilità di reindirizzare oggetti da cmdlet a cmdlet, o anche da cmdlet a script, consente di creare "comandi di una riga" estremamente potenti. Queste sono stringhe di esempio di cmdlet uniti in una lunga pipeline che rifiniscono ulteriormente un set di oggetti per fornire esattamente il risultato desiderato. Senza praticamente alcun lavoro di script o programmazione, i cmdlet di Windows PowerShell raccordati in una pipeline appropriata sono in grado di ottenere notevoli risultati.

Supporto delle generazioni future

Il fatto che anche i futuri prodotti server di Microsoft saranno basati su Windows PowerShell estende questa funzionalità. Ad esempio, nell'implementazione di un nuovo computer Exchange Server 2007 è possibile utilizzare Windows PowerShell per recuperare tutte le cassette postali, filtrare quelle che non si trovano nell'ufficio in cui è situato il nuovo server di posta e spostarle su un nuovo server, con una sola riga di testo senza l'ausilio di script. Il team di Exchange Server 2007 ha pubblicato un lungo elenco di efficaci comandi di una riga. Questi dimostrano realmente la potenza della pipeline e delle attività amministrative che consente di svolgere.

Il trucco con Windows PowerShell è di comprendere che, pur essendo basato su concetti e filosofie di lunga data provenienti dal mondo UNIX, questo nuovo strumento è adatto in modo particolare all'amministrazione di Windows. Non si deve quindi lasciare che una semplice analogia terminologica induca a pensare che Windows PowerShell sia una semplice imitazione della shell UNIX per Windows. Windows PowerShell contiene alcuni concetti nuovi che sfruttano i vantaggi della piattaforma Windows ed è strettamente collegato al modo di operare di Windows.

Don Jones è un Windows PowerShell MVP e autore di Windows PowerShell 101 (ScriptingTraining.com). È possibile contattare Don all'indirizzo www.ScriptingAnswers.com.

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