Hey, Scripting Guy!Gestione desktop dall'aldilà

Gli Scripting Guy di Microsoft

Scarica il codice per questo articolo: HeyScriptingGuy2007_11.exe (151KB)

A causa della domanda travolgente, si è pensato di fare qualcosa di diverso questo mese: anziché iniziare parlando della creazione degli script di amministrazione del sistema, si comincerà (riprodurre la musica lugubre) raccontando una storia di fantasmi!

Nota: OK, tecnicamente, se davvero questo mese si volesse fare qualcosa di diverso, si dovrebbe iniziare subito a parlare della creazione degli script di amministrazione del sistema. Ma si può giocare un po' insieme, no? Grazie!

Molti anni fa, una delle bis-bis-bis-bisnonne degli Scripting Guy morì. Poco dopo la sua sepoltura, in una semplice bara di legno, il marito iniziò ad avere dei terribili incubi, nei quali la sua amata moglie cercava disperatamente di scavare una via d'uscita dalla fossa. Dopo vari incubi, e varie implorazioni, il marito riuscì finalmente a convincere le autorità locali a riesumare il corpo. Quando la bara venne aperta, con orrore tutti constatarono che le unghie della moglie si erano incurvate all'indietro e l'interno della bara era ricoperto di graffi!

OK, questa storia potrebbe non essere completamente vera; in effetti, a pensarci bene, sembra proprio che non lo sia per niente. Tuttavia, la storia ha una lezione importante da insegnare. Non è chiaro quale sia, ma da qualche parte c'è una lezione.

