Inventaire des Service Packs Windows XP - Troisième partie - Création d'un script de déploiement

Par Les Messieurs Script de Microsoft

Le Docteur Scripto au travail

Le magasin de scripts du Docteur Scripto aborde les problèmes de script liés à l'administration du système, souvent tirés des expériences de nos lecteurs, et développe des scripts pour les résoudre. La plupart des exemples du référentiel de scripts exécutent une seule tâche, assez simple. Dans cette rubrique, en revanche, nous rassemblerons différents éléments afin d'obtenir des scripts plus complexes. Ces scripts ne seront ni complets ni infaillibles, mais vous montreront la marche à suivre pour créer des scripts à partir de modules de code réutilisables, gérer des erreurs et des codes de retour, obtenir des entrées et des sorties à partir de différentes sources, exécuter des scripts sur plusieurs ordinateurs, et effectuer d'autres opérations avec vos scripts de production.

Nous espérons que ces articles et scripts vous seront utiles – faites-nous part de votre avis, des solutions que vous proposez pour ces problèmes et des sujets que vous souhaiteriez voir publiés.

Cet article est le dernier d'une série de trois, mais surtout pas le dernier du Magasin de scripts du Docteur Scripto. Nous vous conseillons de commencer par lire les deux premiers articles de cette série :

(Remarque : nous remercions Patrick Lanfear et Tom Yaguchi pour la nouvelle présentation du Dr. Scripto.)

Sommaire,Sur cette page

De l'inventaire au déploiement : création d'un script de déploiement
Le script à la rescousse
Préparation de l'installation du Service Pack 2
Création d'un partage réseau pour les fichiers d'installation
Exécution du programme d'installation
Commentaires
Pour en savoir plus

De l'inventaire au déploiement : création d'un script de déploiement

Et si, après avoir réalisé l'inventaire des Service Packs Windows XP de votre réseau, vous pouviez effectivement installer le Service Pack 2 sur l'ensemble des clients qui n'en bénéficient pas encore ? Mais il faudrait être fou ne serait-ce que d'imaginer pouvoir écrire un tel script ! Même les plus chevronnés de nos vétérans de l'informatique sont terrifiés par l'extrême complexité de cette tâche et par l'extraordinaire maîtrise technique qu'exige sa mise en œuvre. La seule contemplation d'un tel exploit pourrait provoquer des sueurs froides à l'ingénieur système le plus courageux.

Mais vous êtes déjà allé si loin sur ce chemin tortueux que représentent WMI, ADSI et ADO... Pourquoi ne pas utiliser tout ce que vous avez appris jusqu'ici pour terminer le travail ?

Comme d'habitude, le Dr. Scripto a laissé ses pensées s'égarer vers l'inimaginable. Puis, il a commencé à écrire un bout de code, juste pour avoir une idée de ses implications. Et, ce bout de code s'est quelque peu transformé en une flotte de VBScripts gargantuesques qui accaparent tout l'espace disponible dans c:\scripts et finissent par bloquer Visual Notepad. (Remarque : si vous recherchez actuellement Visual Notepad sur le Web, pouvons-nous vous proposer un pont déjà utilisé, mais en excellent état ?) Il est difficile de vous expliquer à quel point tout ceci l'affecte, mais nous pouvons vous dire que des cernes sont apparues sous ses yeux et que depuis, il a très souvent le regard perdu.

Regardons la vérité en face : si vous avez Systems Management Server (SMS) ou Windows Server Update Services (WSUS), utilisez-le ! Si votre organisation utilise la Stratégie de groupe, conservez-la et ne revenez pas en arrière ! Ce sont des solutions Microsoft recommandées pour le déploiement de mises à jour telles que le Service Pack 2. Elles ont été conçues et optimisées spécialement pour résoudre ce type de problème.

Et si SMS, WSUS et la Stratégie de groupe n'existaient pas ?

Le script à la rescousse

Le script, d'après le Dr. Scripto, c'est comme un ruban adhésif : ni joli ni élégant, mais très utile lorsque vous devez coller ensemble différents éléments.

Le Dr Scripto s'est tellement concentré sur son codage que nous n'avons pas voulu gâcher son enthousiasme. Mais en réalité, personne n'ignore qu'il est possible d'utiliser des scripts pour installer le Service Pack 2 Windows XP sur plusieurs ordinateurs. Il existe deux documents connexes, avec des exemples de code, qui expliquent deux méthodes que vous pouvez utiliser :

Les exemples de scripts présentés dans le guide (en anglais) Compatibility Testing and Mitigation Guide for Windows XP Service Pack 2 utilisent notamment des fichiers de commandes et le modèle d'objet Windows Script Host pour exécuter cette tâche, alors que les Scripts complémentaires utilisent principalement le modèle d'objet du Pare-feu Windows et WMI. Ces deux méthodes sont complexes et impliquent le réamorçage de l'ordinateur distant à deux reprises. Dans cet article, nous avons décidé de vous montrer une autre méthode, plus simple, que vous pouvez également utiliser pour l'installation à distance d'autres applications.

Voici le cœur du problème : si vous installez SP2 avec les paramètres par défaut, vous ne pourrez pas y exécuter des scripts ou des outils à distance. Dans les paramètres par défaut de SP2, le Pare-feu Windows est activé et les paramètres par défaut du Pare-feu bloquent toute tentative d'administration à distance via l'appel de procédure distante (RPC, Remote Procedure Call), le modèle DCOM (Distributed Component Object Model) ou les canaux nommés.

Pour comprendre la façon dont le Pare-feu Windows bloque l'administration à distance et les contraintes que cela peut représenter pour les administrateurs système qui automatisent leurs réseaux à l'aide de scripts, consultez un autre article des Messieurs Script, I Married Bigfoot. Oh: and Service Pack 2 Made My Computers Disappear site en anglais (en anglais).
Si vous préférez apprendre à l'aide de webcasts, nous vous proposons celui-ci : TechNet Webcast - Scripting with Microsoft Windows XP Service Pack 2: SOS! site en anglais (en anglais). N'allez surtout pas dire que les Messieurs Script n'ont pas tout ce qu'il vous faut en matière de scripts pour le Service Pack 2.

