List the packages and their status

Questions about WAPT Packaging / Requests and help regarding Wapt packages.
Forum Rules
Community Forum Rules
* English support on www.reddit.com/r/wapt
* French community support is available on this forum
* Please prefix the topic title with [RESOLVED] if it is resolved.
* Please do not edit a topic that is tagged [RESOLVED]. Open a new topic referencing the old one.
* Specify the installed WAPT version, full version, and build number (2.2.1.11957 / 2.2.2.12337 / etc.) as well as the Enterprise/Discovery edition.
* Versions 1.8.2 and earlier are no longer supported. The only questions accepted regarding version 1.8.2 are related to upgrading to a supported version (2.1, 2.2, etc.).
* Specify the server OS (Linux/Windows) and version (Debian Buster/Bullseye - CentOS 7 - Windows Server 2012/2016/2019).
* Specify the OS of the administration/package creation machine and the machine with the problematic agent, if applicable (Windows 7/10/11/Debian 11/etc.).
* Avoid asking multiple questions when opening a topic, otherwise it may be ignored. If there are multiple topics, open separate topics, preferably one after the other and not all at the same time (i.e., do not spam the forum).
* Include code snippets, screenshots, and other images directly in the post. Links to Pastebin, Bitly, and other third-party sites will be systematically removed.
* As with any community forum, support is provided voluntarily by members. If you require commercial support, you can contact Tranquil IT's sales department at 02.40.97.57.55
Mikael S
Messages: 37
Registration: January 20, 2025 - 3:54 PM

October 9, 2026 - 2:42 PM

Good morning,

A small update after all this time. We've had very good results since then

Code: Select all

# -*- coding: utf-8 -*-
import datetime
import itertools
import json
import re
import winreg
from contextlib import suppress

from setuphelpers import *

