Seite 2 von 2

Betreff: Auflistung der Pakete und deren Status

Veröffentlicht: 9. Oktober 2026 - 14:42 Uhr
von Mikael S
Guten Morgen,

Ein kurzes Update nach all der Zeit. Wir haben seitdem sehr gute Ergebnisse erzielt

Code: Alle auswählen

# -*- 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)
Bei Apps ist ein Fallback manchmal nützlich, wenn der WMI-Cache beschädigt ist, aber in der Realität wird er selten verwendet.
In wapt gibt es eine Funktion zum Wiederherstellen des Caches, diese gibt jedoch nur einen Fehler zurück.
Hier ist ein funktionierender Code

Code: Alle auswählen

# -*- 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