Euh... Où en étions-nous avant ce petit coup de pub ? Ah, oui, votre script d'installation doit trouver le moyen de modifier les paramètres par défaut du pare-feu, avant ou après l'installation.

Préparation de l'installation du Service Pack 2

Les exemples de scripts proposés dans les documents « Application Compatibility Testing and Mitigation Guide for Windows XP Service Pack 2 » (en anglais) et « Compatibilité des applications Service Pack 2 Windows XP - Scripts complémentaires » utilisent le fichier exécutable non modifié de SP2, disponible en téléchargement, puis modifient les paramètres après l'installation. Cette solution utilise un algorithme ingénieux, mais requiert une certaine souplesse acrobatique. Malheureusement, les Messieurs Script ne sont pas très adroits et notre style est plutôt pathétique (nous avons développé une importante musculature en écrivant les Scripts complémentaires). Nous avons donc opté pour une approche moins physique.

Heureusement, il existe d'autres solutions. La première consiste à modifier les paramètres du pare-feu en extrayant le contenu du fichier SP2 téléchargé sur un partage réseau d'un serveur de fichiers et en modifiant le fichier de configuration de pare-feu qu'il contient. Les fragments personnalisés stockés sur ce partage peuvent alors être utilisés pour l'installation sur chaque ordinateur distant. Pour plus de détails sur cette procédure, reportez-vous au Scénario 2 du Guide d'installation et de déploiement du Service Pack 2 Microsoft® Windows® XP site en anglais
et de Deploying Windows Firewall Settings for Microsoft Windows XP with Service Pack 2 (WF_XPSP2.doc) site en anglais (en anglais). Le seul inconvénient de cette approche c'est qu'après avoir modifié le fichier de configuration, vous devez signer le code numériquement. Dans le cas contraire, le fichier exécutable de mise à jour échouera. Pour les organisations qui utilisent peu la signature numérique, ce procédé peut s'avérer un peu fastidieux.

Nous avons opté pour une méthode qui semble fonctionner indépendamment du fait que vous ayez ou non extrait les fichiers d'installation avant d'exécuter la mise à jour. Ainsi, vous pouvez configurer les paramètres de Registre du Pare-feu Windows à l'aide d'un script avant d'installer SP2, pour activer l'administration à distance ou pour désactiver le pare-feu, et les paramètres ne seront pas remplacés par l'installation.

Une autre question essentielle : les choix qui s'offrent à vous, à savoir, exécuter le fichier exécutable SP2 à partir d'un partage central ou le copier sur un ordinateur distant et l'exécuter localement, présentent tous deux des avantages et des inconvénients. Le fichier exécutable est très volumineux, environ 266 Mo, et peut générer un trafic réseau relativement dense. L'espace disque requis sur les clients est cependant beaucoup moins important lorsque vous optez pour un partage central. Pour une installation à partir d'un partage réseau central (comme c'est le cas du script décrit dans cet article), comptez un peu plus de 1 Go d'utilisation maximale du disque au cours de l'installation sur l'ordinateur cible et un peu plus de 1,5 Go pour une installation à partir d'un fichier exécutable local. Pour plus d'informations, reportez-vous à l'article 837783 de la Base de connaissances, intitulé « Espace disque minimal requis pour le Service Pack 2 Windows XP ».

La probabilité que tous les ordinateurs clients à mettre à niveau soient en ligne au moment de l'installation est un autre élément à prendre en considération. Si la plupart des clients sont des ordinateurs portables connectés au réseau par intermittence, vous devez copier le fichier exécutable d'installation sur chacun d'entre eux lorsqu'ils sont connectés et les exécuter localement. Nous n'allons pas vous expliquer comment écrire un tel script dans cet article, mais les documents Application Compatibility Testing and Mitigation Guide for Windows XP Service Pack 2 (en anglais) et Compatibilité des applications Service Pack 2 Windows XP - Scripts complémentaires abordent cette approche dans le Scénario 2. Le Guide d'installation et de déploiement de Microsoft® Windows® XP Service Pack 2 site en anglais décrit également comment exécuter manuellement cette opération dans le « Scénario 1 : Installation du Service Pack de manière à ce que les ordinateurs utilisent les fichiers sources locaux du Service Pack ».

Dans cet article, nous allons appliquer ce que le Guide d'installation et de déploiement appelle « Scénario 2 : Installation du Service Pack de manière à ce que les ordinateurs utilisent les fichiers sources distants et partagés du Service Pack ». Ce scénario décrit la procédure manuelle permettant de mettre en œuvre cette méthode.

Par ailleurs, le script de cet article suppose que les clients sur lesquels vous installez le Service Pack 2 exécutent déjà Windows XP. Cette opération est également appelée « installation autonome ». Si vous souhaitez effectuer une installation intégrée de Windows XP et du Service Pack 2, en les installant simultanément sur des ordinateurs qui n'exécutent pas encore Windows XP, consultez la section « Installation intégrée » du Guide d'installation et de déploiement.

Mais ne négligeons pas le rôle de l'ingénierie humaine dans tout déploiement d'un Service Pack, que ce soit avec ou sans script :

  • Effectuez les mises à jour la nuit ou pendant les heures où les ordinateurs sont peu utilisés.

  • Informez les utilisateurs à l'avance qu'ils ne doivent pas travailler sur leurs ordinateurs au moment de l'installation car celle-ci s'exécutera automatiquement, entraînant l'arrêt forcé de toutes les applications et le redémarrage de l'ordinateur une fois l'installation terminée.

  • Demandez aux utilisateurs d'enregistrer leur travail et de sauvegarder leurs fichiers avant la mise à jour (ou exécutez votre programme de sauvegarde régulière sur chaque ordinateur avant de démarrer la mise à jour).

  • Le choix de désactiver temporairement ou non le logiciel antivirus dépend de la configuration de votre réseau. Si l'analyse anti-virus est activée, l'installation peut durer une heure de plus sur les anciens ordinateurs.

