AppScript-H. Tester la présence des prérequis

I. Présentation

Pour ce n volet relatif aux techniques de script,

.
_Prerequisites

Cette étape de contrôle des prérequis est une bonne pratique au même titre que le contrôle du contexte (architecture, privilèges…). Les prérequis d’une application peuvent prendre différentes formes, telles que des composants système, des correctifs particuliers (KB), la version du système ou d’un produit, voire la présence ou bien l’absence d’une autre application.

En conséquence, je n’ai pas de méthode ou de technique prémâchée pour ce point hormis qu’il faut le garder à l’esprit lors de l’élaboration de vos scripts d’installation.

Pour rappel, le MDT permet de gérer des “dépendances” au sein des bundles d’application. Cette faculté permet de “lier” facilement et logiquement différentes applications entre elles. Dans MDT, lorsque des dépendances sont associées à une application, celles-ci sont prioritairement installées avant de déclencher l’installation de l’application.

Je vous rappelle par la même occasion, que le MDT peut exploiter des tests conditionnels au sein de chaque tache ou groupe de taches afin d’effectuer ou non l’action définie. Cf mon article http://www.it-connect.fr/mdt-introspection-des-sequences-de-taches/#B_Mise_en_oeuvre_des_taches_conditionnelles

 

II. Recourir à l’infrastructure WMI pour le contrôle

 

1.  Quelques classes WMI

L’usage des classes WMI constitue probablement un des moyens les plus répandus pour effectuer ces contrôles de prérequis, principalement sur le matériel, mais également les logiciels. Voici un petit extrait des possibilités

classe WMI Signification
Win32_SystemEnclosure Différencier un ordinateur de bureau, d’un portable
Win32_ComputerSystem Informations sur le matériel telles que la marque, le modèle, la quantité de mémoire vive….
Win32_PhysicalMemory Informations sur les caractéristiques physiques des barrettes mémoire
Win32_BIOS Informations sur le BIOS (Ne s’applique pas à la détection d’UEFI*)

Le fabriquant peuvent proposer des classes spécifiques pour l’accès aux réglages internes du firmware (ie : BiosSettings) – Ces classes ne sont pas toujours natives et peuvent nécessiter l’installation d’un package constructeur (cf Site Support du fabriquant).

Win32_Process Informations sur les processus en cours. Pratique pour terminer un processus avant d’entamer une mise à jour ou une installation
Win32_NetworkAdapterConfiguration Informations sur les cartes réseaux
Win32_QuickFixEngineering Gestion des correctifs (mises à jour système)
Win32_OperatingSystem Informations sur le système d’exploitation
Win32_Product Informations sur les applications installées via des packages MSI. Pour une liste exhaustive des applications installées, préférez la clé de registre HKLM:\SOFTWARE(\Wow6432Node)\Microsoft\Windows\CurrentVersion\Uninstall

 

*Note “BiosSettings” : Pour détecter si le contexte système est de type UEFI ou BIOS traditionnel, sous WinPE 4 ou ultérieur, vous pouvez utiliser la commande “wpeutil UpdateBootInfo” puis lire la valeur “PEFirmwareType” située sous la clé de registre “HKLM\System\CurrentControlSet\Control”. Si la valeur renvoyée est “0x1”, cela indique que l’ordinateur a démarré en mode BIOS classique, alors que la valeur “0x2”, correspond à un amorçage en mode UEFI.

Cette liste de classes WMI est loin d’être exhaustive sans compter les compléments spécifiques aux fabricants de PC, tels que Acer, Asus, Dell, Fujitsu ‐Siemens, HP, Lenovo (IBM), Sony, ou encore Toshiba.

 

2. Tester la présence de correctifs (KBxxxxxx)

Pour illustrer un test de prérequis, je vais prendre le cas concret d’installation d’Internet Explorer 11 au sein d’un système Windows 7. En effet, pour installer ce package IE11, il est nécessaire que les  mises à jour KB2729094, KB2731771, KB2533623, KB2670838, KB2786081 et KB2834140 soient présentes sur le système en question (32 et 64 bits)

 

(Batch)Pour tester la présence d’un correctif en batch, on peut recourir à l’outil WMIC, mais je n’affectionne plus vraiment cette technique, rapidement complexe dès que le nombre de contrôles augmente.

 

for /f %%a in ('wmic qfe where "hotfixid='KB2729094'" get hotfixid /format:list ^| findstr "="') do echo Correctif present else echo Correctif introuvable

