Hey, Scripting Guy!La scarica di adrenalina

Microsoft Scripting Guys

Nella nostra testa non c'è dubbio che scrivere per TechNet Magazine sia il lavoro più prestigioso e gratificante che si possa fare. (Naturalmente, sarebbe ancora più gratificante se venissimo veramente pagati, ma questa è tutta un'altra storia). Quanto può essere prestigioso questo lavoro? Mettiamola così: proprio in questo momento, in tutto il mondo, i bambini che stanno andando a letto guardano la mamma che rincalza le loro coperte e le dicono, "Mamma, da grande voglio scrivere per una rubrica mensile di scripting su TechNet Magazine".

Nota Inutile dire che, in tutto il mondo, ci sono persone che pensano che la rubrica sia già tenuta da bambini. Ma anche questa è tutta un'altra storia.

Ormai tutti sanno che gli Scripting Guy amano crogiolarsi nell'ammirazione che deriva dallo scrivere per TechNet Magazine; abbiamo persino imparato a sopportare i paparazzi e i cacciatori di autografi. Ma la verità è che non facciamo questo lavoro per l'onore e la gloria. Lo facciamo per la scarica di adrenalina pura che accompagna la scrittura degli script di amministrazione del sistema.

Certo, non capita spesso di vedere le espressioni "scarica di adrenalina pura" e "script di amministrazione del sistema" nella stessa frase. (A meno che, ovviamente, la scarica di adrenalina pura non sia preceduta da una sua assenza assoluta).

Le persone comuni possono considerare la scrittura di script di amministrazione del sistema estremamente utile, ma difficilmente la riterranno un'attività entusiasmante. Al contrario, la riterranno con ogni probabilità una cosa abbastanza noiosa. E il motivo è questo: queste persone non hanno mai provato a scrivere script per i dati di configurazione di avvio in Windows Vista® o Windows Server® 2008.

Saperlo non vi ha fatto aumentare le pulsazioni di uno o due battiti? Come sapranno molti di quelli che stanno leggendo questo articolo, in Windows Vista e Windows Server 2008, il vecchio file boot.ini è stato messo da parte a favore di un nuovo archivio dati di configurazione di avvio che, quando si tratta di gestire il processo di avvio, assicura maggiore flessibilità (e funzionalità).

È tutto molto bello. Ma quello che fa davvero la differenza è che grazie al nuovo provider di Strumentazione gestione Windows® (WMI), tramite gli script oggi è possibile accedere e gestire completamente l'archivio dati di configurazione di avvio (BCD).

Non bisogna preoccuparsi troppo di quella sensazione di formicolio che ha appena passeggiato su e giù lungo la schiena: quello è esattamente il sintomo prodotto da una scarica di adrenalina pura. Basta iniziare a lavorare con gli script BCD e ci si fa presto l'abitudine.

Prima di continuare, ci corre l'obbligo di avvertire che nello spazio di questa rubrica non riusciremo a fare altro che iniziare appena ad accennare a tutto ciò che è possibile fare utilizzando il provider BCD. (A dire il vero, abbiamo inviato alla redazione della rivista un messaggio di posta elettronica in cui chiedevamo se fosse possibile pubblicare un numero doppio speciale interamente dedicato alla scrittura di script per i dati di configurazione di avvio, ma ancora non ci hanno risposto).

Per ottenere informazioni più esaustive, consigliamo di consultare la documentazione relativa al provider WMI di BCD disponibile all'indirizzo go.microsoft.com/fwlink/?LinkId=116953 (in inglese). Nel frattempo, abbiamo pensato di proporre alcuni esempi di codice progettati per computer ad avvio multiplo, ovvero computer in cui è installato più di un sistema operativo.

Sono script che funzionano soltanto in Windows Vista e Windows Server 2008. Questo perché, come ricordato prima, sono gli unici due sistemi operativi che attualmente supportano i BCD.