Ah, un secondo, eccola qua: originariamente, le bare erano concepite per proteggere il deceduto dagli elementi e aiutare a impedire la decomposizione del corpo. Purtroppo però hanno avuto una conseguenza involontaria: consentono, almeno in teoria, di seppellire una persona viva e assicurarsi che non riesca a uscire. Come dimostra chiaramente la storia della bis-bis-bis-bisnonna degli Scripting Guy, anche i piani meglio preordinati da uomini e mouse possono causare disastri e persone sepolte vive (riprodurre un'altra volta la musica lugubre)!

Nota: a meno che, naturalmente, non si preferisca la bara inventata da Franz Vester negli anni '60 del 1800. Si trattava di una versione migliorata, contenente una cordicella collegata a una campana, che rimaneva in superficie; nel caso di una sepoltura prematura, il "deceduto" poteva semplicemente far suonare la campana per chiedere aiuto. La bara migliorata comprendeva anche una scala pieghevole, benché non sia ovvio come tale dispositivo possa aiutare a uscire da una bara sepolta due metri sottoterra. Certo, se capitava di essere seppelliti sul tetto di un garage, una scala pieghevole poteva essere utile. In caso contrario...

La stessa cosa (ovvero il fatto che i piani meglio preordinati possano condurre a disastri) è vera per i firewall di Internet (almeno in un certo senso). Originariamente, i firewall erano concepiti per impedire l'accesso ai malintenzionati: bloccano il traffico di rete in entrata, contribuendo a tenere hacker e intrusi lontani dai computer. Ciò è molto positivo ma, come per il problema di essere seppelliti vivi, implica una conseguenza involontaria: il firewall può escludere anche gli utenti con buone intenzioni. Questo è vero soprattutto nel caso di Strumentazione gestione Windows®, che si affida a DCOM per eseguire attività amministrative sui computer remoti. I firewall tendono a bloccare tutto il traffico DCOM in entrata, il che rende estremamente difficile (se non impossibile) gestire i computer su Internet a livello di programmazione. In effetti, senza aprire porte aggiuntive sul firewall, diventando in tal modo più vulnerabili per hacker e cracker, ciò è impossibile. A meno che, ovviamente, non si scelga WinRM: Gestione remota Windows (la scala pieghevole non è inclusa).

Cos'è Gestione remota Windows?

Secondo WinRM SDK (msdn2.microsoft.com/aa384426), Gestione remota Windows è l'implementazione Microsoft del protocollo WS-Management, un protocollo standard, basato su SOAP, di facile integrazione con i firewall, che consente all'hardware e ai sistemi operativi di diversi fornitori di interoperare. Notevole, no? Non verranno discussi i dettagli del protocollo WS-Management nell'articolo di questo mese, quindi per tali informazioni si consiglia di leggere WinRM SDK. Per il momento, è importante sapere che WinRM è disponibile in Windows Server® 2003 R2, Windows Vista® e Windows Server 2008 e che consente di gestire i computer su Internet. WinRM opera tramite la porta 80, una porta per servizi Internet standard che la maggior parte dei firewall lascia aperta (comunque la porta utilizzata da WinRM e dal metodo di trasporto predefinito, HTTP, può essere modificata come necessario).

Inoltre, nell'articolo di questo mese, non verrà illustrato come installare e configurare WinRM. A tale scopo, sono già disponibili informazioni abbondanti (msdn2.microsoft.com/aa384372). Tuttavia, è necessario dedicare un momento per sottolineare un punto importante: se si desidera utilizzare WinRM per recuperare informazioni da un computer remoto (il che, naturalmente, è il motivo principale per ricorrere a WinRM), sia il computer locale che quello remoto devono eseguire WinRM.

Cosa significa? Beh, significa che se non è ancora stato eseguito l'aggiornamento dei computer client a Windows Vista (ma non è così, vero?) o dei server a Windows Server 2003 R2 o a Windows Server 2008, WinRM non sarà molto utile, almeno non oggi. Inutile dire, comunque, che probabilmente non sarà così domani (e certo, supponendo che il firewall lo consenta, è sempre possibile utilizzare WinRM e DCOM per gestire i computer remoti).

Restituzione di tutte le proprietà e istanze di una classe

Ma a chi interessano le avvertenze e le dichiarazioni di non responsabilità? Invece di perdere tempo con discorsi inutili e confusi, è il momento di provare a escogitare un modo per scrivere uno script che sia in grado di avvantaggiarsi di WinRM. Per iniziare, ecco un piccolo, semplice script che, utilizzando il protocollo HTTP e la porta 80, si connette a un computer denominato atl-fs-01.fabrikam.com e restituisce informazioni complete su tutti i servizi installati in tale sistema. Vedere la Figura 1 per lo script in tutta la sua gloria.

Figure 1 Componenti del progetto Silverlight

File Descrizione
CreateSilverlight.js È uno script JScript (nella versione iniziale Silverlight supporta solo script JScript) utilizzato per specificare le impostazioni di avvio iniziali di Silverlight, compreso il file XAML utilizzato per configurare l'interfaccia utente e gli oggetti grafici.
SampleProject.js Un file vuoto in cui è possibile inserire le funzioni JScript.
Silverlight.js Questo file viene utilizzato per inizializzare il controllo Silverlight.
SampleProject.html Il file che contiene la parte più divertente. SampleProject.html è semplicemente un file HTML che include codice per la lettura dei tre file js. Contiene inoltre il codice per la creazione dell'istanza del controllo Silverlight.
SampleProject.xaml A che serve questo file? Per scoprirlo, è necessario tornare al testo principale dell'articolo.
   

Figure 1 Elenco dei servizi su un computer remoto

strComputer = "atl-fs-01.fabrikam.com"

Set objWRM = CreateObject("WSMan.Automation")
Set objSession = objWRM.CreateSession("http://" & strComputer)

strResource = "https://schemas.microsoft.com/wbem/wsman/1/wmi/root/cimv2/Win32_Service"

Set objResponse = objSession.Enumerate(strResource)

Do Until objResponse.AtEndOfStream
    DisplayOutput(objResponse.ReadItem)
Loop

Sub DisplayOutput(strWinRMXml)
    Set xmlFile = CreateObject("MSXml2.DOMDocument.3.0")    
    Set xslFile = CreateObject("MSXml2.DOMDocument.3.0")
    xmlFile.LoadXml(strWinRMXml)
    xslFile.Load("WsmTxt.xsl")
    Wscript.Echo xmlFile.TransformNode(xslFile)
End Sub

Come si può notare, all'inizio il nome DNS del computer (atl-fs-01.fabrikam.com) è stato assegnato a una variabile denominata strComputer. In alternativa, è possibile stabilire la connessione utilizzando l'indirizzo IP del computer (o persino il suo indirizzo IPv6). Ad esempio:

strComputer = "192.168.1.1"

Dopo l'assegnazione di un valore a strComputer, si crea un'istanza dell'oggetto WSMan.Automation, quindi viene richiamato il metodo CreateSession per connettersi al computer remoto, in questo caso utilizzando il protocollo HTTP (proprio come era stato anticipato):

Set objSession = objWRM.CreateSession _
    ("http://" & strComputer)

Come si è notato, si desidera che vengano restituite informazioni relative ai servizi installati nel computer remoto. Inoltre, e almeno per questo primo esempio, si desiderano informazioni su tutte le proprietà di tutti i servizi. Che cosa significa tutto questo? Significa che è necessario specificare una Risorsa URI che vincoli alla classe Win32_Service sul computer remoto:

strResource = _
  "https://schemas.microsoft.com" & _
  "/wbem/wsman/1/wmi/root/cimv2" & _
  "/Win32_Service"

Effettivamente non è l'URI più bello in circolazione (ma, d'altronde, riflettendoci, non è detto che esistano URI belli). Fortunatamente, tuttavia, la maggior parte dell'URI è standard; l'unico punto importante è il percorso WMI alla fine:

https://schemas.microsoft.com/wbem/wsman/1/wmi/root/cimv2/Win32_Service

Dovrebbe essere piuttosto semplice. E se si desiderasse connettersi alla classe root/cimv2/Win32_Process? Beh, in tal caso sarebbe sufficiente modificare il percorso URI di conseguenza:

https://schemas.microsoft.com/wbem/wsman/1/wmi/root/cimv2/Win32_Process

Si è interessati alla classe root/default/SystemRestore? Ancora una volta, è sufficiente modificare la classe URI, facendo attenzione a specificare lo spazio dei nomi predefinito (anziché lo spazio dei nomi cimv2):

https://schemas.microsoft.com/wbem/wsman/1/wmi/root/default/SystemRestore

E così via... È un po' un peccato dover includere anche la parte dell'URI https://schemas.microsoft.com/wbem/wsman/1/wmi, ma...

A questo punto si è pronti per ottenere alcuni dati. A tale scopo, è sufficiente richiamare il metodo Enumerate, passando la variabile strResource quale unico parametro corrispondente:

Set objResponse = _
  objSession.Enumerate(strResource)

La riga di codice popolerà effettivamente objResponse con informazioni relative ai servizi installati sul computer atl-fs-01? Lo farà senz'altro. Tuttavia, a differenza degli script WMI standard, non viene restituita una serie di oggetti, ciascuno con le sue proprietà e metodi di proprietà. Invece, si otterrà una grande, tipica massa XML che assomiglia un po' a quella riportata nella Figura 2.

Figure 2 Possibili colori da utilizzare

<Canvas
 xmlns="https://schemas.microsoft.com/client/2007"
 xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml"
 Width="800"
 Height="300">
 
 <Canvas.Background>
 <LinearGradientBrush>
 <GradientStop Color="Blue" Offset="0.0" />
 <GradientStop Color="Black" Offset="1.0" />
 </LinearGradientBrush>
 </Canvas.Background>

</Canvas>

Figure 2 Grande, tipica massa XML

<p:Win32_Service xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="
https://schemas.microsoft.com/wbem/wsman/1/wmi/root/cimv2/Win32_Service" xmlns:ci
m="http://schemas.dmtf.org/wbem/wscim/1/common" xsi:type="p:Win32_Service_Type"
xml:lang="en-US"><p:AcceptPause>false</p:AcceptPause><p:AcceptStop>false</p:Acce
ptStop><p:Caption>Windows Media Center Service Launcher</p:Caption><p:CheckPoint
>0</p:CheckPoint><p:CreationClassName>Win32_Service</p:CreationClassName><p:Desc
ription>Starts Windows Media Center Scheduler and Windows Media Center Receiver
services at startup if TV is enabled within Windows Media Center.</p:Description
><p:DesktopInteract>false</p:DesktopInteract><p:DisplayName>Windows Media Center

Per gli esperti di XML non è una novità: chiunque conosca l'XML dovrebbe essere in grado di analizzare e generare queste informazioni senza troppe difficoltà (benché, secondo WinRM SDK, questi dati non siano espressi in "formato leggibile" dagli esseri umani). Ma per chi non conosce l'XML? In tal caso sono disponibili due scelte. La prima è aspettare il mese prossimo, quando verranno illustrati alcuni trucchi per operare con l'XML di WinRM. La seconda è ripetere quanto è stato fatto nello script di esempio: utilizzare la trasformazione XSL installata unitamente a WinRM.

La trasformazione XSL?

Una trasformazione XSL è semplicemente un modello che descrive come dovrebbe essere visualizzato un file XML. Una discussione completa dei file XSL non rientra nell'ambito dell'articolo di questo mese. Del resto, anche una discussione superficiale dei file XSL andrebbe oltre i limiti del presente articolo. Pertanto non si cercherà di spiegare come funziona effettivamente WsmTxt.xsl (il nome della trasformazione incorporata). Al contrario, verrà illustrato soltanto come utilizzare la trasformazione negli script.