Création d'un partage réseau pour les fichiers d'installation

Il nous reste un peu de travail de préparation à effectuer avant d'explorer le code du script. Pour préparer l'installation du Service Pack 2, nous devons configurer un dossier de distribution partagé sur la station de travail d'administration ou sur un serveur de fichiers disponible en permanence. Le partage peut se trouver sur le même ordinateur que le script. Mais la procédure sera plus efficace si vous configurez à cet effet un serveur de fichiers distinct lorsque le nombre d'ordinateurs à mettre à jour est important. Dans ce script, nous avons appelé le partage \\<server>\xpsp2\, mais vous pouvez lui attribuer n'importe quel nom à condition de modifier le chemin d'accès en conséquence dans le script.

Ce partage doit être permanent afin de garantir la disponibilité de tous les fichiers susceptibles d'être remplacés par un client à l'avenir.

Si vous déplacez le dossier de distribution partagé, consultez l'article de la Base de connaissances Microsoft « Des fichiers et des dossiers sont ajoutés à votre système après avoir installé un Service Pack » pour plus d'informations.

Une fois que nous avons créé ce partage, nous devons y placer le programme d'installation du Service Pack 2, à savoir Xpsp2.exe ou WindowsXP-KB835935-SP2-ENU.exe.

Pour plus de précisions, consultez le Scénario 2 du Guide d'installation et de déploiement du Service Pack 2 Microsoft® Windows® XP site en anglais.

Exécution du programme d'installation

Le fichier d'installation s'appelle WindowsXP-KB835935-SP2-ENU.exe en version téléchargeable (anglais U.S.) et Xpsp2.exe sur le CD-ROM d'installation de SP2. Nous allons utiliser ce dernier, mais cette explication s'applique aux deux sans distinction.

Vous pourriez exécuter Xpsp2.exe sans arguments afin de mettre à jour manuellement des ordinateurs individuels avec les paramètres par défaut. Cependant, si vous optez pour cette alternative, les utilisateurs devront répondre aux boîtes de dialogue qui s'affichent pendant l'installation. Nous voulons effectuer une installation sans assistance sur des clients distants, à partir d'un script. Même s'il est préférable d'exécuter le script lorsque très peu d'utilisateurs sont connectés, nous voulons quand même que l'installation s'exécute en mode silencieux de sorte que l'interface utilisateur soit masquée sur le client et que toute application ouverte soit immédiatement fermée. À la fin de l'installation, nous voulons nous assurer que l'ordinateur est réamorcé afin que l'installation du Service Pack 2 soit effective.

Pour satisfaire à ces exigences, l'une des solutions serait d'utiliser les commutateurs de ligne de commande suivants avec Xpsp2.exe :

xpsp2.exe /q /f /forcerestart

/q - L'installation s'effectue en mode silencieux (identique au mode sans assistance avec masquage de l'interface utilisateur). Si vous utilisez cette option, aucune invite ne s'affiche à l'écran durant le processus d'installation.

/f - Force les autres applications à se fermer lors de l'arrêt du système.

/forcerestart - L'ordinateur redémarre une fois l'installation terminée.

Il s'agit de la ligne de commande utilisée par le script. Si vous êtes en train de décompresser les fichiers dans un partage et de modifier et signer le fichier de configuration du pare-feu, ces commutateurs fonctionnent également pour Update.exe, le fichier exécutable que vous exécuteriez dans ce cas.

Vous pouvez utiliser différentes combinaisons de commutateurs en fonction de l'environnement d'installation. La section « Options de ligne de commande pour XPsp2.exe et Update.exe » du Guide d'installation et de déploiement de Microsoft® Windows® XP Service Pack 2 site en anglais dresse la liste de toutes les options de ligne de commande disponibles.

Commentaires

Avant de montrer le chef d'œuvre du Dr. Scripto, nous voulons vous donner un petit conseil : EXÉCUTEZ CE SCRIPT D'ABORD SUR UN RÉSEAU DE TEST !!! Même si cela peut vous surprendre, les Messieurs Script ne peuvent pas garantir que ce qui a été exécuté sur notre parc de test fonctionnera parfaitement la première fois sur votre réseau de production. Vous ne pouvez donc en aucun cas exécuter ce script sans avoir modifié certaines valeurs du bloc de modifications au début du script (et dans le fichier d'entrée hosts.txt, si vous l'utilisez). ENCORE UNE FOIS : N'EXÉCUTEZ RIEN SUR VOTRE RÉSEAU DE PRODUCTION QUE VOUS N'AURIEZ PAS PARFAITEMENT TESTÉ !!!

Pourquoi sommes-nous en train de perturber la mise en forme paisible de cette page Web avec tous ces caractères en majuscules ? Parce que nous sommes profondément attachés à nos lecteurs et pensons qu'apprendre à écrire des scripts doit leur permettre d'éviter des problèmes majeurs et non de se faire virer. Les réseaux sont comme des petits flocons de neige : il est très peu probable qu'il en existe deux identiques. (Bon, d'accord, ils ne ressemblent pas vraiment à des flocons de neige.) Malgré leur extraordinaire clairvoyance, les Messieurs Script ne peuvent pas anticiper toutes les permutations possibles des configurations réseau. Suivez notre conseil, mais avec prudence : pendant la Guerre froide, on avait coutume de dire à propos du contrôle des armes « Ayez confiance, mais vérifiez quand même ».

Voilà pour les mauvaises nouvelles. Et voici les bonnes : certaines fonctions de ce script, quelque peu modifiées, peuvent être utilisées pour installer ou exécuter à distance d'autres applications, et pas seulement le Service Pack 2 Windows XP. Par conséquent, en travaillant sur les composants de ce script, vous construisez une bibliothèque de codes réutilisables.

