Hé, vous le scripteur !Secrets de gestion des ordinateurs de bureau d'outre-tombe

Les scripteurs Microsoft

Télécharger le code de cet article: HeyScriptingGuy2007_11.exe (151KB)

À la demande générale, nous avons voulu ce mois-ci faire quelque chose d'un peu différent : au lieu de commencer par parler de scripts d'administration système, nous allons commencer par (envoyez la musique sinistre) vous raconter une histoire de fantômes !

Remarque : Techniquement parlant, si nous voulions vraiment faire quelque chose de vraiment différent ce mois-ci, nous commencerions par parler des scripts d'administration système. Mais faites-nous confiance. Vous allez bientôt comprendre.

Il y a plusieurs années de cela, l'une des arrière-arrière-arrière-grands-mères Script mourut. Peu de temps après que Grand-mère eut été enterrée dans son cercueil en bois, Grand-père commença à faire des cauchemars terribles dans lesquels sa femme bien-aimée essayait désespérément de sortir de sa tombe à la force des ongles. Après bon nombre de cauchemars et de supplications incessantes, Grand-père réussit à convaincre les autorités locales d'exhumer le corps de sa femme. Lorsque le cercueil fut ouvert, tout le monde fut horrifié de voir que les ongles de Grand-mère étaient tordus et que l'intérieur du cercueil était couvert d'égratignures !

D'accord, cette histoire n'est peut-être pas être tout à fait vraie. En fait, à bien y réfléchir, elle n'est absolument pas vraie. Néanmoins, elle nous enseigne une leçon importante. Qu'est-ce que c'était déjà...

Ah, nous nous en souvenons maintenant ! Les cercueils étaient initialement conçus pour protéger le défunt des éléments et pour empêcher le corps de se décomposer. Malheureusement, ils avaient également une conséquence inattendue : ils permettaient, en théorie du moins, d'enterrer une personne vivante et de faire en sorte qu'elle n'en sorte jamais. Comme le montre l'histoire de l'arrière-arrière-arrière-grand-mère Script, même les projets les mieux planifiés peuvent avoir des résultats désastreux, voire entraîner l'enterrement de personnes vivantes ! (Envoyez à nouveau la musique sinistre).

Remarque : à moins, bien sûr, que vous n'optiez pour le cercueil de sécurité inventé par Franz Vester dans les années 1860. Ce cercueil incluait une ficelle reliée à une cloche placée à la surface ; dans le cas d'un enterrement prématuré, le « défunt » pouvait simplement sonner la cloche pour appeler à l'aide. Le cercueil de sécurité incluait également une échelle pliante, bien que nous ne sachions pas très bien comment une échelle pliante peut aider quelqu'un à s'échapper d'un cercueil enterré six pieds sous terre. Bien sûr, si vous êtes enterré au-dessus d'un garage, une échelle pliante peut s'avérer utile. Autrement...