Note : “qfe” est en fait l’alias de la classe “Win32_QuickFixEngineering” pour la console WMIC

(VBscript)Un autre exemple en vbscript, avec un passage du numéro de correctif recherché en paramètre, histoire d’être un peu plus proche d’une fonction réutilisable.

If WScript.Arguments.count = 0 Then
  WScript.Echo"Veuillez saisir un numéro de correctif à rechercher, comme KB2729094." & _
     vbCrLf & "Fin du script."
     WScript.Quit 1
End If
strHotfix = WScript.Arguments(0)
WScript.Echo "Recherche en cours, veuillez patienter..."
strComputer = "."
Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\cimv2")
Set colItems = objWMIService.ExecQuery("Select * from Win32_QuickFixEngineering",,48)
bFound = False
For Each objItem in colItems
  If objItem.HotfixID = strHotfix Then bFound = True
Next
If bFound = True Then 
  WScript.Echo strHotfix & " détectée."
Else
  WScript.Echo strHotfix & " introuvable."
End If

(PShell)En Powershell, on peut utiliser la même technique d’appel WMI ou bien recourir à l’applet de commande “Get-Hotfix”.

$HotFix = 'KB2729094'
Write-Host "Recherche en cours, veuillez patienter..."
if ((Get-HotFix -Id $HotFix -ErrorAction SilentlyContinue) -ne $null) {
 Write-Host -fore Green "$HotFix détectée."
 } else {

 Write-Host -fore Red "$HotFix introuvable."
} 

Pour le cas concret d’IE11, il faut tester la présence de plusieurs correctifs et vous remarquerez que chaque requête dure plusieurs secondes. En conséquence, pour optimiser cette recherche, je vous propose de collecter l’ensemble des correctifs en une seule requête, puis d’effectuer une recherche sur ce résultat, comme suit :

$NeededHotFixes = @('KB2670838','KB2726535','KB2729094','KB2786081','KB2834140')
Write-Host "Vérification de la présence des correctifs requis pour IE11."
$InstalledHotFixes = (Get-HotFix).HotFixId
$NeededHotFixes | foreach {
 if ($InstalledHotFixes -match $_) {
 Write-Host -fore Green "Correctif $_ installé";
 } else {
 Write-Host -fore Red "Correctif $_ manquant";
 }
} 

3 – Tester la présence d’un complément système

Pour tester la présence et/ou la version d’un élément requis à l’installation tel que le Framework.NET, les redistribuable C++, on utilise généralement le registre, un fichier “type” ou encore la classe Win32_Product. Toutefois, les requêtes sur cette classe WMI sont relativement longues et pénalisantes dans le cadre d’un contrôle de base.

(Batch)N’ayant jamais procédé de la sorte, je m’abstiendrais de vous proposer une solution en batch.

A – Framework .NET

FwDotNET

(VBscript)Voici un exemple en vbscript, permettant d’obtenir les différentes versions du Framework DotNET installées sur un ordinateur.

Const HKEY_LOCAL_MACHINE = &H80000002
strComputer = "."
Set oReg=GetObject("winmgmts:\\" & strComputer & "\root\default:StdRegProv")
strKeyPath = "SOFTWARE\Microsoft\NET Framework Setup\NDP"
oReg.EnumKey HKEY_LOCAL_MACHINE, strKeyPath, arrSubKeys
sList = "Liste des ""Framework .NET"" installé(s):" & vbCrLf  & String(60,"-") & vbCrLf

Dim  sFramework()
i=0
For Each subkey In arrSubKeys
    ReDim Preserve sFramework(i+1)
    sFramework(i) = subKey '  
    sList = sList & "Framework .NET " & sFramework(i)
    On Error Resume Next
    oReg.EnumValues  HKEY_LOCAL_MACHINE, strKeyPath & "\" & subKey, Details
    For Each sValueName In Details
       If sValueName = "SP" Then 
          oReg.GetDWORDValue HKEY_LOCAL_MACHINE, strKeyPath & "\" & subKey, sValueName, dwValue
          sList = sList & " - SP" & dwValue
       End If
    Next
    sList = sList & vbCrLf
Next

Wscript.Echo  sList

(PShell)En Powershell, voici un exemple permettant d’obtenir les différentes versions du Framework DotNET installées sur un ordinateur.

[reflection.assembly]::LoadWithPartialName('system.version')
Get-ChildItem 'HKLM:\SOFTWARE\Microsoft\NET Framework Setup\NDP' -recurse |
   Get-ItemProperty -name Version,Release -EA 0 |
      Where { $_.PSChildName -match '^(?!S)\p{L}'} |
        Select PSChildName, Version, Release 