Iniziamo col dare un'occhiata a uno script che indica quale sistema operativo è al momento utilizzato in un computer. Di certo non si tratta dell'uso più entusiasmante che si possa fare del provider BCD; dopo tutto, possiamo già utilizzare la classe WMI Win32_OperatingSystem per stabilire quale sia il sistema operativo attualmente in uso in un computer. Tuttavia, questo è uno script abbastanza semplice (almeno in fatto di script BCD), che offre un buon modo per descrivere le tecniche necessarie quando si lavora con i BCD. (Tecniche che, a dire il vero, sono un tantino … insolite).

D'altra parte, la nostra rubrica non può trattare temi che suscitano troppe emozioni: TechNet Magazine ha già avvertito che ci ritiene responsabili di tutti i danni provocati dai fan sovraeccitati e troppo zelanti di Hey, Scripting Guy! Considerando il marasma generale esploso nel mondo a seguito della nostra rubrica sulle espressioni regolari, non possiamo proprio permetterci di scrivere di nuovo cose altrettanto destabilizzanti.

Nota Qualcuno ricorda quei filmati in cui si vedono i Beatles assaliti dai loro fan e tutte quelle immagini di ragazze che svenivano e piangevano ogni volta che John, Paul, George e Ringo si facevano vedere? Più o meno è quello che succede a noi ogni volta che pubblichiamo una nuova rubrica.

OK, d'accordo, forse è un'esagerazione. Ma non c'è dubbio che molte persone, sia uomini che donne, iniziano a singhiozzare dopo aver letto uno dei nostri articoli.

Ad ogni modo, diamo uno sguardo allo script mostrato nella Figura 1, in cui il provider BCD viene utilizzato per stabilire quale sistema operativo sia al momento usato in un computer. Prima di tentare di eseguire lo script, è bene sapere che deve essere attiva l'esecuzione come amministratore, altrimenti lo script non riesce.

Figura 1 Individuazione del sistema operativo corrente

Const BcdLibraryString_Description = &h12000004
Const Current = "{fa926493-6f1c-4193-a414-58f0b2456d1e}"

strComputer = "."

Set objStoreClass = GetObject("winmgmts:{(Backup,Restore)}\\" & _
 strComputer & "\root\wmi:BcdStore")

objStoreClass.OpenStore "", objStore
objStore.OpenObject Current, objDefault

objDefault.GetElement BcdLibraryString_Description, objElement
Wscript.Echo "Current operating system: " & objElement.String

Questo non significa che si deve soltanto eseguire l'accesso a un account con privilegi di amministratore. Significa che è necessario aprire una finestra del prompt dei comandi facendo clic con il pulsante destro del mouse su Prompt dei comandi nel menu Start e selezionando Esegui come amministratore. Solo a questo punto si può eseguire lo script dal prompt dei comandi.

Come funziona lo script? Temevamo che qualcuno ce l'avrebbe chiesto. Ma va bene lo stesso, tenteremo di spiegarlo meglio che possiamo (cosa che, se non altro, dovrebbe riuscire a tenere a bada l'emozione, almeno per un po').

Iniziamo con la definizione di due costanti: BcdLibraryString_Description e Current. BcdLibraryString_Description fa riferimento all'oggetto da recuperare; in questo caso, l'oggetto contiene la proprietà Description (il nome) del sistema operativo corrente.

Per inciso, questa è una delle simpatiche stravaganze prodotte dal lavoro con il provider BCD. In genere, non si recupera soltanto il valore di una proprietà; al contrario, si usa uno dei valori delle costanti (e il metodo GetElement) per recuperare un altro oggetto, quindi si restituisce il valore di una proprietà che appartiene all'oggetto. È di certo un po' sciocco, ma sapete come si dice: arrivare è la metà del divertimento.

Nota Cosa che comunque ti fa chiedere dove stessero andando, no?

Quanto alla costante Current, si tratta soltanto di un GUID che rappresenta il sistema operativo utilizzato al momento. Il valore

 {fa926493-6f1c-4193-a414-58f0b-2456d1e} 