Désolé, j'avais oublié une autre mauvaise nouvelle, mais pas si mauvaise. Ce script n'est qu'un exemple du mode d'automatisation du processus d'installation du SP2. Nous présentons des alternatives que vous pouvez essayer en fonction de la configuration de votre réseau. L'exemple que nous proposons n'est qu'un modèle ; à vous de faire jouer votre imagination et votre créativité. Et, détrompez-vous, nous ne faisons pas partie du service Marketing, c'est juste notre style d'écriture.

À l'instar de tous les scripts de cette rubrique et de la plupart des scripts du Centre de scripts TechNet, ce script doit être exécuté sous Cscript.exe, l'environnement d'exécution de scripts de ligne de commande. Vous pouvez exécuter :

cscript xpsp2-deploy.vbs

Pour définir Cscript comme valeur par défaut sur votre ordinateur, supprimer les lignes de logos lors de l'exécution de chaque script et enregistrer ces paramètres, vous pouvez exécuter :

wscript \\h:cscript \\nologo \\s

Le cœur du script

Vous devez d'abord décider si : vous souhaitez obtenir les données du script en lisant une liste d'ordinateurs dans un fichier texte (les ordinateurs que vous souhaitez mettre à jour vers SP2) ou en utilisant ADO pour identifier les clients Windows XP qui n'exécutent pas encore SP2. Pour choisir la méthode à utiliser, définissez la valeur de la variable blnAD sur True ou sur False dans le bloc de modifications situé au début du script.

Si vous définissez blnAD sur False, assurez-vous que le nom et le chemin d'accès du fichier texte correspondent à la chaîne attribuée à strInputFile. Le fichier texte doit contenir une liste de noms d'ordinateurs (un nom par ligne) accessibles sur le réseau, exécutant Windows XP et prêts pour la mise à jour avec le Service Pack 2.

Si vous définissez blnAD sur True, vérifiez que strContainer présente le nom du conteneur Active Directory dans lequel vous souhaitez rechercher des ordinateurs Windows XP non mis à jour avec le Service Pack 2.

Toutes les autres variables devant être configurées pour fonctionner sur un réseau ou un ordinateur spécifique se trouvent dans le bloc de modifications. Veillez à les modifier et à leur attribuer les valeurs appropriées pour votre station de travail et votre réseau avant d'exécuter le script.

Dans l'exemple de script, les valeurs de strInputFile et de strOutputFile supposent que vous avez créé un répertoire nommé c:\scripts\xpsp2. Bien entendu, si vous le souhaitez, vous pouvez modifier les chemins d'accès et les noms des fichiers.

Vous devez également définir la variable d'heure, strHrMin, sur une heure appropriée, afin de planifier les mises à jour. Le paramètre d'heure pour la méthode Create de Win32_ScheduledJob utilise un format 24 heures. Ainsi, dans l'exemple de strHrMin présenté dans le script, « 1637 » correspond à 16h37. Il va de soi qu'il est préférable de définir ce paramètre sur une heure tardive à laquelle peu d'utilisateurs sont susceptibles d'être connectés.

Avec une légère modification des chaînes, le script pourrait échelonner les heures d'installation pour chaque ordinateur en incrémentant strHrMin à chaque boucle dans la liste des ordinateurs. Cela permettrait d'alléger la charge du serveur de fichiers à partir duquel vous exécutez les installations. Vous pourriez même prolonger une installation jusqu'au lendemain, bien que cela implique la configuration d'un autre paramètre de la méthode Create non utilisé dans cet exemple.

La logique de la section principale du script passe en revue le tableau de noms d'ordinateurs obtenus à partir du fichier texte ou du conteneur Active Directory. Sur chaque ordinateur, la logique :

  • vérifie si l'hôte est en ligne à l'aide de la commande ping. Si l'exécution de cette commande réussit, elle...

  • essaie de se connecter à WMI sur l'ordinateur. Si elle parvient à créer une liaison vers WMI, elle…

  • vérifie s'il y a suffisamment d'espace disque disponible pour exécuter la mise à niveau. Si tel est le cas, elle...

  • crée de nouvelles sous-clés de Registre et y écrit des entrées et des valeurs permettant l'administration à distance sur le Pare-feu Windows après l'installation. Si le Registre est modifié avec succès, elle...

  • exécute Xpsp2.exe avec les commutateurs de ligne de commande appropriés à partir du partage de fichiers central.

Le script affiche les résultats à l'écran et les consigne dans un fichier journal .CSV dont les valeurs sont séparées par des virgules. Pour construire la chaîne qui sera transmise à la sous-routine, laquelle l'écrira dans le fichier journal, le script utilise un code similaire au suivant, qui extrait le contenu de strData et y ajoute une autre chaîne littérale :

strData = strData & "ERROR: Ping failed"

Dans la deuxième partie de cette série de trois articles, nous avons expliqué comment utiliser les variables globales pour que les procédures puissent lire et modifier les données. Ce script présente une approche différente : il utilise des noms de variables uniques avec une étendue locale dans la section principale du script et dans chaque fonction ou sous-routine. Par conséquent, toutes les données doivent être transférées aux procédures sous forme de paramètres et les fonctions doivent renvoyer les données à la section principale du script. Cette méthode consistant à échanger des données entre les procédures permet d'identifier plus précisément les données échangées entre les différentes sections du script.

Fonction GetADList

Cette fonction extrait le nom d'un conteneur Active Directory sous forme de paramètre et renvoie un tableau contenant les noms des ordinateurs à mettre à jour. Elle est très similaire à la fonction utilisée dans le script ADO abordé dans la section « ADO et la recherche dans Active Directory » de l'Inventaire des Service Packs Windows XP – Deuxième partie.

Fonction ReadTextFile

Cette fonction est très similaire à la fonction qui porte le même nom dans l'Inventaire des Service Packs Windows XP  – Première partie. Elle extrait le nom d'un fichier texte contenant une liste d'ordinateurs à mettre à jour vers le Service Pack 2 et renvoie un tableau avec les noms d'ordinateurs.

Fonction PingHost