Quando viene richiamato il metodo Enumerate, WinRM restituisce un flusso di dati XML. Il modo più facile per operare con questi dati è impostare un ciclo Do Until che continua a essere eseguito finché non si raggiunge la fine del flusso di dati. Ecco come si procede:

Do Until objResponse.AtEndOfStream
    DisplayOutput(objResponse.ReadItem)
Loop

Come si può notare, nel ciclo viene richiamata una sottoroutine denominata DiplayOutput. Al momento di richiamare la sottoroutine, viene passato il valore del metodo ReadItem del flusso, come parametro corrispondente (come implica l'intero approccio, il flusso XML viene rinviato in porzioni separate, anziché in un'unica grande massa di dati; lo script, a sua volta, legge i dati XML in singole porzioni, o elementi).

Nel frattempo, la sottoroutine DisplayOutput assume l'aspetto seguente:

Sub DisplayOutput(strWinRMXml)
  Set xmlFile = _
    CreateObject("MSXml2.DOMDocument.3.0")    
  Set xslFile = _
    CreateObject("MSXml2.DOMDocument.3.0")
  xmlFile.LoadXml(strWinRMXml)
  xslFile.Load("WsmTxt.xsl")
  Wscript.Echo xmlFile.TransformNode(xslFile)
End Sub

In breve, si inizia creando due istanze dell'oggetto MSXml2.DOMDocument.3.0. Prima viene caricato il flusso di dati XML (strWinRMXML) in un oggetto, quindi il file XSL (WsmTxt.xsl) nell'altro oggetto. A questo punto viene richiamato il metodo TransformNode per utilizzare le informazioni nel file XSL allo scopo di formattare e visualizzare i dati raccolti dal flusso XML.

È vero, tutto questo può confondere. Ma almeno è un po' più facile leggere l'output (per quanto imperfetto) (vedere la Figura 3).

Figure 3 Applicazione di colori al testo

<TextBlock 
 Name="Test"
 FontSize="40"
 FontFamily="Georgia"
 FontWeight="Bold"
 Canvas.Top="20" 
 Canvas.Left="20"
 Text="The TechNet Script Center">

 <TextBlock.Foreground>
 <SolidColorBrush Name="test_brush" Color="red"/>
 </TextBlock.Foreground>

</TextBlock>

Figure 3 Una versione più ordinata dell'XML

Win32_Service
    AcceptPause = false
    AcceptStop = true
    Caption = User Profile Service
    CheckPoint = 0
    CreationClassName = Win32_Service
    Description = This service is responsible for loading and unloading user profiles. If this service is stopped or disabled, users will no longer be able to successfully logon or logoff, applications may have problems getting to users' data, and components registered to receive profile event notifications will not receive them.

Come si è detto, i risultati sono soddisfacenti, ma non straordinari. Proprio per questo è opportuno tornare il mese prossimo, quando verranno illustrati vari modi per manipolare l'output XML da soli.

Restituzione di istanze e proprietà selezionate di una classe

Inutile a dirsi, tutto ciò è molto interessante, tranne per un aspetto: potrebbe non riflettere completamente il tipico modo di operare del lettore. A volte si può desiderare che vengano restituite tutte le proprietà di tutte le istanze di una classe, ma altre volte, forse più spesso, è sufficiente ottenere solo proprietà o istanze selezionate di una classe. Ad esempio, potrebbe essere opportuno solo ricevere informazioni sui servizi in esecuzione. Ciò è possibile utilizzando uno script WMI regolare simile al seguente:

Set colItems = objWMIService.ExecQuery _
  ("Select * From Win32_Service " & _
   "Where State = 'Running'")

Funziona. Ma come sarà mai possibile modificare la stringa Resource per renderla equivalente?

Beh, per essere sinceri, la stringa Resource non deve essere modificata per renderla equivalente all'istruzione ExecQuery. È certamente necessario modificare la stringa Resource, ma devono essere effettuate anche altre operazioni.

Ricordando questi presupposti, si consideri la Figura 4. Si tratta di uno script WinRM che restituisce informazioni sui servizi in esecuzione su un computer (invece che su tutti i servizi installati in tale computer).

Figure 4 Suggerimenti di TextBlock

<TextBlock.Triggers>
 <EventTrigger RoutedEvent=
     "TextBlock.Loaded">
 <BeginStoryboard>
 <Storyboard>
 <DoubleAnimation
 Storyboard.TargetName="Test"
 Storyboard.TargetProperty="Opacity"
 From="0.0" To="1.0" 
 Duration="0:0:5" />
 </Storyboard>
 </BeginStoryboard>
 </EventTrigger>
