Comment déployer un logiciel au format EXE par GPO ?

I. Présentation

Aujourd'hui, j'ai envie de dire que l'on se retrouve pour l'épisode 2 de la série "Déploiement de logiciels par GPO" puisque j'ai déjà publié un article au sujet des logiciels au format MSI. Dans la continuité, je vais vous parler aujourd'hui du déploiement d'un logiciel au format EXE par GPO, et nous allons voir que c'est différent et que ce n'est pas toujours gagné d'avance !

? Le deuxième épisode est également disponible au format vidéo :

Pour les retardataires, retrouvez le premier épisode ci-dessous :

Comment déployer un logiciel au format MSI par GPO ?

Lorsqu'il s'agit de déployer un exécutable, il n'est pas possible d'utiliser une GPO de type "Installation de logiciels" comme pour un package MSI. Si l'on n’est pas équipé d'un logiciel tiers de déploiement de logiciels, c'est possible de le faire par GPO à l'aide d'un script qui va s'exécuter au démarrage de la machine.

L'idée est la suivante :

  • Récupérer le fichier exécutable à déployer
  • Rechercher les options pour installer cet exécutable en mode silencieux (et prier pour qu'il y en ait)
  • Créer le script pour installer le logiciel sur les postes
  • Faire en sorte que le logiciel n'essaie pas de s'installer à chaque fois

J'insiste sur l'étape n°2 "Rechercher les options pour installer cet exécutable en mode silencieux" : si l'exécutable n'a pas d'options pour une installation silencieuse, il ne sera pas possible de l'installer sans interaction de l'utilisateur. Cela remet en cause la possibilité de déployer cet exécutable par GPO en l'état....

II. Le partage pour héberger les exécutables

Ce que je vous propose, c'est d'utiliser le partage "Applications$" accessible à l'emplacement "\\SRV-ADDS-01\Applications$" et que nous avons appris à créer dans le premier article.

  • Nom du partage : Applications$
  • Droits sur le partage : "Tout le monde" en contrôle total (la restriction sera appliquée par les droits NTFS)
  • Chemin réseau : \\SRV-ADDS-01\Applications$

Je ne vais pas m'attarder sur cette partie puisque j'ai détaillé la création du partage dans la première vidéo.

III. Déployer un exécutable par GPO

Pour déployer un exécutable, au format EXE donc, par GPO, il faut avant tout faire preuve de méthodologie.

A. A la recherche du commutateur magique !

Après avoir récupéré le fichier d'installation, il faut regarder s'il propose des commutateurs pour l'installation silencieuse.

Pour visualiser les commutateurs disponibles sur un fichier exécutable, vous pouvez essayer les méthodes ci-dessous où l'on va chercher à consulter l'aide. Néanmoins, c'est possible qu'aucune ne fonctionne !

monfichier.exe /?
monfichier.exe /help
monfichier.exe --help

Je vous invite également à :

  • Consulter la documentation de l'éditeur du logiciel
  • Consulter page ci-dessous qui recense les commandes d'installation de nombreux logiciels (EXE et MSI)

En fait, cela dépend en partie du logiciel utilisé pour compiler le logiciel. Il y a quelques commutateurs classiques que vous pouvez tester et qui ont la réputation de permettre une installation silencieuse :

monfichier.exe /S
monfichier.exe /quiet
monfichier.exe /q

Prenons quelques exemples de logiciels que vous pourriez avoir besoin de déployer : Photofiltre 7 et SuperCopier. Pour Photofiltre 7, à première vue, les commutateurs d'aide ne retournent rien... Cependant, l'utilisation du commutateur "/S" permet de réaliser une installation silencieuse !

.\pf7-setup-fr-7.2.1.exe /S

Dans le même esprit, le logiciel SuperCopier supporte lui aussi ce commutateur :

.\supercopier-windows-x86_64-4.0.1.13-setup.exe /S

Voici deux exemples, mais qui ne sont pas une généralité. Maintenant que l'on connaît le commutateur à utiliser, on peut commencer à construire notre script.

B. Script PowerShell - Première étape : installer un exécutable

La tendance étant à l'utilisation de Windows 10, cela présente l'avantage d'avoir des machines équipées de PowerShell, dans une version récente. Pour créer le script, on pourrait tout bêtement inclure la ligne ".\pf7-setup-fr-7.2.1.exe /S" et puis basta... Mais bon, cela veut dire que l'on va chercher à installer le logiciel en boucle : pas top !

Il faut tenir compte de cette contrainte dans notre script : comment faire pour installer le logiciel une fois et ne pas chercher à le réinstaller à chaque fois, sauf s'il ne s'est pas bien installé ?

Commençons par nous occuper de la gestion de l'installation, et nous allons traiter cette contrainte juste après. Reprenons Photofiltre 7 en tant qu'exemple.

J'estime qu'il est préférable de copier en local l'exécutable le temps de l'installation et de le supprimer une fois l'opération terminée. Cela vous évitera aussi d'avoir des problèmes si vos partages ne sont pas déclarés comme emplacement sûrs.

Commençons par définir quatre variables :

### Variables
# Chemin UNC vers le partage qui contient l'exécutable
$SharedFolder = "\\srv-adds-01.it-connect.local\applications$"

# Chemin vers le dossier temporaire local sur le poste
$LocalFolder = "C:\TEMP"

# Nom de l'exécutable
$ExeName = "pf7-setup-fr-7.2.1.exe"

# Argument(s) à associer à l'exécutable
$ExeArgument = "/S"

Ces variables seront à modifier en fonction du logiciel à installer. Ensuite, nous allons :

  • Vérifier si le chemin réseau vers l'exécutable existe
  • Si c'est le cas, on crée le dossier temporaire en local et on copie l'exécutable à l'intérieur
  • Si l'exécutable est bien copié en local, on lance l'installation du logiciel via Start-Process et l'option -Wait pour rester en attente tout le temps que l'installation s'effectue
  • On supprime l'exécutable en local

Ce qui donne :

# Si le chemin réseau vers l'exécutable est valide, on continue
if(Test-Path "$SharedFolder\$ExeName"){

  # Créer le dossier temporaire en local et copier l'exécutable sur le poste
  New-Item -ItemType Directory -Path "$LocalFolder" -ErrorAction SilentlyContinue
  Copy-Item "$SharedFolder\$ExeName" "$LocalFolder" -Force

  # Si l'on trouve bien l'exécutable en local, on lance l'installation
  if(Test-Path "$LocalFolder\$ExeName"){
    Start-Process -Wait -FilePath "$LocalFolder\$ExeName" -ArgumentList "$ExeArgument"
  }

  # On supprime l'exécutable à la fin de l'installation
  Remove-Item "$LocalFolder\$ExeName"

}else{
  Write-Warning "L'exécutable ($ExeName) est introuvable sur le partage !"
}

À partir de là, nous avons un script de base qui est capable d'installer un logiciel à partir d'un exécutable stocké sur un emplacement réseau.

C. Script PowerShell - Deuxième étape : le logiciel est-il installé ?

Il est temps de traiter la contrainte évoquée précédemment : le logiciel est-il installé ? Il y a plusieurs façons de regarder si un logiciel est installé ou en tout cas d'en trouver une trace.

  • Le cmdlet PowerShell "Get-Package" (minimum PowerShell 5.1) qui permet de lister les logiciels installés sur la machine
  • Le Registre Windows qui contient des entrées pour tous les logiciels installés
  • Les fichiers créés lors de l'installation du logiciel

Si l'on prend l'exemple du logiciel Photofiltre 7 (qui remonte avec ce nom dans Windows) et de Get-Package, on peut tester que le logiciel est bien installé avec ce bout de code :

if(Get-Package -Name "Photofiltre 7"){
   Write-Output "Le logiciel Photofiltre 7 est présent sur la machine !"
}

Pour obtenir le nom exact du logiciel dans Windows, il faut l'installer une fois et exécuter la commande Get-Package pour récupérer le nom. Ce qui est dommage dans le cas de Photofiltre, c'est que la commande ne retourne pas la version installée :

EXE Silent install

On peut s'orienter vers le Registre Windows pour essayer de récupérer une information plus précise, mais avec Photofiltre ce n'est pas gagné. Pour lister les logiciels installés en s'appuyant sur le registre, il y a deux commandes intéressantes :

Sur une machine 32 bits :

Get-ItemProperty HKLM:\Software\Microsoft\Windows\CurrentVersion\Uninstall\* | Select-Object DisplayName, DisplayVersion, Publisher, InstallDate | Format-Table –AutoSize

Sur une machine 64 bits, il faut aussi s'intéresser à "Wow6432Node" :

Get-ItemProperty HKLM:\Software\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\* | Select-Object DisplayName, DisplayVersion, Publisher, InstallDate | Format-Table –AutoSize

Dans les deux cas, Photofiltre 7 ne ressort pas. Nous avons une troisième option : les fichiers dans le répertoire d'installation.

On sait que Photofiltre 7 s'installe dans le répertoire "C:\Program Files (x86)\PhotoFiltre 7" sur une machine 64 bits. On sait aussi que son exécutable, une fois installé, se nomme "PhotoFiltre7.exe". Si l'exécutable est présent, il y a de fortes chances que le logiciel soit correctement installé... On peut même récupérer la version exacte installée (on aura fini par l'avoir) :

(Get-ItemProperty -Path "C:\Program Files (x86)\PhotoFiltre 7\PhotoFiltre7.exe").VersionInfo.FileVersion

Ce qui retournera la valeur : 7.2.1.0 - De cette façon, on peut estimer que si l'on trouve l'exécutable, le logiciel est bien installé.

D. Script PowerShell - Troisième étape : le logiciel est-il à jour ?

Installer le logiciel une fois, c'est bien, le maintenir à jour c'est mieux. Nous allons exploiter le numéro de version que l'on peut récupérer au sein de l'exécutable pour comparer ce numéro à celui de l'exécutable que l'on veut installer.

On va ajouter trois variables à notre script

# Version cible de l'exécutable
$ExeVersion = "7.2.1.0"

# Chemin vers l'exécutable une fois l'installation terminée
$ExeInstallPath = "C:\Program Files (x86)\PhotoFiltre 7\PhotoFiltre7.exe"

# Le logiciel est-il déjà installé dans la bonne version ? Ici, sur une machine 64 bits
$InstalledVersion = (Get-ItemProperty -Path "C:\Program Files (x86)\PhotoFiltre 7\PhotoFiltre7.exe" -ErrorAction SilentlyContinue).VersionInfo.FileVersion

À partir de la valeur de $InstalledVersion (numéro de la version installée sur la machine) :

  • On peut déterminer si le logiciel est installé ou non : si $InstalledVersion est null c'est qu'il n'a pas trouvé l'exécutable
  • On peut comparer les deux numéros de version pour déterminer s'il faut mettre à jour ou non le logiciel

Ainsi, il y a deux cas pour lesquels il faut mettre à jour le logiciel :

  • $InstalledVersion est null
  • $InstalledVersion n'est pas null et $InstalledVersion est différent de $ExeVersion, autrement dit la version actuelle est différente de la version à installer

Ce qui se traduit de cette façon :

if(($InstalledVersion -eq $null) -or ($InstalledVersion -ne $null -and $InstalledVersion -ne $ExeVersion)){ <code> }

Nous venons de gérer notre contrainte initiale, afin d'avoir un script léger, mais fonctionnel qui va permettre d'installer le logiciel seulement s'il n'est pas déjà installé, et de le mettre à jour si nécessaire.

E. Tester le script en local et manuellement

Voici le script complet que je vous invite à tester en local et manuellement sur une machine type de votre parc. Ce script est une base qui ne demande qu'à être améliorée si vous le souhaitez. Le code est à mettre dans un fichier qu'il faut enregistrer avec l'extension PS1.

### Variables
# Chemin UNC vers le partage qui contient l'exécutable
$SharedFolder = "\\srv-adds-01.it-connect.local\applications$"

# Chemin vers le dossier temporaire local sur le poste
$LocalFolder = "C:\TEMP"

# Nom de l'exécutable
$ExeName = "pf7-setup-fr-7.2.1.exe"

# Argument(s) à associer à l'exécutable
$ExeArgument = "/S"

# Version cible de l'exécutable (obtenue sur une installation manuelle)
$ExeVersion = "7.2.1.0"

# Chemin vers l'exécutable une fois l'installation terminée
$ExeInstallPath = "C:\Program Files (x86)\PhotoFiltre 7\PhotoFiltre7.exe"

# Le logiciel est-il déjà installé dans la bonne version ?
$InstalledVersion = (Get-ItemProperty -Path "C:\Program Files (x86)\PhotoFiltre 7\PhotoFiltre7.exe" -ErrorAction SilentlyContinue).VersionInfo.FileVersion

if(($InstalledVersion -eq $null) -or ($InstalledVersion -ne $null -and $InstalledVersion -ne $ExeVersion)){

   # Si $InstalledVersion n'est pas null et que la version est différente : c'est qu'il faut faire une mise à jour
   if($InstalledVersion -ne $null){ 
      Write-Output "Le logiciel va être mis à jour : $InstalledVersion -> $ExeVersion"
   }

   # Si le chemin réseau vers l'exécutable est valide, on continue
   if(Test-Path "$SharedFolder\$ExeName"){

     # Créer le dossier temporaire en local et copier l'exécutable sur le poste
     New-Item -ItemType Directory -Path "$LocalFolder" -ErrorAction SilentlyContinue
     Copy-Item "$SharedFolder\$ExeName" "$LocalFolder" -Force

     # Si l'on trouve bien l'exécutable en local, on lance l'installation
     if(Test-Path "$LocalFolder\$ExeName"){
        Start-Process -Wait -FilePath "$LocalFolder\$ExeName" -ArgumentList "$ExeArgument"
     }

     # On supprime l'exécutable à la fin de l'installation
     Remove-Item "$LocalFolder\$ExeName"

   }else{

     Write-Warning "L'exécutable ($ExeName) est introuvable sur le partage !"
   }
}else{
   Write-Output "Le logiciel est déjà installé dans la bonne version !"
}

Une fois que le script fonctionne sur un poste, on peut le mettre en place dans une GPO pour automatiser le déploiement du logiciel. Pensez à le désinstaller sur le poste sur lequel vous avez fait le test pour retester par GPO.

F. Mettre en place le script dans une GPO

Basculez sur le contrôleur de domaine, où nous allons créer une nouvelle stratégie de groupe pour exécuter au démarrage de l'ordinateur le script PowerShell qui sert à installer le logiciel.

Avant cela, un petit rappel sur la politique d'exécution des scripts PowerShell :

Par défaut, une machine Windows 10 utilise la politique d'exécution "Restricted", ce qui signifie que les scripts PowerShell ne sont pas autorisés à s'exécuter. Forcément, cela va poser problème pour exécuter notre script par GPO.

Nous allons devoir modifier la politique d'exécution pour permettre l'exécution des scripts (vous l'avez peut-être déjà fait pour d'autres besoins) en ajustant la politique machine.

Ouvrez la console de Gestion des stratégies de groupe et créez une nouvelle GPO. Pour ma part, ce sera la GPO "Deployer-EXE-Photofiltre7".

Ensuite, parcourez les paramètres de GPO de cette façon :

Configuration ordinateur > Paramètres Windows > Scripts (démarrage/arrêt) > Démarrage

Dans le paramètre "Démarrage", accédez à l'onglet "Scripts PowerShell", cliquez sur "Ajouter" puis sur "Parcourir". Vous allez arriver dans un dossier au sein de la GPO où le chemin se termine par "Machine\Scripts\Startup" : c'est à cet endroit que vous devez coller votre script (voir copie d'écran ci-dessous).

Lorsque le script est positionné au bon endroit, sélectionnez-le et cliquez sur "Ouvrir". Il va être intégré à la GPO (voir ci-dessous), ensuite modifier le paramètre "Pour cet objet de stratégie de groupe, exécuter les scripts dans l'ordre suivant" et sélectionnez "Exécuter les scripts Windows PowerShell en premier", même si c'est le seul script de la GPO.

Pour finir avec cette GPO, nous allons modifier la politique d'exécution des scripts pour la définir sur "Remote Signed", accédez au paramètre suivant :

Configuration ordinateur > Modèle d'administration > Composants Windows > Windows PowerShell

Ouvrez le paramètre "Activer l'exécution des scripts", cliquez sur "Activé" et choisissez la valeur suivante : "Autoriser les scripts locaux et les scripts signés distants". Validez.

La GPO est prête ! Avant de basculer sur le poste client pour réaliser un test, liez la GPO à une OU pour valider le bon fonctionnement. Une OU de test bien sûr ?

IV. Tester la GPO

Pour finir, rendez-vous sur un poste client. Windows 10 pour ma part, il y a de fortes chances que ce soit le cas chez vous aussi. Il va falloir redémarrer la machine, avant cela ouvrez une console et exécutez la commande ci-dessous pour actualiser les GPO :

gpupdate /force

Puisqu'il s'agit d'un script qui s'exécute au démarrage de la machine, il est indispensable de redémarrer pour tester.

Au redémarrage, vous devez trouver le logiciel installé sur la machine ! Il se peut qu'il ne soit pas présent dès le démarrage de la machine, le script peut mettre quelques minutes à s'exécuter (comportement normal) : patientez avant de vous inquiéter ?

Par ailleurs, on constate que la politique d'exécution déployée par GPO s'applique bien sur la machine. C'est grâce à cette modification que le script a pu s'exécuter :

V. Conclusion

Le déploiement d'un logiciel au format exécutable par GPO n'est pas quelque chose de simple ! En comparaison du déploiement d'un logiciel au format MSI, c'est le jour et la nuit. Néanmoins, on a vu que c'est possible, mais que l'on doit avoir recours à un script PowerShell pour réaliser l'installation proprement : ne pas chercher à l'installer en boucle et gérer les mises à jour du logiciel dans le temps.

Il existe des alternatives à PowerShell, à l'ancienne j'ai envie de dire : un script Batch ou VBS. Je préfère m'orienter directement vers PowerShell et cette solution, bien que complexe au premier abord, fonctionne bien. Le tout c'est de bien tester  étape par étape et ensuite d'adapter les quelques variables dans le script. Si l'on fait abstraction des scripts, nous en revenons aux logiciels de déploiement, mais le challenge ici, c'était de vous proposer une solution à l'aide des outils de base.

Pour vous inspirer, en complément du script fourni dans cet exemple, je vous recommande de regarder le script que j'ai fait pour automatiser le déploiement de l'agent Fusion Inventory.

Maintenant, il ne me reste plus qu'à réfléchir à l'épisode 3 de cette série... Peut-être un premier pas vers les outils de déploiement ? ?

Partagez cet article Partager sur Twitter Partager sur Facebook Partager sur Linkedin Partager sur Google+ Envoyer par mail

Florian Burnel

Ingénieur système et réseau, cofondateur d'IT-Connect et Microsoft MVP "Cloud and Datacenter Management". Je souhaite partager mon expérience et mes découvertes au travers de mes articles. Généraliste avec une attirance particulière pour les solutions Microsoft et le scripting. Bonne lecture.

florian has 3285 posts and counting.See all posts by florian

11 thoughts on “Comment déployer un logiciel au format EXE par GPO ?

  • Très très bonne vidéo, l’installation de logiciels est parfois un casse tête. Certain logiciels ne sont pas prévus pour être déployés.

    Répondre
  • Bonjour, sympa l’article, merci pour le partage et tout ce que vous partager (site #1 de ma veille techno)

    Dans notre équipe d’admin système et reseau pour les collèges, on déploie jusqu’à 30 à 40 applications par GPO (avec un outil développé en interne qui fait la même chose que cet article)

    Pour trouver les commutateurs d’installations silencieuses : USSF (Universal Silent Switch Finder) .

    Certains Packages répondent aussi quand on les exécutent avec un /? (Batch)

    Quand les Package n’ont pas de switch d’installation, souvent on les installe sur une machine, on compresse le dossier d’installation et on le rends autoextractible qu’on déploie avec les paramètres de 7z)
    C’est clairement pas super propre (voire complètement , mais si ça nous évitent de faire une image machine a redéployer 150/200 fois pour 10,20 ou 30 Mb d’applications, on ne se gêne pas ! Surtout quand les délais sont court!!

    Répondre
    • Bonjour Tac,
      Merci pour ton retour d’expérience ! Je ne connaissais pas Universal Silent Switch Finder, je l’essaierai à l’occasion 😉
      Florian

      Répondre
    • Bonjour,

      je déploie actuellement des applications dans le même projet collèges après la centralisation de tous les collèges pouvez-vous me dire comment vous avez fait pour déployer et installer des application .EXE qui auront besoin de les suivre en cliquant sur suivant …suivant ….suivant plusieurs fois pour terminer l’installation contrairement a mozila ou google chrom
      je vous remercie par avance .

      Répondre
  • Très bon tuto, néanmoins par expériences, j’essai toujours de faire autrement, déployer les exe par GPO, les résultats sont souvent trop aléatoire dans le temps.
    En tout cas merci pour les pistes pour les numéro de version et notamment « Get-Package ».

    Répondre
  • Concernant le test de la version installée, je pense qu’il est préférable d’installer le logiciel si la version à installer est supérieure à la version déjà installée le cas échéant

    Répondre
    • Bonjour Thierry
      Oui c’est vrai, je le mentionne dans la vidéo. La condition mérite d’être revue pour comparer les numéros de versions différemment.
      Bon dimanche
      Florian

      Répondre
  • Bonjour,
    Un grand merci pour ce tuto!
    J’ai une petite question. Je souhaite utiliser cette technique pour installer un programme et, parmi mes arguments j’ai un chemin de fichier entre guillemets.

    en batch ça donne :
    « \\176.12.1.8\Application$\setup.exe » /adminfile « \\176.12.1.8\Application$\Personnalisation.msp »

    comment dois-je écrire la variable $ExeArgument ?

    Merci d’avance! 🙂

    Répondre
    • Hello Brisfan 🙂

      Tu peux essayer comme ça (sous réserve qu’il n’y ait pas de variables dans cette chaîne) :
      $ExeArgument = ‘\\176.12.1.8\Application$\setup.exe /adminfile « \\176.12.1.8\Application$\Personnalisation.msp »‘

      Redis-moi 🙂
      Florian

      Répondre
  • Bonjour,
    1- Je souhaite modifier le clavier Français/Canada vers le clavier Français/Canada Multilingue. Je sais que c’est possible de le faire via le panneau de configuration. Par ailleurs, je voudrais le changer par gpo. Auriez-vous une procédure?
    2- Je dois installer les pilotes Nvidia exécutable par gpo(group Policy).

    Merci d’avance

    Répondre

Laisser un commentaire

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

 

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