Comment déployer un logiciel au format EXE par GPO ?
jeudi 25 février 2021 à 12:45I. 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 :
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 ?
The post Comment déployer un logiciel au format EXE par GPO ? first appeared on IT-Connect.