Pour déterminer si un ordinateur est accessible sur le réseau avant d'essayer de se connecter à WMI et d'y exécuter une tâche, la fonction PingHost utilise la méthode Exec de l'objet Windows Script Host Shell site en anglais pour appeler Ping.exe. VBScript fournit des fonctions de traitement de chaînes qui permettent à la fonction PingHost d'analyser le flux StdOut résultant afin de vérifier si l'ordinateur distant a répondu. PingHost renvoie 0 en cas de réussite de la commande ping, 1 en cas d'échec, et 2 en cas d'erreur lors de l'appel de la méthode Exec.

Fonction CheckFreeDiskSpace

CheckFreeDiskSpace utilise la propriété FreeSpace de la classe Win32_LogicalDisk site en anglais pour s'assurer qu'il existe suffisamment d'espace disponible sur le disque dur pour installer le Service Pack 2. Si vous pensez qu'une valeur autre que 1 Go est plus appropriée pour l'espace disque maximal utilisé au cours de l'installation, vous pouvez modifier la valeur de la constante SP2_FREE_SPACE.

Cette fonction suppose que le lecteur C: est le lecteur système sur tous les clients. Si l'un des ordinateurs à mettre à jour possède un lecteur système autre que C:, vous pouvez ajouter une fonction qui identifie le lecteur système et renvoie la lettre correspondante, laquelle pourra ensuite être utilisée par CheckFreeDiskSpace. Vous pouvez obtenir ces informations à l'aide de la propriété SystemDrive de la classe Win32_OperatingSystem site en anglais.

Si cette fonction trouve suffisamment d'espace disque disponible pour installer le Service Pack 2, elle renvoie la valeur 0. Dans le cas contraire, elle renvoie 1. En cas d'erreur lors de l'interrogation de la classe Win32_LogicalDisk, elle renvoie 2.

Fonction EnableRemoteAdmin

Nous devons ensuite personnaliser l'installation en configurant les paramètres de Registre du Pare-feu Windows afin que l'ordinateur vous permette à nouveau d'y exécuter des scripts à distance une fois l'installation terminée.

Dans ce script, nous allons tirer profit de la classe WMI StdRegProv site en anglais pour créer et configurer ces paramètres dans le Registre avant d'installer le Service Pack 2. Le fichier exécutable d'installation tient compte des paramètres d'administration à distance présents dans le Registre.

Nous transférons à EnableRemoteAdmin le nom de l'ordinateur sur lequel les paramètres doivent être modifiés. Cette étape est obligatoire car la fonction doit créer une liaison vers WMI sur chaque ordinateur afin d'utiliser la classe StdRegProv. Même si nous nous sommes déjà connectés à l'espace de noms root\cimv2 de WMI, nous devons réitérer l'opération car StdRegProv se trouve dans l'espace de noms root\default.

EnableRemoteAdmin crée les deux sous-clés requises pour les paramètres DomainProfile et StandardProfile à l'aide de la méthode CreateKey. Les deux sous-clés doivent être créées car elles n'existent pas dans le Registre tant que le Service Pack 2 n'a pas été installé. Le Pare-feu Windows comporte deux jeux de paramètres : Domain, utilisé lorsque l'ordinateur est connecté à son domaine d'origine, et Standard, lorsqu'il ne l'est pas. Si les sous-clés sont créées avec succès, EnableRemoteAdmin attribue à l'entrée Enabled la valeur 1 et à l'entrée RemoteAddresses la valeur « * », en utilisant respectivement les méthodes SetDWORDValue et SetStringValue. Ces paramètres autorisent l'administration à distance sur toutes les adresses pour les deux profils.

Voici un exemple du code pour le paramètre DomainProfile :

blnCreateSubKey1 = objReg.CreateKey(HKLM, strKeyPath1)
  If blnCreateSubKey1 = 0 Then
    intReturn1 = objReg.SetDWORDValue(HKLM, strKeyPath1, _
     strEntryName1, intValue1)
    If intReturn1 <> 0 Then
      WScript.Echo "  ERROR: Unable to set " & strEntryName1
      EnableRemoteAdmin = 1
      Exit Function
    End If
    intReturn2 = objReg.SetStringValue(HKLM, strKeyPath1, _
     strEntryName2, strValue2)
    If intReturn2 <> 0 Then
      WScript.Echo "  ERROR: Unable to set " & strEntryName2
      EnableRemoteAdmin = 1
      Exit Function
    End If
  Else
    WScript.Echo "  ERROR: Unable to create registry subkey:" & VbCrLf & _
     "HKLM" & " " & strKeyPath1
    EnableRemoteAdmin = 1
    Exit Function
  End If

Si vous voulez désactiver le pare-feu par défaut, vous pouvez modifier les entrées et les valeurs correspondantes. Reportez-vous à Deploying Windows Firewall Settings for Microsoft Windows XP with Service Pack 2 (WF_XPSP2.doc) site en anglais (en anglais) pour plus de détails.

Si EnableRemoteAdmin réussit, il renvoie la valeur 0 ; sinon, il renvoie 1.

Fonction ScheduleJob

Si toutes les vérifications préliminaires se déroulent avec succès, cette fonction planifie une tâche sur chaque ordinateur local afin d'exécuter le fichier d'installation du Service Pack 2 à partir d'un partage distant, à l'aide de la méthode Create de Win32_ScheduledJob site en anglais.

Voici le code qui crée ce travail :

Set objNewJob = objWMIService.Get("Win32_ScheduledJob")
intCreated = objNewJob.Create(strCL, strTime, , , , , JobID)

ScheduleJob extrait sous forme de paramètres d'entrée deux variables de chaîne :

  • La première, strCL, contient la chaîne de ligne de commande destinée à exécuter Xpsp2.exe, y compris le chemin d'accès au fichier exécutable et les arguments permettant de l'exécuter sans assistance.

  • La seconde, strTime, contient une chaîne représentant l'heure à laquelle le travail doit être effectué.

D'autres paramètres, non décrits ici, peuvent spécifier la ou les dates auxquelles le travail doit être effectué et sa périodicité.