</TextBlock.Triggers>

Figure 4 Individuazione dei servizi in esecuzione

strComputer = "atl-fs-01.fabrikam.com"

Set objWRM = CreateObject("WSMan.Automation")
Set objSession = objWRM.CreateSession("http://" & strComputer)

strResource = "https://schemas.microsoft.com/wbem/wsman/1/wmi/root/cimv2/*"
strFilter = "Select * From Win32_Service Where State = 'Running'"
strDialect = "https://schemas.microsoft.com/wbem/wsman/1/WQL"

Set objResponse = objSession.Enumerate(strResource, strFilter, strDialect)

Do Until objResponse.AtEndOfStream
    DisplayOutput(objResponse.ReadItem)
Loop

Sub DisplayOutput(strWinRMXml)
    Set xmlFile = CreateObject("MSXml2.DOMDocument.3.0")    
    Set xslFile = CreateObject("MSXml2.DOMDocument.3.0")
    xmlFile.LoadXml(strWinRMXml)
    xslFile.Load("WsmTxt.xsl")
    Wscript.Echo xmlFile.TransformNode(xslFile)
End Sub

A un primo sguardo, potrebbe sembrare identico al primo script WinRM illustrato, ma esistono alcune differenze molto importanti. Innanzitutto, si consideri il valore assegnato alla stringa Resource:

strResource = _
  "https://schemas.microsoft.com" & _
  "/wbem/wsman/1/wmi/root/cimv2/*"

Si noti che, nella scrittura di una query filtrata, non viene specificato il nome effettivo della classe (Win32_Service) con cui si desidera operare; al contrario, ci si connette semplicemente allo spazio dei nomi (root/cimv2) dove risiede tale classe. È importante ricordare di aggiungere l'asterisco (*) alla fine. In caso contrario lo script non riesce e un messaggio indica che il nome della classe deve essere '*' (stella), ovvero che è necessario creare il nome della classe *.

Inoltre devono essere definiti un Filtro e un Tipo:

strFilter = _
  "Select * From Win32_Service " & _
  "Where State = 'Running'"
strDialect = _
  "https://schemas.microsoft.com" & _
  "/wbem/wsman/1/WQL"

Non dovrebbe essere difficile individuare il Filtro: si trova nel punto di inserimento della query Windows Management Instrumentation Query Language (WQL) ("Select * From Win32_Service Where State = 'Running'"). Il Tipo, d'altra parte, è il linguaggio di query utilizzato per la creazione del Filtro. Attualmente è consentito solo un linguaggio di query: WQL. Tuttavia, è necessario specificare il Tipo, altrimenti lo script non riesce e viene visualizzata la nota "il tipo di filtro... non è supportato".

Nota: il messaggio di errore suggerisce di rimuovere il Tipo quando viene richiamato il metodo Enumerate. Tuttavia è consigliabile non seguire tale raccomandazione. Quando viene eseguita una query filtrata, è necessario specificare il Tipo, che deve essere WQL. Tutto qui.

L'unica altra modifica richiesta ha luogo quando viene richiamato il metodo Enumerate. A questo punto, è necessario passare le variabili che rappresentano il Filtro (strFilter) e il Tipo (strDialect), nonché la variabile della Risorsa (strResource) :

Set objResponse = _
  objSession.Enumerate _
  (strResource, strFilter, strDialect)

Provare e verificare il risultato.

Ma come restituire solo le proprietà selezionate di una classe? Ad esempio, si supponga di essere interessati a ottenere solo le proprietà Name e DisplayName di tutti i servizi in esecuzione su un computer. Cosa accadrebbe?

In un caso del genere si può provare a manipolare l'XML in modo da visualizzare solo Name e DisplayName. Ciò è possibile, ma indubbiamente non facile. Un modo più semplice per conseguire questo risultato è specificare solo le proprietà desiderate al momento di assegnare il Filtro:

strFilter = _
  "Select Name, DisplayName " & _
  "From Win32_Service " & _
  "Where State = 'Running'"

Fatto questo, si otterranno solo le proprietà Name e DisplayName per ciascun servizio:

XmlFragment
    DisplayName = Windows Event Log
    Name = EventLog

XmlFragment
    DisplayName = COM+ Event System
    Name = EventSystem

È vero, la formattazione è un po' particolare (ad esempio, cosa c'entra la parte XmlFragment?). Ragione di più per tornare il mese prossimo.