La même chose (c'est-à-dire le fait que même les meilleurs plans peuvent conduire au désastre) est vraie pour les pare-feu Internet. Enfin, presque. Les pare-feu ont été initialement conçus pour empêcher l'accès aux personnes non autorisées : ils bloquent le trafic réseau entrant, empêchant ainsi les pirates informatiques et les intrus d'accéder à votre ordinateur. Tout ceci est très bien, mais, comme dans le cas de l'enterrement vivant, ils ont également une conséquence imprévue : ils peuvent également empêcher les personnes autorisées de rentrer. C'est surtout vrai dans le cas de Windows® Management Instrumentation (WMI), qui repose sur DCOM pour exécuter des tâches administratives sur les ordinateurs distants. Les pare-feu ont tendance à bloquer tout le trafic DCOM entrant, si bien qu'il est très difficile (si ce n'est carrément impossible) de gérer des ordinateurs par programmation sur Internet. En fait, sans ouvrir de ports supplémentaires sur le pare-feu et vous rendre ainsi plus vulnérable aux pirates informatiques, c'est franchement impossible. À moins que, bien sûr, que vous n'optiez pour WinRM : la Gestion à distance de Windows (échelle pliante non incluse).

Qu'est-ce que la Gestion à distance de Windows ?

D'après le kit de développement WinRM (msdn2.microsoft.com/aa384426), la Gestion à distance de Windows est « la mise en œuvre par Microsoft du protocole WS-Management, protocole standard SOAP compatible avec les pare-feu qui permet au matériel et aux systèmes d'exploitation de différents fournisseurs d'interfonctionner ». Impressionnant, n'est-ce pas ? Nous n'aborderons pas les détails du protocole WS-Management dans l'article de ce mois, mais nous vous recommandons de lire le kit de développement WinRM pour plus d'informations. Pour le moment, il vous suffit de savoir que WinRM est disponible sur Windows Server® 2003 R2, Windows Vista® et Windows Server 2008, et qu'il vous permet de gérer des ordinateurs sur Internet. WinRM utilise pour cela le port 80, un port de services Internet standard que la plupart des pare-feu laissent ouvert (cependant, le port utilisé par WinRM et le mécanisme de transport par défaut, HTTP, peuvent être modifiés si besoin est).

Nous ne nous attarderons pas non plus dans cet article sur l'installation et la configuration de WinRM. Il y a déjà toute une foule d'informations disponibles à ce propos (msdn2.microsoft.com/aa384372). Cependant, j'aimerais tout de même souligner un point important : si vous voulez utiliser WinRM pour récupérer des informations depuis un ordinateur distant (ce qui est la raison principale de l'utilisation de WinRM), votre ordinateur local et l'ordinateur distant doivent tous deux exécuter WinRM.

Qu’est-ce que cela signifie ? Cela signifie que si vous n'avez pas mis à niveau vos ordinateurs clients vers Windows Vista (j'espère que ce n'est pas le cas), ou si vous n'avez pas mis à niveau vos serveurs vers Windows Server 2003 R2 ou Windows Server 2008, vous ne trouverez pas WinRM particulièrement utile, du moins pas pour l'instant. Il va de soi, cependant, que cela ne sera probablement pas le cas à l'avenir. De plus, en supposant bien entendu que votre pare-feu l'autorise, vous toujours pouvez utiliser WMI et DCOM pour gérer des ordinateurs distants.

Renvoi de toutes les propriétés et instances d'une classe

Mais pourquoi se soucier des avertissements et des avis de non-responsabilité ? Au lieu de tout ce jargon obscur, voyons si nous pouvons écrire un script qui tire parti de WinRM. Justement, il se trouve que nous disposons d'un petit script simple qui utilise le protocole HTTP et le port 80 pour se connecter à un ordinateur nommé atl-fs-01.fabrikam.com, puis renvoie des informations complètes sur tous les services installés sur cet ordinateur. Reportez-vous à la figure 1 pour voir le script dans toute sa splendeur.

Figure 1 Composants d'un projet Silverlight

Fichier Description
CreateSilverlight.js Il s'agit d'un script JScript (dans sa version initiale, Silverlight ne prend en charge que les scripts JScript) servant à spécifier les paramètres initiaux de démarrage de Silverlight, y compris le fichier XAML utilisé pour configurer l'interface utilisateur et les objets graphiques.
SampleProject.js Il s'agit simplement d'un fichier blanc où vous pouvez mettre des fonctions JScript.
Silverlight.js Ce fichier sert à initialiser la commande Silverlight.
SampleProject.html C'est le fichier le plus excitant. SampleProject.html est simplement un fichier HTML qui inclut le code de lecture des trois fichiers .js. Il inclut également le code permettant d'instancier la commande Silverlight.
SampleProject.xaml À quoi est-ce que cela sert ? Pour le découvrir, il faut que vous reveniez à la partie principale de cette rubrique.
   

Figure 1 Affichage d'une liste de services sur un ordinateur distant

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

Comme vous pouvez le voir, nous commençons par attribuer le nom DNS de l'ordinateur (atl-fs-01.fabrikam.com) à une variable appelée strComputer. Nous pourrions éventuellement effectuer la connexion en utilisant l'adresse IP de l'ordinateur (ou même son adresse IPv6). Par exemple :

strComputer = "192.168.1.1"

Après avoir attribué une valeur à strComputer, nous créons une instance de l'objet WSMan.Automation, puis nous appelons la méthode CreateSession pour nous connecter à l'ordinateur distant, en utilisant dans ce cas le protocole HTTP (exactement comme nous l'avions prévu) :

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

Comme nous l'avons dit, nous voulons renvoyer les informations sur les services installés sur l'ordinateur distant. De plus, et au moins pour ce premier exemple, nous voulons des informations sur toutes les propriétés de tous les services. Qu’est-ce que ça signifie ? Cela signifie que nous devons spécifier une ressource URI qui nous lie à la classe Win32_Service sur l'ordinateur distant :

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

D'accord, ce n'est pas la ressource URI la plus avenante qu'on ait jamais vue (mais à bien y réfléchir, nous ne nous souvenons pas avoir jamais rencontre une URI avenante). Heureusement, l'essentiel de l'URI est passe-partout ; tout ce dont vous devez vous soucier est le chemin de WMI tout à la fin :

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

Cela devrait être assez simple. Que se passe-t-il si vous voulez vous connecter à la classe root/cimv2/Win32_Process ? Et bien, il suffit de modifier le chemin de l'URI en conséquence :

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

Vous voulez utiliser la classe root/default/SystemRestore ? Encore une fois, il suffit de modifier la classe URI, en prenant soin de spécifier l'espace de noms par défaut (au lieu de l'espace de noms cimv2) :

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

Et ainsi de suite. Dommage qu'il faille inclure la partie https://schemas.microsoft.com/wbem/wsman/1/wmi de l'URI...

À ce stade nous sommes prêts à recevoir certaines données en retour. Pour cela, il nous suffit d'appeler la méthode Enumerate, en utilisant la variable strResource comme unique paramètre de méthode :

Set objResponse = _
  objSession.Enumerate(strResource)

Cette ligne de code peut-elle vraiment remplir objResponse avec des informations sur les services installés sur l'ordinateur atl-fs-01 ? Absolument. Cependant, contrairement aux scripts WMI standard, vous ne recevez pas une série d'objets, chacun avec ses propres propriétés et méthodes de propriété. Au lieu de cela, vous recevez un seul blob XML qui ressemble un peu à ce que vous pouvez voir à la figure 2.

Figure 2 Jolies couleurs

<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 Blob 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

Si vous êtes un as du XML, cela n'est pas un problème ; quiconque connaissant bien XML devrait pouvoir analyser et traiter ces informations sans trop de difficultés (bien que, d'après le kit de développement WinRM, ces informations ne soient pas dans « format lisible »). Mais qu'en est-il si vous n'êtes pas un as du XML ? Dans ce cas, vous avez deux choix. Soit vous attendez jusqu' au mois prochain, lorsque nous vous montrerons quelques astuces pour travailler avec le XML de WinRM, soit vous faites ce que nous avons fait dans notre exemple de script : vous utilisez la transformation XSL qui est installée avec WinRM.