Si elle réussit à créer un travail, la méthode Create renvoie un paramètre de sortie à la fonction qui contient l'ID de travail de la tâche planifiée qui a été créée. ScheduleJob renvoie l'ID de travail du processus Xpsp2.exe en cas de succès et -1 en cas d'échec.

Fonction HandleError

La fonction HandleError n'extrait aucun paramètre car elle peut accéder aux objets VBScript Err créés ailleurs dans le script. Elle construit une chaîne à partir des propriétés Number, Source et Description de cet objet et la renvoie en tant que valeur. Cette fonction est très similaire à celle du script principal, décrite dans l'Inventaire des Service Packs Windows XP  – Deuxième partie.

Sous-routine WriteCSVFile

WriteCSVFile extrait deux paramètres, à savoir le nom du fichier dans lequel la sortie du script sera écrite, et une chaîne contenant des informations sur l'installation réalisée sur chaque ordinateur. Si le travail d'installation a été créé avec succès, la chaîne contient l'ID de travail ; dans le cas contraire, elle contient un message d'erreur.

Cette fonction utilise l'objet FileSystemObject site en anglais de Script Runtime pour ouvrir un fichier .CSV pouvant être ouvert dans une feuille de calcul et y écrire les données.

Fichier Hosts.txt

Le fichier d'entrée lu par la fonction ReadTextFile est un simple fichier texte contenant sur chaque ligne le nom d'un ordinateur accessible qui doit être mis à jour vers le Service Pack 2. Souvenez-vous que, à l'instar du conteneur Active Directory pour la fonction GetADList, vous devez disposer de privilèges d'administrateur sur tous les hôtes.

client1
client2
client3
client4

Code du script

À présent, respirez profondément. Ne paniquez pas : de nombreux romans russes sont plus longs que ce script. Prenez une autre tasse de café ou de thé et mettez-vous à l'aise. Le voici :

'Deploy Windows XP Service Pack 2 on multiple clients.

'******************************************************************************
'Change block: Change these values to reflect local machine and network.
'Set blnAD to True to run against an Active Directory Container.
'Set blnAD to False to run against a list in a text file.
blnAD = False
'If blnAD = True, must specify
strContainer = "dc=na,dc=fabrikam,dc=com"
'If blnAD = False, must specify text file with names of XP clients to upgrade.
strInputFile = "c:\scripts\xpsp2\hosts.txt"
'UNC path to share with Service Pack 2 executable followed by switches
'If using xpsp2.exe or WindowsXP-KB835935-SP2-ENU.exe on a share.
strCmdLine = "\\server\xpsp2\xpsp2.exe /q /f /forcerestart"
'If using extracted installation files on a share.
'strCmdLine = "\\server\xpsp2\i386\update\update.exe /q /f /forcerestart"
'Time (24-hour clock) today to run first scheduled job.
strHrMin = "1637"
strRunTime = "********" & strHrMin & "00.000000-420"
'Add date to name of log file.
strDate = Replace(Date, "/", "-")
strOutputFile = "c:\scripts\xpsp2\xpsp2-" & strDate & ".csv"
'******************************************************************************

On Error Resume Next

strData = ""
'Get list of XP clients in container to update to SP2.
If blnAD = True Then
  arrHosts = GetADList(strContainer)
Else
  arrHosts = ReadTextFile(strInputFile)
End If

'Loop through list of hosts.
For Each strHost in arrHosts

  WScript.Echo VbCrLf & "Host Name: " & strHost
  strData = strData & VbCrLf & strHost & ","

'Ping client to check connection.
  intPing = PingHost(strHost)
  If intPing = 0 Then
'Connect to WMI on client.
    Set objWMIService = GetObject("winmgmts:" _
     & "{impersonationLevel=Impersonate}!\\" & strHost & "\root\cimv2")
    If Err = 0 Then
'Check for sufficient disk space on target machine for SP2.
      intFree = CheckFreeDiskSpace()
      If intFree = 0 Then
'Enable remote administration.
        intEnabled = EnableRemoteAdmin(strHost)
        If intEnabled = 0 Then
'Run SP2 installation.
          intJobID = ScheduleJob(strCmdLine, strRunTime)
          If intJobID = -1 Then
            strData = strData & "ERROR: Unable to create job."
          Else
            strData = strData & "SUCCESS: Job" & _
             intJobID & " created."
          End If
        Else
          strData = strData & "ERROR: Unable to enable remote " & _
           "administration."
        End If
      ElseIf intFree = 1 Then
        strData = strData & "ERROR: Insufficient free disk space."
      Else
        strData = strData & "ERROR: Unable to determine free disk space."
      End If
    Else
      WScript.Echo "  ERROR: Unable to connect to WMI provider on host."
      strMessage = HandleError
      strData = strData & "ERROR: Unable to connect to WMI provider " & _
       "on host." & strMessage
    End If
  ElseIf intPing = 1 Then
    WScript.Echo "  ERROR: Ping failed."
    strData = strData & "ERROR: Ping failed"
  Else
    strData = strData & "ERROR: Unable to execute ping."
  End If

Next

strData = strData & VbCrLf

'Open output .csv file and write results to it.
WriteCSVFile strOutputFile, strData
WScript.Echo VbCrLf & "Data written to " & strOutputFile

'******************************************************************************

'Use ADO to get list of XP clients in container to update to SP2.
Function GetADList(strCntnr)

On Error Resume Next

'Local constants and variables
Const ADS_SCOPE_SUBTREE = 2
intPageSize = 1000
strQuery = _
 "SELECT CN, operatingSystemVersion, operatingSystemServicePack " _
 & "FROM 'LDAP://" & strCntnr & "' " _
 & "WHERE objectCategory='computer' " _
 & "AND operatingSystemVersion = '5.1 (2600)' " _
 & "AND NOT operatingSystemServicePack = 'Service Pack 2'"