In attesa

Con un po' di fortuna, quanto è stato illustrato dovrebbe essere sufficiente per iniziare a cimentarsi con il mondo selvaggio e meraviglioso di WinRM. Certo, non è possibile concludere un articolo su WinRM senza citare gli "obitori di attesa", un tempo molto diffusi in Germania. Nelle città con gli obitori di attesa, i cadaveri non venivano seppelliti subito. Al contrario, venivano collocati in sale riscaldate con numerose cordicelle e fili collegati alle dita delle mani e dei piedi. Il presupposto era, naturalmente, che il più lieve movimento avrebbe attivato un allarme e fatto intervenire il personale. I corpi venivano tenuti negli obitori di attesa finché non era chiaro che queste persone erano veramente senza speranza e non si sarebbero più mosse.

A pensarci bene, essere ricoverati in un obitorio di attesa è molto simile a far parte del team degli Scripting Guy, no? Certo, nessuno è mai ritornato in vita in un obitorio di attesa, mentre chi è stato assegnato al team degli Scripting Guy...

Il rompicapo di script del Dottor Scripto.

A giugno 2007, gli Scripting Guy hanno assistito alla conferenza Tech•Ed 2007 di Orlando, Florida. Non contenti di assistere semplicemente alla conferenza, hanno deciso di divertirsi. Non solo, hanno pensato che sarebbe piaciuto anche ad altri. Pensando a questo, hanno trovato il Fun Book del Dottor Scripto, un opuscolo pieno di puzzle correlati agli script e varie altre informazioni. Di conseguenza si sono alleati con il team di TechNet Magazine, ovvero li hanno convinti a ospitarli in un angolo del loro stand nella sala dell'esposizione, da dove hanno distribuito copie del Fun Book ai visitatori.

Il Fun Book ha riscosso un grande successo (forse non paragonabile a quello delle bambole bobblehead del Dottor Scripto, ma abbastanza simile). I gentili e opportunisti rappresentanti di TechNet Magazine, notando un altro modo per approfittare del successo degli Scripting Guy (che peraltro non sembrano mai capaci di avvantaggiarsene loro stessi), hanno chiesto loro di creare dei puzzle. Quando la Scripting Guy Jean Ross ha voltato le spalle per un attimo, lo Scripting Guy Greg Stemp ha detto: "Certo, lo faremo!". Ed ecco il risultato: il rompicapo di script del Dottor Scripto. Buon lavoro.

Creazione di uno script rilasciando caratteri

Per risolvere il puzzle, riordinare tutte le lettere nella sezione superiore in modo da creare uno script (in VBScript). Niente paura: non è necessario riordinare lo script tutto insieme, è sufficiente procedere una colonna per volta. Le lettere in ogni colonna della sezione superiore devono riempire gli spazi della stessa colonna nella sezione inferiore. Ecco un esempio:

Come si può vedere, nella colonna 1 sono incluse le lettere S, C e T. Queste tre lettere appartengono alla griglia sottostante, in un ordine sconosciuto. Ma quando tutte le lettere vengono rilasciate nella sezione inferiore secondo l'ordine appropriato, la griglia in basso, letta da sinistra a destra, mostra una stringa logica. Uno sguardo alla soluzione:

Le lettere S, C e T nella colonna 1 si spostano in basso nell'ordine T, S e C. Queste lettere sono le iniziali delle parole "The Script Center". Il puzzle vero e proprio è un po' più difficile: in primo luogo è più lungo e poi il risultato finale è un script completo.

Suggerimento: lo script finale inizia con un percorso completo a un file, quindi lo isola e visualizza solo il nome del file.

Buona fortuna!

ANSWER:

Il rompicapo di script del Dottor Scripto.

Risposta: Creazione di uno script rilasciando caratteri, novembre 2007

In questo puzzle, è necessario rilasciare i caratteri di una colonna inserendoli nelle caselle sottostanti, in modo da creare uno script nelle righe inferiori. Ecco lo script completo:

name = "C:\Scripts\Test.txt"
arr = Split(name, "\")
index = Ubound(arr)
Wscript.Echo "Filename: " _
& arr(index)
        

Aspetto dello script nella griglia del puzzle:

Gli Scripting Guy di Microsoft lavorano o, per meglio dire, sono stipendiati da Microsoft. Quando non si dedicano al baseball (o ad altre attività) come giocatori, allenatori o semplici spettatori, gestiscono il TechNet Script Center. Consultare la pagina www.scriptingguys.com.

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