Ou une alternative pour distinguer les versions ultérieures  à v4.5

Get-ChildItem 'HKLM:\SOFTWARE\Microsoft\NET Framework Setup\NDP' -recurse |
Get-ItemProperty -name Version,Release -EA 0 |
Where { $_.PSChildName -match '^(?!S)\p{L}'} |
Select PSChildName, Version, Release, @{
  name="Product"
  expression={
      switch($_.Release) {
        378389 { [Version]"4.5" }
        378675 { [Version]"4.5.1" }
        378758 { [Version]"4.5.1" }
        379893 { [Version]"4.5.2" }
        393295 { [Version]"4.6" }
        393297 { [Version]"4.6" }
        394254 { [Version]"4.6.1" }
        394271 { [Version]"4.6.1" }
      }
    }
} 

 

B – Redistributables Visual C++ ou autres

 

Pour tester la présence d’un produit tel que les redistribuables C++ ou une autre application, à mon sens, la technique la plus efficace porte sur le contrôle de l’identifiant unique (“IdentifyingNumber” ou “GUID“) dans le registre.

Pour connaitre cet identifiant, défini dans et par le package d’installation, vous pouvez :

  • Soit installer sur le produit sur un poste de test, puis obtenir cette information
    • [#1] via une requête WMI sur la classe Win32_Product, uniquement s’il s’agit d’un package de type MSI ou dérivé d’InstallShield. Par exemple, pour énumérer les redistribuables Visual C++ en Powershell:
       gwmi -query "select * from win32_product" | ? { $_.name -match "Visual C" }
    • [#2] via une recherche sous la clé de registre HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall

Note : La sous-clé “UninstallString” est généralement présente et riche d’enseignement du fait qu’elle permet de connaitre la commande de désinstallation d’un produit. Ce qui peut également, dans certains cas, constituer un prérequis d’installation d’une application incompatible.

  • Sans installer le produit si vous disposez du package MSI d’installation, utilisez un éditeur tel que “InstEd It!“, puis récupérez la valeur “Product Code” dans la table “Property” comme par exemple :

InstEd

A ma connaissance, les redistribuables C++ sont généralement livrés sous forme de packages exécutables pour lesquels l’identifiant n’est visible qu’après installation. Pour votre gouverne, voici de petits tableaux récapitulatifs que je m’étais constitué (en 2013).

  • Redistribuables Visual C++ 2005
Name CPU  Version IdentifyingNumber
Microsoft Visual C++ 2005 Redistributable x86  8.0.59193 {837b34e3-7c30-493c-8f6a-2b0f04e2912c}
Microsoft Visual C++ 2005 Redistributable x86  8.0.56336 {7299052b-02a4-4627-81f2-1818da5d550d}
Microsoft Visual C++ 2005 Redistributable x86  8.0.61001 {710f4c1c-cc18-4c49-8cbf-51240c89a1a2}
Microsoft Visual C++ 2005 Redistributable x86  8.0.50727.42 {A49F249F-0C91-497F-86DF-B2585E8E76B7}
Microsoft Visual C++ 2005 Redistributable x86  8.0.50727.4940 Intégré à Windows 7 x64 sp1
Microsoft Visual C++ 2005 Redistributable (x64) x64  8.0.61000 {ad8a2fa1-06e7-4b0d-927d-6e54b3d31028}
Microsoft Visual C++ 2005 Redistributable (x64) x64  8.0.56336 {071c9b48-7c32-4621-a0ac-3f809523288f}
Microsoft Visual C++ 2005 Redistributable (x64) x64  8.0.50727.42 {6E8E85E8-CE4B-4FF5-91F7-04999C9FAE6A}
Microsoft Visual C++ 2005 Redistributable (x64) x64  8.0.59192 {6ce5bae9-d3ca-4b99-891a-1dc6c118a5fc}
Microsoft Visual C++ 2005 Redistributable (amd64) x64  8.0.50727.4940 Intégré à Windows 7 x64 sp1

 

  • Redistribuables Visual C++ 2008
·          Name CPU  Version IdentifyingNumber
Microsoft Visual C++ 2008 Redistributable – x64 9.0.21022 x64  9.0.21022 {350AA351-21FA-3270-8B7A-835434E766AD}
Microsoft Visual C++ 2008 Redistributable – x86 9.0.30729 x86  9.0.30729 {820B6609-4C97-3A2B-B644-573B06A0F0CC}
Microsoft Visual C++ 2008 Redistributable – x64 9.0.30729 x64  9.0.30729 {9B3F0A88-790D-3AD9-9F96-B19CF2746452}
Microsoft Visual C++ 2008 Redistributable – x64 9.0.30729.4148 x64  9.0.30729.4148 {4B6C7001-C7D6-3710-913E-5BC23FCE91E6}
Microsoft Visual C++ 2008 Redistributable (amd64) x64  9.0.30729.4940 Intégré à Windows 7 x64 sp1
Microsoft Visual C++ 2008 Redistributable – x64 9.0.30729.6161 x64  9.0.30729.6161 {5FCE6D76-F5DC-37AB-B2B8-22AB8CEDB1D4}
Microsoft Visual C++ 2008 Redistributable – x86 9.0.21022.218 x86  9.0.21022.218 {E503B4BF-F7BB-3D5F-8BC8-F694B1CFF942}
Microsoft Visual C++ 2008 Redistributable – x86 9.0.30729.17 x86  9.0.30729 {9A25302D-30C0-39D9-BD6F-21E6EC160475}
Microsoft Visual C++ 2008 Redistributable – x64 9.0.30729.17 x64  9.0.30729 {8220EEFE-38CD-377E-8595-13398D740ACE}
Microsoft Visual C++ 2008 Redistributable – x86 9.0.30729.4148 x86  9.0.30729.4148 {1F1C2DFC-2D24-3E06-BCB8-725134ADF989}
Microsoft Visual C++ 2008 Redistributable (x86) x86  9.0.30729.4940 Intégré à Windows 7 x64 sp1
Microsoft Visual C++ 2008 Redistributable – x86 9.0.30729.6161 x86  9.0.30729.6161 {9BE518E6-ECC6-35A9-88E4-87755C07200F}

 

  • Redistribuables Visual C++ 2010

A partir de 2010, les mises à jour des redistribuables Visual C++ sont cumulatifs – Autrement dit, les différentes déclinaisons ne sont plus concomitantes. Le contrôle de l’identifiant unique n’est peut-être plus la meilleure solution.

Name CPU  Version IdentifyingNumber
Microsoft Visual C++ 2010  x64 Redistributable – 10.0.40219 x64  10.0.40219 {1D8E6291-B0D5-35EC-8441-6616F567A0F7}
Microsoft Visual C++ 2010  x86 Redistributable – 10.0.40219 x86  10.0.40219 {F0C3E5D1-1ADE-321E-8167-68EF0DE699A5}

 

  • Redistributables Visual C++ 2012
Name CPU  Version IdentifyingNumber
Microsoft Visual C++ 2012 x64 Additional Runtime – 11.0.60610 x64  11.0.60610 {764384C5-BCA9-307C-9AAC-FD443662686A}
Microsoft Visual C++ 2012 x64 Minimum Runtime – 11.0.60610 x64  11.0.60610 {2EDC2FA3-1F34-34E5-9085-588C9EFD1CC6}
Microsoft Visual C++ 2012 x86 Additional Runtime – 11.0.60610 x86  11.0.60610 {3D6AD258-61EA-35F5-812C-B7A02152996E}
Microsoft Visual C++ 2012 x86 Minimum Runtime – 11.0.60610 x86  11.0.60610 {E7D4E834-93EB-351F-B8FB-82CDAE623003}
Microsoft Visual C++ 2012 x86 Minimum Runtime – 11.0.61030 x86 11.0.61030 {BD95A8CD-1D9F-35AD-981A-3E7925026EBB}
Microsoft Visual C++ 2012 x64 Additional Runtime – 11.0.61030 x64 11.0.61030 {B175520C-86A2-35A7-8619-86DC379688B9}
Microsoft Visual C++ 2012 x64 Minimum Runtime – 11.0.61030 x64 11.0.61030 {CF2BEA3C-26EA-32F8-AA9B-331F7E34BA97}

 

 

Voilà, c’est tout ce que j’ai en tête pour l’instant, mais en matière de contrôle de prérequis les pistes et solutions sont très nombreuses, voire du cas par cas.

N’hésitez-pas à commenter cet article si vous avez des cas d’école à étudier, ils méritent surement un partage J.

Bien à vous

 

Retour au sujet principal

Laisser un commentaire

Votre adresse de messagerie ne sera pas publiée. Les champs obligatoires sont indiqués avec *

Ce site utilise Akismet pour réduire les indésirables. Apprenez comment les données de vos commentaires sont utilisées.