Set objConnection = CreateObject("ADODB.Connection")
Set objCommand = CreateObject("ADODB.Command")
objConnection.Provider = ("ADsDSOObject")
objConnection.Open "Active Directory Provider"
If Err <> 0 Then
  WScript.Echo "ERROR: Unable to connect to AD Provider with ADO."
  strMessage = HandleError
  WScript.Echo strMessage
  WScript.Quit
End If
objCommand.ActiveConnection = objConnection
objCommand.Properties("Page Size") = intPageSize
objCommand.Properties("Searchscope") = ADS_SCOPE_SUBTREE
objCommand.CommandText = strQuery
Set objRecordSet = objCommand.Execute
If Err <> 0 Then
  WScript.Echo "ERROR: Unable to execute ADO query."
  strMessage = HandleError
  WScript.Echo strMessage
  WScript.Quit
End If
objRecordSet.Sort = "CN"
objRecordSet.MoveFirst 

Do Until objRecordSet.EOF
  strUpdateList = strUpdateList & objRecordSet.Fields("CN").Value & ","
  objRecordSet.MoveNext 
Loop 

If strUpdateList = "" Then
  WScript.Echo "ERROR: No hosts found for update to Service Pack 2."
  WScript.Quit
End If

arrUpdateList = Split(strUpdateList, ",")

GetADList = arrUpdateList

End Function

'******************************************************************************

'Get list of XP clients from text file to update to SP2.
Function ReadTextFile(strFileName)

On Error Resume Next

Const FOR_READING = 1
Dim arrLines()

Set objFSO = CreateObject("Scripting.FileSystemObject")
If objFSO.FileExists(strFilename) Then
  Set objTextStream = objFSO.OpenTextFile(strFilename, FOR_READING)
Else
  WScript.Echo "ERROR: Input text file " & strFilename & " not found."
  WScript.Quit
End If

If objTextStream.AtEndOfStream Then
  WScript.Echo "ERROR: Input text file " & strFilename & " is empty."
  WScript.Quit
End If

Do Until objTextStream.AtEndOfStream
  intLineNo = objTextStream.Line
  ReDim Preserve arrLines(intLineNo - 1)
  arrLines(intLineNo - 1) = objTextStream.ReadLine
Loop

objTextStream.Close

ReadTextFile = arrLines

End Function

'******************************************************************************

'Ping client to check network connection.
Function PingHost(strTarget)

On Error Resume Next

Set objShell = CreateObject("WScript.Shell")
Set objExec = objShell.Exec("ping -n 2 -w 1000 " & strTarget)
If Err <> 0 Then
  Wscript.Echo "  ERROR: Unable to execute ping."
  strMessage = HandleError
  PingHost = 2
  Exit Function
End If
strPingResults = LCase(objExec.StdOut.ReadAll)
If InStr(strPingResults, "reply from") Then
  PingHost = 0
Else
  PingHost = 1
End If

End Function

'******************************************************************************

'Check for sufficient free disk space on client.
Function CheckFreeDiskSpace()

On Error Resume Next

Const HARD_DISK = 3
Const DEVICEID = "C:"
Const SP2_FREE_SPACE = 1000000000 'One gigabyte in bytes
Const MB = 1048576 'Megabyte factor

Set colDisks = objWMIService.ExecQuery _
 ("SELECT * FROM Win32_LogicalDisk WHERE DriveType = " _
 & HARD_DISK & " AND DeviceID = '" & DEVICEID & "'")

If Err <> 0 Then
  Wscript.Echo "  ERROR: Unable to determine free disk space."
  strMessage = HandleError
  CheckFreeDiskSpace = 2
  Exit Function
End If

For Each objDisk in colDisks
  intFreeSpace = objDisk.FreeSpace
Next

If intFreeSpace > SP2_FREE_SPACE Then
  CheckFreeDiskSpace = 0
Else
  CheckFreeDiskSpace = 1
End If

End Function

'******************************************************************************

'Set registry entries to enable remote administration.
Function EnableRemoteAdmin(strTarget)

On Error Resume Next

'Set constants and variables.
Const HKLM = &H80000002
Const ENABLED = 1
Const DISABLED = 0
Const ALL = "*"
Const LOCAL_SUBNET = "LocalSubnet"
strKeyPath1 = "SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters" & _
 "\FirewallPolicy\DomainProfile\RemoteAdminSettings"
strKeyPath2 = "SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters" & _
 "\FirewallPolicy\StandardProfile\RemoteAdminSettings"
strEntryName1 = "Enabled"
strEntryName2 = "RemoteAddresses"
intValue1 = ENABLED
strValue2 = ALL

'Connect with WMI service and StdRegProv class.
Set objReg = GetObject("winmgmts:{impersonationLevel=impersonate}!\\" & _
 strTarget & "\root\default:StdRegProv")

If Err = 0 Then

  blnCreateSubKey1 = objReg.CreateKey(HKLM, strKeyPath1)
  If blnCreateSubKey1 = 0 Then
    intReturn1 = objReg.SetDWORDValue(HKLM, strKeyPath1, _
     strEntryName1, intValue1)
    If intReturn1 <> 0 Then
      WScript.Echo "  ERROR: Unable to set " & strEntryName1
      EnableRemoteAdmin = 1
      Exit Function
    End If
    intReturn2 = objReg.SetStringValue(HKLM, strKeyPath1, _
     strEntryName2, strValue2)
    If intReturn2 <> 0 Then
      WScript.Echo "  ERROR: Unable to set " & strEntryName2
      EnableRemoteAdmin = 1
      Exit Function
    End If
  Else
    WScript.Echo "  ERROR: Unable to create registry subkey:" & VbCrLf & _
     "HKLM" & " " & strKeyPath1
    EnableRemoteAdmin = 1
    Exit Function
  End If

  blnCreateSubKey2 = objReg.CreateKey(HKLM, strKeyPath2)
  If blnCreateSubKey2 = 0 Then
    intReturn3 = objReg.SetDWORDValue(HKLM, strKeyPath2, _
     strEntryName1, intValue1)
    If intReturn3 <> 0 Then
      WScript.Echo "  ERROR: Unable to set " & strEntryName1
      EnableRemoteAdmin = 1
      Exit Function
    End If
    intReturn4 = objReg.SetStringValue(HKLM, strKeyPath2, _
     strEntryName2, strValue2)
    If intReturn4 <> 0 Then
      WScript.Echo "  ERROR: Unable to set " & strEntryName2
      EnableRemoteAdmin = 1
      Exit Function
    End If
  Else
    WScript.Echo "  ERROR: Unable to create registry subkey:" & VbCrLf & _
     "HKLM" & " " & strKeyPath1
    EnableRemoteAdmin = 1
    Exit Function
  End If

