Une petite maj depuis tout ce temps. Nous avons de très bons résultats depuis
Code : Tout sélectionner
# -*- 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)
Il existe une fonction dans wapt pour restaurer le cache mais qui remonte juste une erreur.
Voici un code qui marche
Code : Tout sélectionner
# -*- 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