La transformation quoi ?

Une transformation XSL n'est rien de plus qu'un modèle qui décrit comment un fichier XML doit être affiché. Une explication, même superficielle, sur les fichiers XSL dépasserait le cadre de l'article de ce mois. Par conséquent, nous n'essaierons pas d'expliquer comment WsmTxt.xsl (nom de la transformation intégrée) fonctionne. Nous allons plutôt vous montrer comment vous pouvez utiliser cette transformation dans votre script.

Lorsque vous appelez la méthode Enumerate, WinRM renvoie un flux de données XML. La façon la plus facile de travailler avec ces données est de configurer une boucle Do Until qui continue à s'exécuter jusqu'à ce que vous atteigniez la fin du flux de données. C'est ce que nous faisons ici :

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

Comme vous pouvez le voir, dans notre boucle, nous appelons une sous-routine appelée DisplayOutput. Lorsque nous appelons cette sous-routine, nous transmettons la valeur de la méthode ReadItem du flux comme paramètre de la sous-routine (comme l'implique cette approche, le flux XML est renvoyé sous forme d'éléments séparés au lieu d'un seul blob de données. Notre script lit également les données XML un élément à la fois).

La sous-routine DisplayOutput a l'aspect suivant :

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

En bref, nous commençons par créer deux instances de l'objet MSXml2.DOMDocument.3.0. Nous chargeons le flux de données XML (strWinRMXML) dans un objet, puis nous chargeons le fichier XSL (WsmTxt.xsl) dans l'autre objet. À ce stade, nous appelons la méthode TransformNode pour utiliser les informations du fichier XSL afin de formater et d'afficher les données reçues du flux XML.

Oui, c'est un peu compliqué. Mais au moins la sortie (bien que loin d'être parfaite) est un peu plus facile à lire (voir figure 3).

Figure 3 Peindre un texte

<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 Une version plus propre du fichier 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.