Else

  WScript.Echo "  ERROR: Unable to connect to WMI class StdRegProv."
  strMessage = HandleError
  EnableRemoteAdmin = 1
  Exit Function

End If

EnableRemoteAdmin = 0

End Function

'******************************************************************************

'Schedule SP 2 upgrade on client from remote share.
Function ScheduleJob(strCL, strTime)

On Error Resume Next

Set objNewJob = objWMIService.Get("Win32_ScheduledJob")
intCreated = objNewJob.Create(strCL, strTime, , , , , JobID)

If intCreated = 0 Then
  Wscript.Echo "  SUCCESS: Job " & JobID & " created."
  ScheduleJob = JobID
Else
  Wscript.Echo "  ERROR: Unable to create job." & _
   vbCrLf & "  Return value: " & intCreated
  ScheduleJob = -1
End If

End Function

'******************************************************************************

'Handle errors.
Function HandleError

intNumber = Err.Number
strDescription = Err.Description
strSource = Err.Source

WScript.Echo "    Number: " & intNumber & VbCrLf & _
 "    Description: " & strDescription & VbCrLf & _
 "    Source: " & strSource
strError = VbCrLf & ",,Number: " & intNumber & VbCrLf & _
 ",,Description: " & strDescription & VbCrLf & _
 ",,Source: " & strSource

HandleError = strError

Err.Clear

End Function

'******************************************************************************

'Write or append data to text file.
Sub WriteCSVFile(strFileName, strOutput)

On Error Resume Next

Const FOR_APPENDING = 8

'Open text file for output.
Set objFSO = CreateObject("Scripting.FileSystemObject")
If objFSO.FileExists(strFileName) Then
  Set objTextStream = objFSO.OpenTextFile(strFileName, FOR_APPENDING)
Else
  Set objTextStream = objFSO.CreateTextFile(strFileName)
End If

'Write data to file.
objTextStream.WriteLine "Windows XP Service Pack 2 Installation"
objTextStream.WriteLine "Run " & Now
objTextStream.WriteLine "--------------------------------------"
objTextStream.WriteLine  strOutput
objTextStream.WriteLine "--------------------------------------"
objTextStream.WriteLine

objTextStream.Close

End Sub

Résultat de la ligne de commande

Voici un exemple de ce que le script pourrait afficher :

C:\scripts\xpsp2>xpsp2-deploy.vbs

Host Name: client1
  ERROR: Ping failed.

Host Name: client2
  ERROR: Unable to create job.
  Return value: 3

Host Name: client3
  SUCCESS: Job 3 created.

Host Name: client4
  SUCCESS: Job 29 created.

Data written to c:\scripts\xpsp2\xpsp2-4-13-2005.csv

Fichier CSV

Voici le même résultat dans un fichier CSV ouvert dans Excel :

Feuille de calcul Excel avec le résultat du script

Que s'est-il passé ?

Avons-nous oublié quelque chose ici ? Très bien, vous l'aviez remarqué. Étant donné que ce script ne fait que créer un travail qui déclenche le processus d'installation, comment pouvons-nous savoir si l'installation a réussi sur chaque ordinateur ? Il existe plusieurs façons de traduire cela en script au moyen de techniques telles que la gestion d'événements. Pour l'instant, le Dr. Scripto dort sur son bureau, épuisé par les efforts déployés dans l'écriture de ce script, mais nous parviendrons peut-être à le convaincre de relever ce défi dans un prochain article.

Une fois que le délai prévu pour les installations se sera écoulé (20 minutes environ sur notre parc de test), vous pourriez envisager une approche simple qui consisterait à exécuter le script à partir de la première ou de la deuxième partie de cette série afin d'identifier les hôtes qui exécutent le Service Pack 2. Optez pour le script de la Première partie, qui fait appel à WMI, si votre réseau n'utilise pas Active Directory, ou pour le script de la Deuxième partie, qui fait appel à ADO et à ADSI, si vous travaillez sur un conteneur Active Directory.

Une autre alternative consisterait à vérifier les journaux des événements sur les ordinateurs distants. Pour ce faire, vous pouvez utiliser la classe WMI Win32_NTLogEvent site en anglais. Lorsque le Service Pack 2 est installé, un événement, dont l'ID est 19 et la source Agent de mise à jour de Windows, est écrit dans le journal des événements système. Un événement différent est probablement écrit en cas d'échec de l'installation du Service Pack 2. Par ailleurs, un ID et une source d'événement n'étant pas uniques, vous seriez probablement amené à vérifier tous les événements 19 avant de conclure que le Service Pack 2 a été installé avec succès.

Si aucune des suggestions précédentes ne vous paraît attrayante, il existe encore une autre source d'informations concernant l'installation : Xpsp2.exe crée en effet un fichier journal pour l'installation dans %systemroot%, sur chaque ordinateur local. D'après la documentation de SP2, ce fichier s'appelle Svcpack.log. Vous pourriez probablement écrire un script qui collecte ces fichiers journaux, puis les copie sur votre station de travail. Pour plus d'informations sur ce fichier, consultez le Guide d'installation et de déploiement du Service Pack 2 Microsoft® Windows® XP site en anglais.

Si vous connaissez un moyen de contrôler les installations et que vous souhaitez le partager avec les Messieurs Script, écrivez-nous à l'adresse scripter@microsoft.com.

Pour en savoir plus

Windows XP Service Pack 2

Pare-feu Windows