viene considerato un GUID "noto a tutti" (cosa che, se non altro, prova che le persone che lavorano in Microsoft sono davvero dotate di senso dell'umorismo).

Benché si tratti di un GUID noto a tutti, siamo andati avanti e ne abbiamo comunque incluso il valore, nel caso in cui qualcuno dei nostri lettori avesse problemi nel ricordare quale dei due valori seguenti è quello corretto:

{fa926493-6f1c-4193-a414-58f0b2456d1e} 
{fa926493-6f1c-4193-a414-58f0b2456d1f}

Nota In caso qualcuno si ponesse il quesito, GUID può essere pronunciato sia "gwid" sia "guu-aidi". Possiamo dire di più, come il fatto che il GUID di cui sopra deve essere un GUID V1, visto che il terzo gruppo di cifre inizia con 4. Ma abbiamo promesso di non esagerare con le emozioni. E noi le promesse le manteniamo.

Come si può immaginare, quando si lavora con il provider BCD è necessario utilizzare costanti, valori esadecimali e GUID praticamente ovunque. Non possiamo trattare tutti questi argomenti nella rubrica di questo mese, ma per un approfondimento consigliamo la consultazione della pagina di MSDN® sui BCD già citata in precedenza (disponibile all'indirizzo go.microsoft.com/fwlink/?LinkId=116953, in inglese). Questo sempre che riusciate a sopportare le emozioni forti.

Dopo aver definito le due costanti, stabiliamo la connessione al servizio WMI nel computer locale. Si può utilizzare lo script per recuperare i dati configurazione di avvio di un computer remoto? Certo che si può.

A dire il vero, se la cosa non fosse possibile questo affare dei BCD non varrebbe granché. Per recuperare i dati configurazione di avvio di un computer remoto (nel quale, ripetiamo, devono essere installati Windows Vista o Windows Server 2008), è sufficiente assegnare il nome del computer alla variabile strComputer:

strComputer = "atl-fs-001"

Vale anche la pena sottolineare un paio di elementi fondamentali nella stringa di connessione a WMI. Per prima cosa, qualcuno avrà notato che nella stringa di connessione sono stati inclusi i privilegi Backup e Restore; questo è ciò che avviene con la costruzione {(Backup,Restore)}. È qualcosa di importante? Per chi vuole che lo script funzioni è una cosa molto importante: se i due privilegi non vengono esplicitamente inclusi, lo script non riesce.

Secondo, notare che non è stato connesso lo spazio dei nomi root\cimv2, ovvero lo spazio dei nomi più comunemente utilizzato negli script di amministrazione del sistema. Piuttosto, abbiamo stabilito la connessione allo spazio dei nomi root\WMI e l'associazione direttamente alla classe BCDStore. Ecco a cosa serve questa parte di codice:

"\root\wmi:BcdStore" 

E no, la parte emozionante non era questa; quella deve ancora venire.

Sebbene da qualche parte potrebbero esserci una o due eccezioni, nella maggior parte dei casi uno script BCD viene avviato con gli stessi tre passaggi: definizione delle costanti, definizione della connessione al servizio WMI e quindi apertura dell'archivio BCD. I Passaggi 1 e 2 li abbiamo già completati e la seguente riga di codice si occupa del Passaggio 3:

objStoreClass.OpenStore "", objStore

Come già detto, qui viene aperto l'archivio BCD, ovvero l'entità del sistema operativo in cui sono archiviate tutte le informazioni sulla configurazione di avvio. Per aprire l'archivio è sufficiente chiamare il metodo OpenStore, passando al metodo due parametri:

  • una stringa vuota (""), che serve per indicare allo script che vogliamo aprire l'archivio predefinito;
  • objStore. Si tratta di un parametro "esterno" che forniamo allo script. Diamo al metodo il nome di una variabile e, come segno di gratitudine, il metodo restituisce un oggetto (in questo caso, un oggetto che rappresenta l'archivio BCD) che utilizza il nome della variabile come riferimento a un oggetto.

Non appena l'archivio è aperto, possiamo utilizzare il metodo OpenObject per recuperare un altro oggetto ancora (archiviato nel parametro esterno objDefault):

objStore.OpenObject Current, objDefault

Qual è questo nuovo oggetto? Proprio così: è il sistema operativo attualmente in uso. Questo lo sappiamo perché abbiamo passato a OpenObject la costante Current, il GUID noto a tutti che rappresenta il sistema operativo corrente.

OK, ora sappiamo qual è il sistema operativo attualmente in uso nel computer, giusto? Quasi, non proprio. Per ottenere quella informazione, dobbiamo ancora utilizzare GetElement per recuperare un oggetto che rappresenti la proprietà Description del sistema operativo:

objDefault.GetElement _
  BcdLibraryString_Description, objElement

Ora, promettete di non esaltarvi troppo e di non lasciarvi andare a qualche genere di scorribanda collettiva? Bene. In tal caso, è tempo di rivelare che possiamo definire la restituzione del valore della proprietà String e, finalmente, stabilire qual è il sistema operativo attualmente in uso nel computer:

Wscript.Echo "Current operating system: " _
  & objElement.String

Per favore, bisogna rimanere calmi. E ricordare le promesse: niente scorribande collettive. Sì, lo sappiamo che è difficile, ma bisogna provarci lo stesso. Ad esempio respirando profondamente: è un sistema che con noi funziona sempre quando scriviamo gli script BCD.

Come già detto, si tratta di un'attività di scrittura complessa soltanto per stabilire il sistema operativo attualmente in uso in un computer; ci sono senz'altro modi più facili per raggiungere lo stesso risultato. Tuttavia, il lato positivo della questione è che abbiamo avuto occasione di chiarire il funzionamento di uno script BCD. Il che significa che i lettori ora possono fare alcune cose che gli autori di script non hanno mai potuto fare. (Calma, bisogna continuare a mantenere la calma). Ad esempio, in un computer ad avvio multiplo, uno dei sistemi operativi è sempre etichettato come quello "predefinito"; perciò, in caso di riavvio, se nessuno indica al computer un'azione diversa verrà caricato automaticamente il sistema operativo predefinito. Prima di Windows Vista (e del provider BCD), un autore di script non aveva modo di stabilire il sistema operativo predefinito di un computer. Oggi, invece, per farlo è sufficiente eseguire uno script come quello mostrato nella Figura 2.

Figura 2 Determinazione del sistema operativo predefinito

Const BcdLibraryString_Description = &h12000004
Const BootMgrId = "{9dea862c-5cdd-4e70-acc1-f32b344d4795}"
Const DefaultType = &h23000003

strComputer = "." 

Set objStoreClass = GetObject("winmgmts:{(Backup,Restore)}\\" & _
    strComputer & "\root\wmi:BcdStore")
objStoreClass.OpenStore "", objStore

objStore.OpenObject BootMgrId, objBootMgr 

objBootMgr.GetElement DefaultType, objDefaultOSIdentifier
objStore.OpenObject objDefaultOSIdentifier.Id, objDefault

objDefault.GetElement BcdLibraryString_Description, objElement 
WScript.Echo "Default operating system: " & objElement.String

È vero: questo è un motivo sufficiente per una piccola scorribanda collettiva. Va bene, ma solo un po', OK? Stavolta non scenderemo troppo nei dettagli per illustrare questo script; partendo dal presupposto che nessuna parte dei precedenti 10 o 12 paragrafi sia stata ignorata, non dovrebbe essere impossibile seguire la logica che lo caratterizza. Si noterà, tuttavia, che per ottenere il sistema operativo predefinito dobbiamo avvalerci di un passaggio intermedio: dobbiamo utilizzare il metodo OpenObject per aprire un'istanza dell'oggetto Boot Manager. Una volta aperto Boot Manager, possiamo utilizzare la costante DefaultType per recuperare un oggetto che rappresenti il sistema operativo predefinito.

E questo, bisogna ammetterlo, è abbastanza emozionante: possiamo determinare il sistema operativo corrente e possiamo anche determinare il sistema operativo predefinito. Ma la cosa più bella di tutte sarebbe recuperare un elenco di tutti i sistemi operativi installati in un computer. Quello sì che sarebbe emozionante! Allora, è tempo di allacciare le cinture di sicurezza e osservare la Figura 3.

Cosa stiamo facendo? Tanto per iniziare, stiamo definendo due costanti nuove: WindowsImages, che consente di recuperare le istanze di tutti i sistemi operativi che supportano i BCD (cioè, Windows Vista and Windows e 2008); e LegacyImages, che consente di recuperare le istanze di tutti i sistemi operativi "legacy" presenti nel computer. Dopo la connessione all'archivio BCD, utilizziamo il metodo EnumerateObjects per recuperare tutte le istanze dei sistemi operativi dotati di supporto dei BCD installati nel computer:

objStore.EnumerateObjects _
  WindowsImages, colObjects 

Figura 3 Rilevamento di tutti i sistemi operativi in un computer

Const BcdLibraryString_Description = &h12000004
Const WindowsImages = &h10200003
Const LegacyImages = &h10300006

strComputer = "."

Set objStoreClass = GetObject("winmgmts:{(Backup,Restore)}\\" & _
 strComputer & "\root\wmi:BcdStore")

objStoreClass.OpenStore "", objStore 

objStore.EnumerateObjects WindowsImages, colObjects 

For Each objObject in colObjects
 objObject.GetElement BcdLibraryString_Description, objElement 
 Wscript.Echo objElement.String
Next
Wscript.Echo

objStore.EnumerateObjects LegacyImages, colObjects 

For Each objObject in colObjects
 objObject.GetElement BcdLibraryString_Description, objElement 
 Wscript.Echo objElement.String
Next

Una volta che EnumerateObjects ha completato il suo lavoro, impostiamo un ciclo For Each per scandire tutti i sistemi operativi presenti nella raccolta. All'interno del ciclo utilizziamo le due righe di codice seguenti per recuperare e visualizzare la proprietà Description del sistema operativo:

objObject.GetElement _
  BcdLibraryString_Description, objElement 
Wscript.Echo objElement.String

Quindi ripetiamo il processo con tutti i sistemi operativi legacy installati nel computer:

objStore.EnumerateObjects _
  LegacyImages, colObjects 

For Each objObject in colObjects
 objObject.GetElement _
  BcdLibraryString_Description, objElement 
 Wscript.Echo objElement.String
Next

Nota Capiamo bene l'eccitazione che questo comporta, ma si devono eseguire gli script BCD con prudenza; con ogni probabilità esiste solo un determinato numero di scariche di adrenalina che il corpo umano può sopportare. Le donne incinta, o che possono rimanere incinta, o che non potrebbero mai rimanere incinta, o che una volta sono rimaste incinta, o che in fondo non sono neanche donne perché di fatto sono uomini non dovrebbero eseguire gli script BCD senza prima consultare il proprio medico curante.

Va bene, d'accordo, si può fare a meno di consultare il medico. Però sarebbe interessante sapere che ne pensa un medico a proposito dell'esecuzione degli script BCD. O no?

Ora cercheremo di fare qualcosa di veramente pazzo: vediamo se riusciamo a modificare il sistema operativo predefinito. Ad esempio, supponiamo di avere un computer ad avvio doppio in cui sono installati sia Windows Vista che Windows Server 2008. E supponiamo di voler impostare Windows Vista come sistema operativo predefinito. Come si fa? Basta osservare la Figura 4, in cui viene mostrato come eseguire questa attività.

Figura 4 Modifica del sistema operativo predefinito

Const BootMgrId = "{9dea862c-5cdd-4e70-accl-f32b344d4795}"
Const BcdLibraryString_Description = &h12000004
Const DefaultType = &h23000003
Const WindowsImages = &h10200003

strComputer = "."

Set objStoreClass = GetObject("winmgmts:{(Backup,Restore)}\\" & _
 strComputer & "\root\wmi:BcdStore")

objStoreClass.OpenStore "", objStore 
objStore.EnumerateObjects WindowsImages, colObjects 

For Each objObject in colObjects
 objObject.GetElement BcdLibraryString_Description, objElement 
 If Instr(objElement.String, "Vista") Then
  objStore.OpenObject BootMgrId, objBootMgr 
  objBootMgr.SetObjectElement DefaultType, objObject.ID 
 End If
Next

Con questo script apriamo di nuovo l'archivio BCD, quindi utilizziamo EnumerateObjects per recuperare una raccolta di tutti i sistemi operativi che riconoscono i BCD installati nel computer. A quel punto, impostiamo un ciclo For Each per scandire tutti gli elementi della raccolta, utilizzando la riga di codice seguente (e ormai familiare) per recuperare la proprietà Description di ciascun sistema operativo:

objObject.GetElement _
  BcdLibraryString_Description, objElement

Non appena disponiamo del nome di un dato sistema operativo, utilizziamo la funzione InStr per vedere se all'interno del valore compare la parola Vista:

If Instr(objElement.String, "Vista") Then

È vero, sembra un po' goffo. Il modo elegante sarebbe quello di utilizzare il GUID di Windows Vista per poi aprirne direttamente il sistema operativo, senza dover enumerare e scandire tutti i sistemi operativi nel computer.

Purtroppo, il modo elegante richiede la conoscenza del GUID di Windows Vista. Invece, in questo modo non è necessario sapere niente (cosa sempre gradita agli Scripting Guy); tutto ciò che dobbiamo fare è continuare a cercare fino a trovare un sistema operativo contenente la parola Vista nel titolo.

Nota Che fare se nel computer sono installate più istanze di Windows Vista? In quel caso, sarà necessario cercare stringhe come Vista Ultimate o Vista Enterprise.

Non appena troviamo Windows Vista, utilizziamo le due righe di codice seguenti per aprire Windows Boot Manager e impostare il sistema operativo predefinito su Windows Vista, appunto:

objStore.OpenObject BootMgrId, objBootMgr 
objBootMgr.SetObjectElement _
  DefaultType, objObject.ID 

È finito il tempo a disposizione, per questo mese. Dopo tutto, neanche gli Scripting Guy riescono a sopportare le emozioni continue, 24 al giorno per 7 giorni la settimana. Ma non c'è da preoccuparsi: torneremo il mese prossimo con una nuova esaltante puntata di Hey, Scripting Guy! Con un po' di fortuna, per allora tutti si saranno ripresi.

Il rompicapo di script del Dottor Scripto

La sfida mensile che verifica non solo l'abilità nella risoluzione dei puzzle, ma anche le competenze di scripting.

Luglio 2008: i quadrati di VBScript

D'accordo, probabilmente sono rettangoli, non quadrati, ma non è questo il punto. Per risolvere il puzzle, inserire ognuno dei quadrati incolonnati sulla destra in uno dei quadrati vuoti sulla sinistra per creare i nomi di funzioni VBScript. Ogni quadrato dovrà essere utilizzato una sola volta. Ecco un esempio:

Per risolvere correttamente l'esempio, si deve spostare il quadrato (rettangolo) OU nel quadrato vuoto della prima parola e i quadrati MS e OX nei quadrati vuoti della seconda parola. Il risultato è rappresentato dalle funzioni VBScript UBound e MsgBox, come mostrato qui di seguito:

Ora prova tu:

RISPOSTA:

Il rompicapo di script del Dottor Scripto

Risposta: Quadrati di VBScript, luglio 2008

Gli Scripting Guy lavorano o, per meglio dire, sono stipendiati da Microsoft. Quando non si dedicano al baseball (o a varie altre attività) da giocatori, allenatori o semplici spettatori, gestiscono il TechNet Script Center. È possibile consultarne la pagina all'indirizzo www.scriptingguys.com (in inglese).

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