Comme nous l'avons déjà dit, c'est bien, mais ce n'est pas parfait, ce qui constitue une raison de plus pour lire l'article du mois prochain, où nous vous montrerons des façons de manipuler vous-même la sortie XML.

Renvoi d'instances et de propriétés sélectionnées d'une classe

Tout cela est très bien, à l'exception d'une chose : il se peut que cela ne reflète pas entièrement votre façon de travailler. Parfois, vous aurez besoin de renvoyer toutes les propriétés de toutes les instances d'une classe, et à d'autres moments vous aurez besoin de renvoyer uniquement certaines propriétés ou instances données d'une classe. Par exemple, vous pourriez vouloir renvoyer uniquement les informations sur les services en cours d'exécution, chose que vous faites dans un script WMI normal en utilisant un code du type :

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

Bon d'accord. Mais comment allez-vous modifier votre chaîne de ressource pour qu'elle soit équivalente à ce code ?

Et bien, pour être parfaitement honnête, vous ne pouvez pas modifier votre chaîne de ressource pour la rendre équivalente à l'instruction ExecQuery. Vous devrez absolument modifier la chaîne de ressource, mais vous devrez également effectuer d'autres actions.

Observons la figure 4 tout en gardant cela à l'esprit. Il s'agit d'un script WinRM qui renvoie des informations sur les services en cours d'exécution sur un ordinateur (par opposition à tous les services installés sur cet ordinateur).

Figure 4 Astuces pour 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 Recherche des services en cours d'exécution

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

À première vue, ce script peut paraître identique au premier script WinRM que nous vous avons montré. Cependant, il y a quelques différences très importantes. Tout d'abord, examinez la valeur que nous attribuons à la chaîne de ressource :

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

Notez que dans la requête filtrée, nous ne spécifions pas le nom réel de la classe (Win32_Service) que nous voulons utiliser ; au lieu de cela, nous nous connectons simplement à l'espace de noms (root/cimv2) où cette classe réside. N'oubliez pas de placer l'astérisque (*) à la fin. Si vous ne le faites pas, le script échoue avec le message «... the class name must be '*' (star) » (... le nom de classe doit être * (étoile)), qui signifie simplement que vous devez définir le nom de classe sur *.

Nous devons en outre également définir un filtre et un dialecte :

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