# Dictionnaire package wapt => nom de l'application en format regex
dict_package_app = {
    "tis-adobereader" : r"Adobe Acrobat \(64-bit\)",
    "tis-affinity" : "Affinity",
    "tis-affinity-designer" : "Affinity Designer",
    "tis-affinity-photo" : "Affinity Photo",
    "tis-affinity-publisher" : "Affinity Publisher",
    "tis-affinity-designer-2" : "Affinity Designer 2",
    "tis-affinity-photo-2" : "Affinity Photo 2",
    "tis-affinity-publisher-2" : "Affinity Publisher 2",
    "tis-anaconda3": "Anaconda3 [0-9].*",
    "tis-audacity" : "Audacity [0-9.]+",
    "tis-bcu-bios-hp": "HP BIOS Configuration Utility",
    "tis-beyondtrust-rs" : "BeyondTrust Jump Client - pmad.unistra.fr",
    "tis-calculator" : r"C:\\Program Files\\WindowsApps\\Microsoft\.WindowsCalculator.*",
    "tis-cartes" : r"C:\\Program Files\\WindowsApps\\Microsoft\.WindowsMaps_.*",
    "tis-chrome" : "Google Chrome",
    "tis-disable-telemetry" : "Microsoft Update Health Tools",
    "tis-element" : "Element",
    "tis-extensions-de-support-web" : r"C:\\Program Files\\WindowsApps\\Microsoft\.WebMediaExtensions_.*",
    "tis-firefox" : r"Mozilla Firefox \(x(86|64) [a-zA-Z -]+\)",
    "tis-firefox-esr" : r"Mozilla Firefox ESR \(x(86|64) [a-zA-Z -]+\)",
    "tis-forticlient-vpn" : "FortiClient VPN",
    "tis-foxit-pdfeditor-11" : "Foxit PDF Editor",
    "tis-foxit-pdfeditor-12" : "Foxit PDF Editor",
    "tis-foxit-pdfeditor-13" : "Foxit PDF Editor",
    "tis-foxit-pdfeditor-14" : "Foxit PDF Editor",
    "tis-foxit-pdfeditor-2024" : "Foxit PDF Editor",
    "tis-gimp" : "GIMP [0-9-.]+",
    "tis-googleearth" : "Google Earth Pro",
    "tis-glpi-agent" : "GLPI Agent [0-9.]+",
    "tis-keepassxc" : "KeePassXC",
    "tis-libreoffice-fresh" : "LibreOffice [0-9.]+",
    "tis-microsoft-windowsalarms" : r"C:\\Program Files\\WindowsApps\\Microsoft\.WindowsAlarms.*",
    "tis-microsoft-edge" : "Microsoft Edge(| Update)",
    "tis-microsoft-photos" : r"C:\\Program Files\\WindowsApps\\Microsoft\.Windows\.Photos.*",
    "tis-microsoft-soundrecorder" : r"C:\\Program Files\\WindowsApps\\Microsoft\.WindowsSoundRecorder.*",
    "tis-microsoft-stickynotes" : r"C:\\Program Files\\WindowsApps\\\Microsoft\.MicrosoftStickyNotes.*",
    "tis-microsoft-teams" : "Teams Machine-Wide Installer",
    "tis-microsoft-windows-camera"  : r"C:\\Program Files\\WindowsApps\\Microsoft\.WindowsCamera.*",
    "tis-naps2" : "NAPS2",
    "tis-windows-notepad" : r"C:\\Program Files\\WindowsApps\\Microsoft\.WindowsNotepad.*",
    "tis-onlyoffice-desktop" : r"ONLYOFFICE [0-9.]+ \(x64\)",
    "tis-oracle-java8-jre-free" : "Java 8 Update [0-9]+(| x64 bit)",
    "tis-paint.net" : "(paint.net|Paint.NET)",
    "tis-paint-3d" : r"C:\\Program Files\\WindowsApps\\Microsoft\.MSPaint.*",
    "tis-pdf24-creator" : "PDF24 Creator",
    "tis-putty" : r"PuTTY release [0-9.]+( \(64-bit\)|)",
    "tis-rtools" : "Rtools [0-9 ().-]+",
    "tis-seafile" : "Seafile [0-9.]+",
    "tis-sphinx-iq3" : "SphinxIQ3",
    "tis-spyder" : "Spyder [0-9]",
    "tis-stormshield-vpn" : "Stormshield SSL VPN Client",
    "tis-teamviewer" : "TeamViewer( [0-9]+|)",
    "tis-thunderbird" : "Mozilla Thunderbird .*",
    "tis-vcredist2015-2022" : r"Microsoft Visual C\+\+ (2015-(2019|2022) Redistributable \(x(86|64)\)|(2019|2022) X(86|64) (Additional|Minimum) Runtime) - [0-9.]+",
    "tis-wazo" : "Wazo Desktop",
    "tis-webex" : "(Webex|Cisco Webex Meetings)",
    "tis-webview2" : "Microsoft Edge WebView2 Runtime",
    "tis-withsecure" : "WithSecure™ Client Security Premium",
    "tis-zoom" : r"Zoom Workplace \(64-bit\)"
}

# Liste des appx gérées
appx = [
    "tis-calculator",
    "tis-cartes",
    "tis-extensions-de-support-web",
    "tis-microsoft-windowsalarms",
    "tis-paint-3d",
    "tis-microsoft-photos",
    "tis-microsoft-soundrecorder",
    "tis-microsoft-stickynotes",
    "tis-microsoft-windows-camera",
    "tis-windows-notepad"
]

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\\WOW6432Node\\Microsoft\\Windows\\CurrentVersion\\Uninstall", 'DisplayName', dict_package_app[wapt_installed_package['package']], winreg.KEY_WOW64_32KEY)
                    delete_key("SOFTWARE\\Classes\\Installer\\Products", 'ProductName', dict_package_app[wapt_installed_package['package']])
                    delete_key("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Appx\\AppxAllUserStore\\Applications", 'Path', dict_package_app[wapt_installed_package['package']])

                    try:
                        WAPT.install(wapt_installed_package['package'], force=True)
                    except:
                        print(f"Erreur d'installation de {wapt_installed_package['package']}")
                        if not status['wmi'] and WAPT.is_installed("tis-script-cache-wmi-reparer") and wapt_installed_package['package'] in appx:
                            print('Tentative de réparation du cache wmi')
                            WAPT.install("tis-script-cache-wmi-reparer", force=True)
                            status['wmi'] = True
                            print('Une tentative sera faite au prochain audit')
                            del status['install'][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) and wapt_installed_package['install_status'] == "OK":
            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'] not in ("tis-audit-battery", "tis-autofix-installation", "tis-pending-reboot-notification"):
            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]

    # Réinitialisation du status wmi si plus aucune appx problématique
    appx_en_erreur = False
    if any(package in appx for package in status['install']):
        appx_en_erreur = True

    if not appx_en_erreur:
        status['wmi'] = False

    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'] = {}
    status['wmi'] = False

    with open(json_file, 'w') as autofix:
        json.dump(status, autofix)

