Bonjour,
Existe-t-il un moyen de lister tous les paquets installés sur une machine ainsi que leur état et leur audit depuis un setup.py ?
L'idée serait de mettre en place des remédiations automatiques dans certains cas avec des installations problématiques.
Cordialement,
Lister les paquets et leur état
Règles du forum
Règles du forum communautaire
* English support on www.reddit.com/r/wapt
* Le support communautaire en français se fait sur ce forum
* Merci de préfixer le titre du topic par [RESOLU] s'il est résolu.
* Merci de ne pas modifier un topic qui est taggé [RESOLU]. Ouvrez un nouveau topic en référençant l'ancien
* Préciser version de WAPT installée, version complète ET numéro de build (2.2.1.11957 / 2.2.2.12337 / etc.) AINSI QUE l'édition Enterprise / Discovery
* Les versions 1.8.2 et antérieures ne sont plus maintenues. Les seules questions acceptées vis à vis de la version 1.8.2 sont liés à la mise à jour vers une version supportée (2.1, 2.2, etc.)
* Préciser OS du serveur (Linux / Windows) et version (Debian Buster/Bullseye - CentOS 7 - Windows Server 2012/2016/2019)
* Préciser OS de la machine d'administration/création des paquets et de la machine avec l'agent qui pose problème le cas échéant (Windows 7 / 10 / 11 / Debian 11 / etc.)
* Eviter de poser plusieurs questions lors de l'ouverture de topic, sinon il risque d'être ignorer. Si plusieurs sujet, ouvrir plusieurs topic, et de préférence les uns après les autres et pas tous en même temps (ie ne pas spammer le forum).
* Inclure directement les morceaux de code, les captures d'écran et autres images directement dans le post. Les liens vers les pastebin, les bitly et autres sites tierces seront systématiquement supprimés.
* Comme tout forum communautaire, le support est fait bénévolement par les membres. Si vous avez besoin d'un support commercial, vous pouvez contacter le service commercial Tranquil IT au 02.40.97.57.55
Règles du forum communautaire
* English support on www.reddit.com/r/wapt
* Le support communautaire en français se fait sur ce forum
* Merci de préfixer le titre du topic par [RESOLU] s'il est résolu.
* Merci de ne pas modifier un topic qui est taggé [RESOLU]. Ouvrez un nouveau topic en référençant l'ancien
* Préciser version de WAPT installée, version complète ET numéro de build (2.2.1.11957 / 2.2.2.12337 / etc.) AINSI QUE l'édition Enterprise / Discovery
* Les versions 1.8.2 et antérieures ne sont plus maintenues. Les seules questions acceptées vis à vis de la version 1.8.2 sont liés à la mise à jour vers une version supportée (2.1, 2.2, etc.)
* Préciser OS du serveur (Linux / Windows) et version (Debian Buster/Bullseye - CentOS 7 - Windows Server 2012/2016/2019)
* Préciser OS de la machine d'administration/création des paquets et de la machine avec l'agent qui pose problème le cas échéant (Windows 7 / 10 / 11 / Debian 11 / etc.)
* Eviter de poser plusieurs questions lors de l'ouverture de topic, sinon il risque d'être ignorer. Si plusieurs sujet, ouvrir plusieurs topic, et de préférence les uns après les autres et pas tous en même temps (ie ne pas spammer le forum).
* Inclure directement les morceaux de code, les captures d'écran et autres images directement dans le post. Les liens vers les pastebin, les bitly et autres sites tierces seront systématiquement supprimés.
* Comme tout forum communautaire, le support est fait bénévolement par les membres. Si vous avez besoin d'un support commercial, vous pouvez contacter le service commercial Tranquil IT au 02.40.97.57.55
Bonjour,
je ne suis pas très sûr de ce que vous cherchez à faire mais dans un de mes paquets j'ai quelque chose dans le genre :
Après.. tout cela est déjà visible dans la console WAPT.
Cdt.
je ne suis pas très sûr de ce que vous cherchez à faire mais dans un de mes paquets j'ai quelque chose dans le genre :
Code : Tout sélectionner
package_list = WAPT.installed_package_names() # recup les paquets installés sur la machine
for package in sorted(package_list):
WAPT.audit(package, force=False) # fait un audit du paquet pour chaque paquet présent dans la listeAprès.. tout cela est déjà visible dans la console WAPT.
Cdt.
WAPT Discovery -- 2.6.1.17705 -- SRV Ubuntu 24.04 arm64
WAPT Enterprise -- 2.6.1.17576 -- SRV Ubuntu 22.04
WAPT Enterprise -- 2.6.1.17576 -- SRV RHEL 9 --//-- Dépôts secondaires -- Rocky 9
adm : W11pro
WAPT Enterprise -- 2.6.1.17576 -- SRV Ubuntu 22.04
WAPT Enterprise -- 2.6.1.17576 -- SRV RHEL 9 --//-- Dépôts secondaires -- Rocky 9
adm : W11pro
Bonjour,
Cela ne me permet pas d'obtenir le statut.
L'idée, c'est par exemple, je veux installer les microsoft visual c++ 2015-2022, mais windows étant un outil formidable, l'installation du msi requiert de désinstaller l'ancien, mais le fichier d'installation a depuis été supprimé.
L'installateur part donc en erreur. Il est impossible de désinstaller, même problème, il faut donc purger la base de registre pour faire oublier à windows la présence de cette installation et donc d'en faire une nouvelle.
Ce type de cas se produit très souvent sur plein de produit.
En faisant un paquet médiation, je liste toutes les erreurs en cours et je lance une remédiation. Dans l'exemple, purger la base de registre pour permettre ensuite la bonne installation.
Actuellement, nous l'avons dans la console, et nous le faisons à la main. Mais avec 10 000 postes à gérer dont 450 avec des erreurs, c'est vite intenable.
On a de tout, du keepassxc, seafile, jabra, etc.
Certaines erreurs sont dues à notre précédente solution et n'apparaissent pas sur les postes installés avec WAPT.
Bref, l'idée est de gérer tout ça au maximum automatiquement et sans être derrière les postes tout le temps.
Sachant qu'un poste corrigé ne veut pas dire que le problème ne se posera pas à la prochaine mise à jour. Cela dépend beaucoup d'installateurs (souvent très bien codé !
)
Cela ne me permet pas d'obtenir le statut.
L'idée, c'est par exemple, je veux installer les microsoft visual c++ 2015-2022, mais windows étant un outil formidable, l'installation du msi requiert de désinstaller l'ancien, mais le fichier d'installation a depuis été supprimé.
L'installateur part donc en erreur. Il est impossible de désinstaller, même problème, il faut donc purger la base de registre pour faire oublier à windows la présence de cette installation et donc d'en faire une nouvelle.
Ce type de cas se produit très souvent sur plein de produit.
En faisant un paquet médiation, je liste toutes les erreurs en cours et je lance une remédiation. Dans l'exemple, purger la base de registre pour permettre ensuite la bonne installation.
Actuellement, nous l'avons dans la console, et nous le faisons à la main. Mais avec 10 000 postes à gérer dont 450 avec des erreurs, c'est vite intenable.
On a de tout, du keepassxc, seafile, jabra, etc.
Certaines erreurs sont dues à notre précédente solution et n'apparaissent pas sur les postes installés avec WAPT.
Bref, l'idée est de gérer tout ça au maximum automatiquement et sans être derrière les postes tout le temps.
Sachant qu'un poste corrigé ne veut pas dire que le problème ne se posera pas à la prochaine mise à jour. Cela dépend beaucoup d'installateurs (souvent très bien codé !
C'est très intéressant car je viens justement de passer pas mal de temps pour trouver une solution pour le client Nextcloud qui nous produit pas mal d'erreur de ce type.
J'ai corrigé seulement ce package avec des try catch mais votre idée d'un paquet de remédiation général est pas mal, je m'abonne au topic si y'a une solution qui tombe.
Je purge ceci dans le registre :
J'ai corrigé seulement ce package avec des try catch mais votre idée d'un paquet de remédiation général est pas mal, je m'abonne au topic si y'a une solution qui tombe.
Je purge ceci dans le registre :
Code : Tout sélectionner
HKLM\SOFTWARE\\Microsoft\Windows\CurrentVersion\Uninstall\{guid}
HKLM\SOFTWARE\Classes\Installer\Products\{guid_key_wininstaller}Bonjour,
par "status", est-ce si le paquet est en "OK"/"WARNING"/"ERROR" ?
Si c'est le cas, alors essayez peut-être :
un simple print devrait afficher le status :
mais vous pouvez ensuite faire par exemple un
edit : après il faut bien entendu que le paquet en question soit déjà présent sur la machine
par "status", est-ce si le paquet est en "OK"/"WARNING"/"ERROR" ?
Si c'est le cas, alors essayez peut-être :
Code : Tout sélectionner
package = WAPT.is_installed('nom_de_votre_paquet')
package_status = package['install_status'] # recupère si status OK/WARNING/ERRORCode : Tout sélectionner
print(package_status)Code : Tout sélectionner
if package_status == 'ERROR' :
ce que vous voulez faire ensuiteedit : après il faut bien entendu que le paquet en question soit déjà présent sur la machine
WAPT Discovery -- 2.6.1.17705 -- SRV Ubuntu 24.04 arm64
WAPT Enterprise -- 2.6.1.17576 -- SRV Ubuntu 22.04
WAPT Enterprise -- 2.6.1.17576 -- SRV RHEL 9 --//-- Dépôts secondaires -- Rocky 9
adm : W11pro
WAPT Enterprise -- 2.6.1.17576 -- SRV Ubuntu 22.04
WAPT Enterprise -- 2.6.1.17576 -- SRV RHEL 9 --//-- Dépôts secondaires -- Rocky 9
adm : W11pro
Il doit peut-être avoir plus simple, mais ceci marche pour avoir la liste des paquets dont l'installation est en erreur.
Reste encore à tenter de corriger en trouvant quoi corriger
Code : Tout sélectionner
for package in WAPT.waptdb.installed_packages_inventory():
if package[5] == 'ERROR':
print(package[1])
C'est encore en test chez nous, mais ça donne ça
Je garde en mémoire dans un json tous les paquets tenté pour ne faire qu'une seule tentative.
Cela donne pour l'instant de bons résultats
Je garde en mémoire dans un json tous les paquets tenté pour ne faire qu'une seule tentative.
Cela donne pour l'instant de bons résultats
Code : Tout sélectionner
# -*- coding: utf-8 -*-
from setuphelpers import *
import json
import datetime
import winreg
import re
from contextlib import suppress
import itertools
# Dictionnaire package wapt => nom de l'application en format regex
dict_package_app = {
"tis-chrome" : "Google Chrome",
"tis-element" : "Element",
"tis-googleearth" : "Google Earth Pro",
"tis-glpi-agent" : "GLPI agent [0-9.]+",
"tis-keepassxc" : "KeePassXC",
"tis-libreoffice-fresh" : "LibreOffice [0-9.]+",
"tis-microsoft-edge" : "Microsoft Edge",
"tis-onlyoffice-desktop" : "ONLYOFFICE [0-9.]+ \(x64\)",
"tis-oracle-java8-jre-free" : "Java 8 Update [0-9]+(| x64 bit)",
"tis-pdf24-creator" : "PDF24 Creator",
"tis-seafile" : "Seafile [0-9.]+",
"tis-microsoft-teams" : "Teams Machine-Wide Installer",
"tis-teamviewer" : "TeamViewer",
"tis-vcredist2015-2022" : "Microsoft Visual C\+\+ (2015-2022 Redistributable \(x(86|64)\)|2022 X64 Additional Runtime) - [0-9.]+",
"tis-wazo" : "Wazo Desktop",
"tis-webex" : "Webex",
"tis-webview2" : "Microsoft Edge WebView2 Runtime",
"tis-zoom" : "Zoom Workplace \(64-bit\)"
}
json_file = r"C:\Windows\wapt\autofix.json"
def install():
generate_json()
def audit():
if not isfile(json_file):
generate_json()
with open(json_file) as file:
status = json.load(file)
return_value = "OK"
packages_installed = set() # Contient la liste des paquets installés pour purge le json ensuite
for wapt_installed_package in WAPT.waptdb.installed_status(include_errors=True):
packages_installed.add(wapt_installed_package['package'])
# Gestion des installation en erreur si le paquet est déclaré dans dict_package_app
# Tentative de purge de la des anciennes installations de la base de registre
if wapt_installed_package['install_status'] == "ERROR" and wapt_installed_package['package'] in dict_package_app:
if status['install'].get(wapt_installed_package['package'], False):
print(f"Réparation de l'installation du paquet {wapt_installed_package['package']} déjà tenté")
return_value = "ERROR"
else:
print(f"Tentative de réparation de l'installation du paquet {wapt_installed_package['package']}")
if WAPT.waptserver.available():
status['install'][wapt_installed_package['package']] = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
delete_key("Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall", 'DisplayName', dict_package_app[wapt_installed_package['package']])
delete_key("SOFTWARE\\Classes\\Installer\\Products", 'ProductName', dict_package_app[wapt_installed_package['package']])
try:
WAPT.install(wapt_installed_package['package'])
except:
print(f"Erreur d'installation de {wapt_installed_package['package']}")
if return_value != "ERROR":
return_value = "WARNING"
else:
print("Serveur WAPT non joignable - une tentative sera faite au prochain audit")
# Si le paquet n'est pas en erreur, on le retire du json s'il existe
elif status['install'].get(wapt_installed_package['package'], False):
del status['install'][wapt_installed_package['package']]
# Gestion des audit en erreur
# Tentative d'une installation forcée
if wapt_installed_package['last_audit_status'] == "ERROR" and wapt_installed_package['package'] != "tis-autofix-installation":
if status['audit'].get(wapt_installed_package['package'], False):
print(f"Réparation de l'audit du paquet {wapt_installed_package['package']} déjà tenté")
return_value = "ERROR"
else:
print(f"Tentative de réparation de l'audit du paquet {wapt_installed_package['package']}")
if WAPT.waptserver.available():
status['audit'][wapt_installed_package['package']] = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
try:
WAPT.install(wapt_installed_package['package'], force=True)
except:
print(f"Erreur d'installation de {wapt_installed_package['package']}")
if return_value != "ERROR":
return_value = "WARNING"
else:
print("Serveur WAPT non joignable - une tentative sera faite au prochain audit")
# Si le paquet n'est pas en erreur, on le retire du json s'il existe
elif status['audit'].get(wapt_installed_package['package'], False):
del status['audit'][wapt_installed_package['package']]
# Purge des anciennes tentative si le paquet n'est plus sur la machine
for wapt_installed_package in status['install'].copy():
if wapt_installed_package not in packages_installed:
del status['install'][wapt_installed_package]
for wapt_installed_package in status['audit'].copy():
if wapt_installed_package not in packages_installed:
del status['audit'][wapt_installed_package]
with open(json_file, 'w') as autofix:
json.dump(status, autofix)
return return_value
def uninstall():
if isfile(json_file):
remove_file(json_file)
def generate_json():
if not isdir(r'C:\Windows\wapt'):
mkdirs(r'C:\Windows\wapt')
status = {}
status['install'] = {}
status['audit'] = {}
with open(json_file, 'w') as autofix:
json.dump(status, autofix)
def delete_key(key_uninstall, key_value, key_search):
for subkey in subkeys(key_uninstall):
appkey = winreg.OpenKey(winreg.HKEY_LOCAL_MACHINE, rf"{key_uninstall}\{subkey}", 0, winreg.KEY_READ)
try:
key_find = reg_getvalue(appkey, key_value, '')
if re.match(f"^{key_search}$", key_find):
print(f'Suppression clé {key_uninstall}\{subkey}')
winreg.DeleteKey(appkey, '')
except FileNotFoundError:
pass
def subkeys(path, hkey=HKEY_LOCAL_MACHINE):
with suppress(WindowsError), winreg.OpenKey(hkey, path, 0, winreg.KEY_READ) as k:
for i in itertools.count():
yield winreg.EnumKey(k, i)
Dernière modification par Mikael S le 24 mars 2026 - 07:59, modifié 1 fois.
Merci pour le partage !
Mikael S a écrit : ↑16 mars 2026 - 13:18 C'est encore en test chez nous, mais ça donne ça
Je garde en mémoire dans un json tous les paquets tenté pour ne faire qu'une seule tentative.
Cela donne pour l'instant de bons résultats
Code : Tout sélectionner
# -*- coding: utf-8 -*- from setuphelpers import * import json import datetime import winreg import re # Dictionnaire package wapt => nom de l'application en format regex dict_package_app = { "tis-chrome" : "Google Chrome", "tis-element" : "Element", "tis-googleearth" : "Google Earth Pro", "tis-glpi-agent" : "GLPI agent [0-9.]+", "tis-keepassxc" : "KeePassXC", "tis-libreoffice-fresh" : "LibreOffice [0-9.]+", "tis-microsoft-edge" : "Microsoft Edge", "tis-oracle-java8-jre-free" : "Java 8 Update [0-9]+(| x64 bit)", "tis-pdf24-creator" : "PDF24 Creator", "tis-seafile" : "Seafile [0-9.]+", "tis-microsoft-teams" : "Teams Machine-Wide Installer", "tis-teamviewer" : "TeamViewer", "tis-vcredist2015-2022" : "Microsoft Visual C++ 2015-2022 Redistributable \(x(86|64)\) - [0-9.]+", "tis-wazo" : "Wazo Desktop", "tis-webex" : "Webex", "tis-webview2" : "Microsoft Edge WebView2 Runtime", "tis-zoom" : "Zoom Workplace \(64-bit\)" } json_file = r"C:\Windows\wapt\autofix.json" def install(): if not isfile(json_file) or force: generate_json() def audit(): if not isfile(json_file): generate_json() with open(json_file) as file: status = json.load(file) return_value = "OK" packages_installed = set() # Contient la liste des paquets installés pour purge le json ensuite for wapt_installed_package in WAPT.waptdb.installed_status(include_errors=True): packages_installed.add(wapt_installed_package['package']) # Gestion des installation en erreur si le paquet est déclaré dans dict_package_app # Tentative de purge de la des anciennes installations de la base de registre if wapt_installed_package['install_status'] == "ERROR" and wapt_installed_package['package'] in dict_package_app: if status['install'].get(wapt_installed_package['package'], False): print(f"Réparation de l'installation du paquet {wapt_installed_package['package']} déjà tenté") return_value = "ERROR" else: print(f"Tentative de réparation de l'installation du paquet {wapt_installed_package['package']}") if WAPT.waptserver.available(): status['install'][wapt_installed_package['package']] = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S") delete_key("Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall", 'DisplayName', dict_package_app[wapt_installed_package['package']]) if iswin64(): delete_key("Software\\WOW6432Node\\Microsoft\\Windows\\CurrentVersion\\Uninstall", 'DisplayName', dict_package_app[wapt_installed_package['package']]) delete_key("SOFTWARE\\Classes\\Installer\\Products", 'ProductName', dict_package_app[wapt_installed_package['package']]) try: WAPT.install(wapt_installed_package['package']) except: print(f"Erreur d'installation de {wapt_installed_package['package']}") if return_value != "ERROR": return_value = "WARNING" else: print("Serveur WAPT non joignable - une tentative sera faite au prochain audit") # Si le paquet n'est pas en erreur, on le retire du json s'il existe elif status['install'].get(wapt_installed_package['package'], False): del status['install'][wapt_installed_package['package']] # Gestion des audit en erreur # Tentative d'une installation forcée if wapt_installed_package['last_audit_status'] == "ERROR" and wapt_installed_package['package'] != "tis-autofix-installation": if status['audit'].get(wapt_installed_package['package'], False): print(f"Réparation de l'audit du paquet {wapt_installed_package['package']} déjà tenté") return_value = "ERROR" else: print(f"Tentative de réparation de l'audit du paquet {wapt_installed_package['package']}") if WAPT.waptserver.available(): status['audit'][wapt_installed_package['package']] = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S") try: WAPT.install(wapt_installed_package['package'], force=True) except: print(f"Erreur d'installation de {wapt_installed_package['package']}") if return_value != "ERROR": return_value = "WARNING" else: print("Serveur WAPT non joignable - une tentative sera faite au prochain audit") # Si le paquet n'est pas en erreur, on le retire du json s'il existe elif status['audit'].get(wapt_installed_package['package'], False): del status['audit'][wapt_installed_package['package']] # Purge des anciennes tentative si le paquet n'est plus sur la machine for wapt_installed_package in status['install'].copy(): if wapt_installed_package not in packages_installed: del status['install'][wapt_installed_package] for wapt_installed_package in status['audit'].copy(): if wapt_installed_package not in packages_installed: del status['audit'][wapt_installed_package] with open(json_file, 'w') as autofix: json.dump(status, autofix) return return_value def uninstall(): if isfile(json_file): remove_file(json_file) def generate_json(): if not isdir(r'C:\Windows\wapt'): mkdirs(r'C:\Windows\wapt') status = {} status['install'] = {} status['audit'] = {} with open(json_file, 'w') as autofix: json.dump(status, autofix) def delete_key(uninstall, key_value, key_search): with winreg.OpenKey(winreg.HKEY_LOCAL_MACHINE, uninstall) as key: i = 0 while True: try: subkey = winreg.EnumKey(key, i) appkey = winreg.OpenKey(winreg.HKEY_LOCAL_MACHINE, "%s\\%s" % (uninstall, subkey)) key_find = reg_getvalue(appkey, key_value, '') if re.match(f"^{key_search}$", key_find): print(f'Suppression clé {uninstall}\{subkey}') registry_deletekey(root=HKEY_LOCAL_MACHINE, path=uninstall, keyname=subkey, force=True, recursive=True) i += 1 except WindowsError as e: # WindowsError: [Errno 259] No more data is available if e.winerror == 259: break else: raise