Le filtre devrait être assez facile à déterminer ; c'est là que se trouve la requête Windows Management Instrumentation Query Language ou WQL ("Select * From Win32_Service Where State = 'Running'"). Le dialecte, lui, est le langage de requête utilisé lors de la création du filtre. Pour l'instant, un seul langage de requête est autorisé : WQL. Néanmoins, le dialecte doit être spécifié, sinon le script échoue avec un message indiquant que « filter dialect ... is not supported. » (le dialecte de filtre... n'est pas pris en charge.).

Remarque : il est intéressant de noter que le message d'erreur suggère de supprimer le dialecte lorsque vous appelez la méthode Enumerate. C'est une recommandation à ne pas suivre. Lors de la création d'une requête filtrée, le dialecte doit être spécifié et doit être WQL. Il n'y a pas d'exception.

Le seul autre changement que nous devons apporter intervient au moment de l'appel de la méthode Enumerate. À ce stade, nous devons transmettre les variables représentant le filtre (strFilter) et le dialecte (strDialect), ainsi que la variable représentant la ressource (strResource) :

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

Faites un essai et voyez ce que vous obtenez.

Maintenant, comment faire pour renvoyer uniquement certaines propriétés données d'une classe ? Par exemple, supposons que vous vouliez renvoyer uniquement les propriétés Name et DisplayName de tous les services exécutés sur un ordinateur. Que se passe-t-il alors ?

Dans un cas comme celui-ci, vous pouvez essayer de manipuler le fichier XML pour que seules les propriétés Name et DisplayName s'affichent. Bien que cela soit faisable, c'est un peu compliqué. Une méthode plus facile consiste à spécifier uniquement ces propriétés lors de l'attribution du filtre :

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

Vous recevez ainsi les propriétés Name et DisplayName de chaque service, comme indiqué ci-dessous :

XmlFragment
    DisplayName = Windows Event Log
    Name = EventLog

XmlFragment
    DisplayName = COM+ Event System
    Name = EventSystem

Certes, le formatage semble un peu bizarre (qu'est-ce que cette histoire de XmlFragment ?). Voilà une nouvelle raison de lire notre article du mois prochain.

Vous verrez !

Avec un peu de chance, vous pourrez commencer à faire des merveilles avec WinRM. Nous ne pouvons cependant pas terminer un article sur WinRM sans mentionner les « morgues temporaires » autrefois courantes à travers l'Allemagne. Dans les villes qui avaient des morgues temporaires, les cadavres n'étaient pas été enterrés tout de suite. Ils étaient placés dans des pièces chauffées avec un certain nombre de ficelles et de fils attachés à leurs doigts et orteils. L'idée, bien sûr, était que le moindre mouvement déclenchait une alarme pour appeler à l'aide. Les corps étaient conservés dans ces morgues jusqu'à ce que leur état ne fasse plus de doute.

A bien y songer, une morgue temporaire est un peu comme être assigné à l'équipe de scripteurs, non ? La seule différence est que personne n'est jamais revenu à la vie dans les morgues, alors que les personnes assignées à l'équipe des scripteurs...

Les scripts embrouillés du Dr. Scripto

En juin 2007, les scripteurs ont assisté à la conférence Tech•Ed 2007 à Orlando, en Floride. Non contents d'assister simplement à la conférence, nous avons décidé de nous amuser un peu. Non seulement cela, mais nous avons en plus pensé que tout le monde avait besoin de se divertir un peu. C'est dans cet esprit que nous avons inventé Dr. Scripto's Fun Book, un petit livre d'énigmes ayant trait aux scripts et divers autres éléments d'information. Nous nous sommes associés à TechNet Magazine (où plutôt nous les avons persuadés de nous laisser utiliser une partie de leur stand dans le hall d'exposition) et nous avons distribué des copies de ce livre aux gens qui passaient.

Il se trouve qu'il a eu beaucoup de succès (peut-être pas autant que la figurine à tête branlante du Dr. Scripto, mais presque). Les gentils opportunistes de TechNet Magazine, décelant une nouvelle occasion d'exploiter le succès des scripteurs (qui eux ne semblent jamais pouvoir exploiter leur propre succès), nous ont alors demandé de créer des énigmes pour eux. Sitôt que la scripteuse Jean Ross a eu le dos tourné, le scripteur Greg Stemp a répondu « Pas de problème » ! Voici donc : Les scripts embrouillés du Dr. Scripto. Bonne chance !

Script dans le désordre

Dans cette énigme, vous devez remettre toutes les lettres de la première section dans le bon ordre pour reconstituer un script (en code VBScript). Ne vous inquiétez pas, vous ne devez pas tout déchiffrer ; il suffit simplement de déchiffrer une colonne à la fois. Les lettres de chaque colonne de la section du haut doivent être placées dans les espaces vides de la même colonne de la section inférieure. Voici un exemple :

Comme vous pouvez le voir, la colonne 1 contient les lettres S, C et T. Ces trois lettres doivent être placées dans un autre ordre dans la grille du bas. Lorsque toutes les lettres sont remises dans le bon ordre, la grille inférieure (qui doit être lue de gauche à droite) devient logique. Regardez la solution :

Vous pouvez voir que les lettres S, C et T de la colonne 1 deviennent T, S et C. Cela correspond à la première lettre de chaque mot de la phrase « The Script Center ». La vraie énigme est un peu plus difficile car elle est plus longue et que le résultat final est un script complet.

Petite astuce : le script final commence par un chemin de fichier complet, puis une analyse et affiche seulement le nom du fichier.

Bonne chance !

ANSWER:

Les scripts embrouillés du Dr. Scripto

Réponse : Script dans le désordre, novembre 2007

Dans cette énigme, vous deviez placer les caractères de chaque colonne dans les cases correctes de la grille du dessous pour que les lignes forment un script. Voici le script :

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

Voici comment il apparaît dans la grille de l'énigme :

Les scripteurs Microsoft travaillent pour (enfin, sont employés par) Microsoft. Lorsqu’ils ne sont pas en train de jouer au base-ball, d’entraîner une équipe ou de regarder un match (ou de se livrer à de multiples autres activités), ils dirigent le Script Center TechNet. Vous pouvez le vérifier vous-même sur www.scriptingguys.com.

© 2008 Microsoft Corporation et CMP Media, LLC. Tous droits réservés. Toute reproduction, totale ou partielle, est interdite sans autorisation préalable.