def delete_key(key_uninstall, key_value, key_search, access=winreg.KEY_WOW64_64KEY):
    for subkey in subkeys(key_uninstall, access):
        appkey = winreg.OpenKey(winreg.HKEY_LOCAL_MACHINE, rf"{key_uninstall}\{subkey}", 0, winreg.KEY_READ | access)

        key_find = reg_getvalue(appkey, key_value, '')

        if re.match(f"^{key_search}$", key_find):
            print(rf'Suppression clé {key_uninstall}\{subkey}')
            registry_deletekey(winreg.HKEY_LOCAL_MACHINE, key_uninstall, subkey, force=True, recursive=True)

def subkeys(path, access=winreg.KEY_WOW64_64KEY, hkey=HKEY_LOCAL_MACHINE,):
    with suppress(WindowsError), winreg.OpenKey(hkey, path, 0, winreg.KEY_READ | access) as k:
        for i in itertools.count():
            yield winreg.EnumKey(k, i)
For apps, a fallback is sometimes useful when the wmi cache is corrupted, but in reality, it is rarely used.
There is a function in wapt to restore the cache but it only returns an error.
Here is a code that works

Code: Select all

# -*- coding: utf-8 -*-
from setuphelpers import *
import glob
import time


def install():
    if force:
        # https://woshub.com/wmi-troubleshooting/
        # arret des services associé à winmgmt
        set_service_start_mode("winmgmt", "Disabled")

        if service_installed('winmgmt') and service_is_running ('winmgmt'):
            run('cmd /c net stop winmgmt /y')

        print('Commande : winmgmt /resetrepository')
        run('cmd /C winmgmt /resetrepository')

        print('Commande : winmgmt /resyncperf')
        run('cmd /C winmgmt /resyncperf')

        print(r'Commande : regsvr32 /s %systemroot%\system32\scecli.dll')
        run(r'cmd /C regsvr32 /s %systemroot%\system32\scecli.dll')

        print(r'Commande : regsvr32 /s %systemroot%\system32\userenv.dll')
        run(r'cmd /C regsvr32 /s %systemroot%\system32\userenv.dll')

        for file in glob.glob(r'c:\windows\system32\wbem\*.dll'):
            print(rf'Commande : regsvr32 /s {file}')
            run_notfatal(rf'cmd "/C regsvr32 /s {file}"')

        for file in glob.glob(r'c:\windows\system32\wbem\*.mof'):
            if "uninstall" not in file.lower():
                print(rf'Commande : mofcomp {file}')
                run_notfatal(rf'cmd "/C mofcomp {file}"')

        for file in glob.glob(r'c:\windows\system32\wbem\*.mfl'):
            if "uninstall" not in file.lower():
                print(rf'Commande : mofcomp {file}')
                run_notfatal(rf'cmd "/C mofcomp {file}"')

        if service_installed('winmgmt') and not service_is_running ('winmgmt'):
            print('Relance du service winmgmt')
            service_start('winmgmt')

        set_service_start_mode("winmgmt", "Auto")

        print('Commande : wmiprvse /regserver')
        run('cmd /C wmiprvse /regserver')

        print(r'Commande : gpupdate /force /target:computer"')
        run(r'gpupdate /force /target:computer"')

def audit():
    winmgmt = run('winmgmt /verifyrepository')

    print(winmgmt)

    if "WMI EST cohérent" in winmgmt:
        retour = "OK"
    elif "WMI repository is consistent" in winmgmt:
        retour = "OK"
    else:
        retour = "ERROR"

    try:
        get_powershell_str('get-printer')
        get_powershell_str('Get-BitLockerVolume -MountPoint c:')
        get_powershell_str('Get-AppXProvisionedPackage -Online')
    except:
        print('Erreur WMI détectée')
        retour = "ERROR"

    return retour
Answer