diff --git a/.github/scripts/validate_bat.py b/.github/scripts/validate_bat.py index bec787e..4ce4844 100644 --- a/.github/scripts/validate_bat.py +++ b/.github/scripts/validate_bat.py @@ -115,6 +115,11 @@ def get_active_lines(content): return result +def _reg_key_normalize(raw: str) -> str: + """Normalise un chemin de registre : minuscules, guillemets retirés, séparateurs consolidés.""" + return raw.strip().strip('"').lower() + + # ─── Logique de détection codée en dur (pas des règles métier) ──────────────── # Ces éléments sont des patterns de détection — ils ne peuvent pas être exprimés # sous forme de simples valeurs dans un tableau markdown. @@ -681,6 +686,80 @@ def test_conditional_services_guarded(active_lines): return errors +# ── Tests v7 — optimisations 25H2 complémentaires ──────────────────────────── + +MANDATORY_OPTIMIZATIONS_V7_RECALL = [ + ("DisableRecallSnapshots=1 (Recall 25H2 snapshots off)", + r"DisableRecallSnapshots.*?/d\s+1"), + ("TurnOffSavingSnapshots=1 (Recall 25H2 sauvegarde off)", + r"TurnOffSavingSnapshots.*?/d\s+1"), + ("RecallFeatureEnabled=0 (HKCU Recall desactive)", + r"HKCU.*RecallFeatureEnabled.*?/d\s+0"), +] + +MANDATORY_OPTIMIZATIONS_V7_AI = [ + ("EnableWindowsAI=0 (Windows AI master switch off)", + r"EnableWindowsAI.*?/d\s+0"), + ("AllowOnDeviceML=0 (ML on-device off)", + r"AllowOnDeviceML.*?/d\s+0"), + ("DisableWinMLFeatures=1 (WinML features off)", + r"DisableWinMLFeatures.*?/d\s+1"), + ("DisableCopilotService=1 (service background Copilot off)", + r"DisableCopilotService.*?/d\s+1"), +] + +MANDATORY_OPTIMIZATIONS_V7_PRIVACY = [ + ("POWERSHELL_TELEMETRY_OPTOUT=1 (telemetrie PS off)", + r"POWERSHELL_TELEMETRY_OPTOUT.*?/d\s+1"), + ("LargeSystemCache=0 (favorise apps vs cache disque)", + r"LargeSystemCache.*?/d\s+0"), + ("NoActiveProbe=1 (NCSI stop probes msftconnecttest.com)", + r"NoActiveProbe.*?/d\s+1"), + ("AutoConnectAllowedOEM=0 (Wi-Fi Sense auto-connect off)", + r"AutoConnectAllowedOEM.*?/d\s+0"), + ("AllowWindowsInkWorkspace=0 (Ink Workspace off)", + r"AllowWindowsInkWorkspace.*?/d\s+0"), + ("ShowCopilotButton=0 (HKCU bouton Copilot masque)", + r"HKCU.*ShowCopilotButton.*?/d\s+0"), +] + + +def test_recall_complementary_keys(content): + """Vérifie les 3 clés complémentaires Recall 25H2 (DisableRecallSnapshots, TurnOffSavingSnapshots, RecallFeatureEnabled=0 HKCU).""" + errors = [] + for description, pattern in MANDATORY_OPTIMIZATIONS_V7_RECALL: + if not re.search(pattern, content, re.IGNORECASE): + errors.append(f" Optimisation Recall manquante : {description}") + return errors + + +def test_windows_ai_master_switch(content): + """Vérifie les 4 clés du master switch IA Windows 25H2 (EnableWindowsAI, AllowOnDeviceML, DisableWinMLFeatures, DisableCopilotService).""" + errors = [] + for description, pattern in MANDATORY_OPTIMIZATIONS_V7_AI: + if not re.search(pattern, content, re.IGNORECASE): + errors.append(f" Optimisation IA manquante : {description}") + return errors + + +NEW_MANDATORY_SERVICES_V7 = [ + "WSAIFabricSvc", # Windows AI Fabric Service — hôte COM IA locale, inutile sur PC sans NPU +] + + +def test_new_services_v7_disabled(content): + return _check_services_disabled(content, NEW_MANDATORY_SERVICES_V7) + + +def test_network_privacy_optimizations(content): + """Vérifie les optimisations vie privée réseau et télémétrie système (POWERSHELL_TELEMETRY_OPTOUT, LargeSystemCache, NCSI, Wi-Fi Sense, Ink Workspace, Copilot button).""" + errors = [] + for description, pattern in MANDATORY_OPTIMIZATIONS_V7_PRIVACY: + if not re.search(pattern, content, re.IGNORECASE): + errors.append(f" Optimisation réseau/système manquante : {description}") + return errors + + def test_hosts_marker_before_entries(content): """Vérifie que le marqueur anti-doublon hosts est écrit avant les premières entrées 0.0.0.0 en Section 16.""" errors = [] @@ -937,6 +1016,462 @@ def test_new_tasks_v5_disabled(content): return errors +# ── Tests v8 — couverture étendue pagefile, AppCompat, réseau, presse-papiers ── + +MANDATORY_OPTIMIZATIONS_V8_PAGEFILE = [ + ("Pagefile fixe 6 Go InitialSize=MaximumSize=6144 (registre PagingFiles)", + r"PagingFiles.*6144\s+6144"), +] + +MANDATORY_OPTIMIZATIONS_V8_APPCOMPAT = [ + ("DisableUAR=1 (AppCompat GPO — bloque reactivation taches AE)", + r"DisableUAR.*?/d\s+1"), + ("DisableInventory=1 (AppCompat GPO — inventaire apps off)", + r"DisableInventory.*?/d\s+1"), + ("DisablePCA=1 (AppCompat GPO — Program Compatibility Assistant off)", + r"DisablePCA.*?/d\s+1"), +] + +MANDATORY_OPTIMIZATIONS_V8_NETWORK = [ + ("DisableIPSourceRouting=2 (routage source off — previent usurpation adresse)", + r"DisableIPSourceRouting.*?/d\s+2"), + ("EnableICMPRedirect=0 (redirections ICMP off — previent attaques routage)", + r"EnableICMPRedirect.*?/d\s+0"), + ("DisableWpad=1 (WPAD desactive — previent proxy poisoning)", + r"DisableWpad.*?/d\s+1"), + ("EnableMulticast=0 (LLMNR desactive — reduit broadcasts reseau)", + r"EnableMulticast.*?/d\s+0"), + ("SMB1=0 (SMBv1 desactive — belt-and-suspenders 25H2)", + r"SMB1.*?/d\s+0"), +] + +MANDATORY_OPTIMIZATIONS_V8_CLIPBOARD = [ + ("AllowCrossDeviceClipboard=0 (presse-papiers cloud cross-device off)", + r"AllowCrossDeviceClipboard.*?/d\s+0"), + ("DisableCdp=1 (CDP / Nearby Share off)", + r"DisableCdp.*?/d\s+1"), +] + + +def test_pagefile_6gb(content): + """Vérifie que le pagefile est configuré en fixe 6 Go (6144 Mo) via clé registre PagingFiles.""" + errors = [] + for description, pattern in MANDATORY_OPTIMIZATIONS_V8_PAGEFILE: + if not re.search(pattern, content, re.IGNORECASE): + errors.append(f" Pagefile manquant : {description}") + return errors + + +def test_appcompat_gpo(content): + """Vérifie les 3 clés GPO AppCompat (DisableUAR=1, DisableInventory=1, DisablePCA=1) — section 17a.""" + errors = [] + for description, pattern in MANDATORY_OPTIMIZATIONS_V8_APPCOMPAT: + if not re.search(pattern, content, re.IGNORECASE): + errors.append(f" GPO AppCompat manquante : {description}") + return errors + + +def test_network_security_tcp(content): + """Vérifie les 5 optimisations sécurité réseau TCP/IP (routage source, ICMP, WPAD, LLMNR, SMBv1).""" + errors = [] + for description, pattern in MANDATORY_OPTIMIZATIONS_V8_NETWORK: + if not re.search(pattern, content, re.IGNORECASE): + errors.append(f" Securite reseau TCP/IP manquante : {description}") + return errors + + +def test_clipboard_cross_device_cdp(content): + """Vérifie que le presse-papiers cross-device est désactivé (AllowCrossDeviceClipboard=0) et CDP coupé (DisableCdp=1).""" + errors = [] + for description, pattern in MANDATORY_OPTIMIZATIONS_V8_CLIPBOARD: + if not re.search(pattern, content, re.IGNORECASE): + errors.append(f" Presse-papiers/CDP manquant : {description}") + return errors + + +# ── Tests v9 — optimisations obligatoires complémentaires ──────────────────── +# Règles présentes dans prerequis_WIN11.md (section Optimisations TOUJOURS appliquées) +# et dans les sections de structure, non couvertes par les tests précédents. + +APP_PRIVACY_PERMISSIONS = [ + "LetAppsAccessCamera", + "LetAppsAccessMicrophone", + "LetAppsAccessLocation", + "LetAppsAccessAccountInfo", + "LetAppsAccessContacts", + "LetAppsAccessCalendar", + "LetAppsAccessCallHistory", + "LetAppsAccessEmail", + "LetAppsAccessMessaging", + "LetAppsAccessTasks", + "LetAppsAccessRadios", + "LetAppsActivateWithVoice", + "LetAppsActivateWithVoiceAboveLock", + "LetAppsAccessBackgroundSpatialPerception", +] + + +def test_startup_sound_disabled(content): + """Vérifie que le son au démarrage est désactivé (DisableStartupSound=1).""" + errors = [] + if not re.search(r"DisableStartupSound.*?/d\s+1", content, re.IGNORECASE): + errors.append(" DisableStartupSound=1 absent (son au démarrage non désactivé)") + return errors + + +def test_remote_assistance_disabled(content): + """Vérifie que l'assistance à distance est désactivée (fAllowToGetHelp=0, fAllowFullControl=0).""" + errors = [] + if not re.search(r"fAllowToGetHelp.*?/d\s+0", content, re.IGNORECASE): + errors.append(" fAllowToGetHelp=0 absent (Remote Assistance non désactivée)") + if not re.search(r"fAllowFullControl.*?/d\s+0", content, re.IGNORECASE): + errors.append(" fAllowFullControl=0 absent (contrôle total Remote Assistance non bloqué)") + return errors + + +def test_app_privacy_permissions(content): + """Vérifie que les 14 permissions AppPrivacy sont bloquées (LetAppsAccess*=2) — prerequis_WIN11.md section 11b.""" + errors = [] + for perm in APP_PRIVACY_PERMISSIONS: + if not re.search(re.escape(perm) + r".*?/d\s+2", content, re.IGNORECASE): + errors.append(f" AppPrivacy permission manquante ou incorrecte : {perm}=2") + return errors + + +def test_autoplay_disabled(content): + """Vérifie que AutoPlay/AutoRun sont désactivés (NoDriveTypeAutoRun=255) — sécurité USB.""" + errors = [] + if not re.search(r"NoDriveTypeAutoRun.*?/d\s+255", content, re.IGNORECASE): + errors.append(" NoDriveTypeAutoRun=255 absent (AutoPlay/AutoRun non désactivé)") + return errors + + +def test_sfc_dism_section19b(content): + """Vérifie que SFC et DISM sont présents en section 19b (vérification intégrité système).""" + errors = [] + if not re.search(r"\bsfc\s+/scannow\b", content, re.IGNORECASE): + errors.append(" sfc /scannow absent (vérification intégrité Section 19b manquante)") + if not re.search(r"\bdism\b.*?/restorehealth\b", content, re.IGNORECASE): + errors.append(" dism /restorehealth absent (réparation image système Section 19b manquante)") + return errors + + +def test_advertising_id_disabled(content): + """Vérifie que l'Advertising ID est désactivé (DisabledByGroupPolicy=1 via AdvertisingInfo).""" + errors = [] + if not re.search(r"AdvertisingInfo.*?DisabledByGroupPolicy.*?/d\s+1", content, re.IGNORECASE): + errors.append( + " DisabledByGroupPolicy=1 absent sous AdvertisingInfo " + "(Advertising ID non désactivé)" + ) + return errors + + +# ── Tests v10 — optimisations obligatoires manquantes (prerequis_WIN11.md) ──── +# Règles présentes dans prerequis_WIN11.md (section Optimisations TOUJOURS appliquées) +# non couvertes par les tests v1-v9. + +MANDATORY_OPTIMIZATIONS_V10_CORTANA = [ + ("AllowCortana=0 (Cortana desactive — HKLM Search)", + r"AllowCortana.*?/d\s+0"), + ("CortanaConsent=0 (HKCU — consentement Cortana desactive)", + r"HKCU.*CortanaConsent.*?/d\s+0"), + ("AllowCloudSearch=0 (Windows Search cloud desactive)", + r"AllowCloudSearch.*?/d\s+0"), + ("ConnectedSearchUseWeb=0 (recherche web dans Search desactivee)", + r"ConnectedSearchUseWeb.*?/d\s+0"), +] + +MANDATORY_OPTIMIZATIONS_V10_LOCATION = [ + ("DisableLocationScripting=1 (scripts localisation bloques)", + r"DisableLocationScripting.*?/d\s+1"), + ("DisableWindowsLocationProvider=1 (fournisseur localisation Windows bloque)", + r"DisableWindowsLocationProvider.*?/d\s+1"), + ("DisableSensors=1 (capteurs physiques bloques)", + r"DisableSensors.*?/d\s+1"), +] + +MANDATORY_OPTIMIZATIONS_V10_CDM = [ + ("SilentInstalledAppsEnabled=0 (reinstall apps silencieux CDM bloque)", + r"SilentInstalledAppsEnabled.*?/d\s+0"), + ("ContentDeliveryAllowed=0 (livraison contenu CDM desactivee)", + r"ContentDeliveryAllowed.*?/d\s+0"), +] + +MANDATORY_OPTIMIZATIONS_V10_STARTMENU = [ + ("Start_TrackProgs=0 (suivi programmes demarre menu demarrer off)", + r"Start_TrackProgs.*?/d\s+0"), + ("Start_TrackDocs=0 (suivi documents recents menu demarrer off)", + r"Start_TrackDocs.*?/d\s+0"), +] + + +def test_cortana_search_cloud_disabled(content): + """Vérifie les 4 clés Cortana/Search (AllowCortana=0, CortanaConsent=0 HKCU, AllowCloudSearch=0, ConnectedSearchUseWeb=0) — prerequis_WIN11.md.""" + errors = [] + for description, pattern in MANDATORY_OPTIMIZATIONS_V10_CORTANA: + if not re.search(pattern, content, re.IGNORECASE): + errors.append(f" Cortana/Search manquant : {description}") + return errors + + +def test_location_privacy_keys(content): + """Vérifie les 3 clés vie privée localisation (DisableLocationScripting=1, DisableWindowsLocationProvider=1, DisableSensors=1) — prerequis_WIN11.md.""" + errors = [] + for description, pattern in MANDATORY_OPTIMIZATIONS_V10_LOCATION: + if not re.search(pattern, content, re.IGNORECASE): + errors.append(f" Localisation privacy manquant : {description}") + return errors + + +def test_min_free_system_commit(content): + """Vérifie que MinFreeSystemCommit est configuré via reg add — libération mémoire agressive pour 1 Go RAM — prerequis_WIN11.md.""" + errors = [] + if not re.search(r"reg\s+add.*MinFreeSystemCommit.*?/d\s+\d+", content, re.IGNORECASE): + errors.append( + " MinFreeSystemCommit absent (liberation memoire agressive pour 1 Go RAM)" + ) + return errors + + +def test_content_delivery_manager(content): + """Vérifie que ContentDeliveryManager bloque la réinstallation silencieuse (SilentInstalledAppsEnabled=0, ContentDeliveryAllowed=0) — prerequis_WIN11.md.""" + errors = [] + for description, pattern in MANDATORY_OPTIMIZATIONS_V10_CDM: + if not re.search(pattern, content, re.IGNORECASE): + errors.append(f" ContentDeliveryManager manquant : {description}") + return errors + + +def test_siuf_period_zero(content): + """Vérifie que la période SIUF est à zéro (PeriodInNanoSeconds=0 HKCU) — désactive le feedback Microsoft — prerequis_WIN11.md.""" + errors = [] + if not re.search(r"PeriodInNanoSeconds.*?/d\s+0", content, re.IGNORECASE): + errors.append( + " PeriodInNanoSeconds=0 absent (SIUF feedback periode non desactivee HKCU)" + ) + return errors + + +def test_maintenance_disabled(content): + """Vérifie que la maintenance automatique Windows est désactivée (MaintenanceDisabled=1) — prerequis_WIN11.md.""" + errors = [] + if not re.search(r"MaintenanceDisabled.*?/d\s+1", content, re.IGNORECASE): + errors.append( + " MaintenanceDisabled=1 absent (maintenance automatique Windows non desactivee)" + ) + return errors + + +def test_start_menu_tracking_off(content): + """Vérifie que le suivi du menu démarrer est désactivé (Start_TrackProgs=0, Start_TrackDocs=0 HKCU) — prerequis_WIN11.md.""" + errors = [] + for description, pattern in MANDATORY_OPTIMIZATIONS_V10_STARTMENU: + if not re.search(pattern, content, re.IGNORECASE): + errors.append(f" Start Menu tracking manquant : {description}") + return errors + + +# ── Tests v11 — performance CPU, Search/Notifications, WER, UI vie privée ─── +# Règles présentes dans prerequis_WIN11.md (section Optimisations TOUJOURS appliquées) +# non couvertes par les tests v1-v10. + +MANDATORY_OPTIMIZATIONS_V11_CPU = [ + ("SystemResponsiveness=10 (priorite CPU apps premier plan — PriorityControl)", + r"SystemResponsiveness.*?/d\s+10"), + ("PowerThrottlingOff=1 (bridage CPU Intel Speed Shift desactive — Power\\PowerThrottling)", + r"PowerThrottlingOff.*?/d\s+1"), +] + +MANDATORY_OPTIMIZATIONS_V11_SEARCH_NOTIF = [ + ("EnableDynamicContentInWSB=0 (Search Highlights tuiles MSN/IA dans barre recherche off)", + r"EnableDynamicContentInWSB.*?/d\s+0"), + ("ToastEnabled=0 (notifications toast HKCU desactivees)", + r"ToastEnabled.*?/d\s+0"), + ("DisableSearchBoxSuggestions=1 (suggestions barre recherche Explorer off)", + r"DisableSearchBoxSuggestions.*?/d\s+1"), +] + +MANDATORY_OPTIMIZATIONS_V11_WER = [ + ("DontSendAdditionalData=1 (WER pas d'envoi donnees supplementaires — Windows Error Reporting)", + r"Windows.Error.Reporting.*DontSendAdditionalData.*?/d\s+1"), + ("LoggingDisabled=1 (WER journalisation desactivee — Windows Error Reporting)", + r"Windows.Error.Reporting.*LoggingDisabled.*?/d\s+1"), + ("DontShowUI=1 (WER interface masquee — pas de popup d'erreur utilisateur)", + r"DontShowUI.*?/d\s+1"), +] + +MANDATORY_OPTIMIZATIONS_V11_UI = [ + ("GameDVR_FSEBehavior=2 (fullscreen optimizations GameDVR off HKCU)", + r"GameDVR_FSEBehavior.*?/d\s+2"), + ("AllowProjectionToPC=0 (SmartGlass/Connect projection Bluetooth desactivee)", + r"AllowProjectionToPC.*?/d\s+0"), + ("PreventHandwritingDataSharing=1 (ecriture manuscrite partage donnees off)", + r"PreventHandwritingDataSharing.*?/d\s+1"), + ("ShellFeedsTaskbarViewMode=2 (fil actualites barre des taches masque)", + r"ShellFeedsTaskbarViewMode.*?/d\s+2"), +] + + +def test_cpu_performance_settings(content): + """Vérifie SystemResponsiveness=10 et PowerThrottlingOff=1 (section 13 — priorité CPU et Power Throttling).""" + errors = [] + for description, pattern in MANDATORY_OPTIMIZATIONS_V11_CPU: + if not re.search(pattern, content, re.IGNORECASE): + errors.append(f" CPU performance manquant : {description}") + return errors + + +def test_search_notifications_ui(content): + """Vérifie les 3 clés Search Highlights et Notifications (EnableDynamicContentInWSB=0, ToastEnabled=0, DisableSearchBoxSuggestions=1).""" + errors = [] + for description, pattern in MANDATORY_OPTIMIZATIONS_V11_SEARCH_NOTIF: + if not re.search(pattern, content, re.IGNORECASE): + errors.append(f" Search/Notifications manquant : {description}") + return errors + + +def test_wer_disabled(content): + """Vérifie les 3 clés WER désactivé (DontSendAdditionalData=1, LoggingDisabled=1, DontShowUI=1) — Windows Error Reporting.""" + errors = [] + for description, pattern in MANDATORY_OPTIMIZATIONS_V11_WER: + if not re.search(pattern, content, re.IGNORECASE): + errors.append(f" WER manquant : {description}") + return errors + + +def test_ui_privacy_settings(content): + """Vérifie les 4 clés UI vie privée (GameDVR_FSEBehavior=2, AllowProjectionToPC=0, PreventHandwritingDataSharing=1, ShellFeedsTaskbarViewMode=2).""" + errors = [] + for description, pattern in MANDATORY_OPTIMIZATIONS_V11_UI: + if not re.search(pattern, content, re.IGNORECASE): + errors.append(f" UI/vie privée manquant : {description}") + return errors + + +def test_no_duplicate_commands(active_lines): + """ + Test 62 — Vérifie qu'aucune commande n'est dupliquée dans win11-setup.bat. + + Précision maximale — catégories analysées (insensibles à la casse) : + [REG] reg add / reg delete — (opération, chemin clé, nom valeur) + [SC] sc stop / config / failure — (opération, nom service) + [TASK] schtasks /Change /TN — nom de tâche normalisé + [HOSTS] echo 0.0.0.0 / 127.0.0.1 — domaine bloqué + [DEL] del — chemin de fichier normalisé + + Exclusions légitimes : + - Lignes commençant par echo (log/hosts write) : ignorées pour reg/sc/del + - Variables de boucle batch (%%X, %X%) : ignorées pour sc + - Même TN sur /Query && /Change sur la même ligne : comptée une seule fois + """ + reg_seen = {} # (op, key, val) -> [linenos] + sc_seen = {} # (op, svc) -> [linenos] + task_seen = {} # tn_low -> [linenos] + hosts_seen = {} # domain_low -> [linenos] + del_seen = {} # path_low -> [linenos] + + for lineno, line in active_lines: + stripped = line.strip() + + # Lignes echo : exclues pour reg/sc/del (mais capturées pour hosts) + is_echo_line = bool(re.match(r"^echo\b", stripped, re.IGNORECASE)) + + # ── 1. reg add / reg delete ────────────────────────────────────────── + if not is_echo_line and re.search(r"\breg\s+(?:add|delete)\b", stripped, re.IGNORECASE): + m_op = re.search(r"\breg\s+(add|delete)\b", stripped, re.IGNORECASE) + op = m_op.group(1).lower() + + # Chemin de clé (guillemets ou non) + m_key = re.search(r"\breg\s+(?:add|delete)\s+\"([^\"]+)\"", stripped, re.IGNORECASE) + if not m_key: + m_key = re.search( + r"\breg\s+(?:add|delete)\s+([^\s\"\'\/][^\s]*)", stripped, re.IGNORECASE + ) + if not m_key: + continue + key = _reg_key_normalize(m_key.group(1)) + + # Nom de valeur : /ve = valeur par défaut, /v NOM (avec ou sans guillemets) + if re.search(r"(?:^|\s)/ve\b", stripped, re.IGNORECASE): + val = "(default)" + else: + m_val = re.search(r"/v\s+\"([^\"]+)\"", stripped, re.IGNORECASE) + if not m_val: + m_val = re.search(r"/v\s+(\S+)", stripped, re.IGNORECASE) + val = m_val.group(1).lower() if m_val else "(default)" + + reg_seen.setdefault((op, key, val), []).append(lineno) + + # ── 2. sc stop / config / failure ──────────────────────────────────── + if not is_echo_line and re.search( + r"\bsc\s+(?:stop|config|failure)\b", stripped, re.IGNORECASE + ): + m = re.search(r"\bsc\s+(stop|config|failure)\s+(\S+)", stripped, re.IGNORECASE) + if m: + op_sc = m.group(1).lower() + svc = m.group(2).lower() + # Exclure les variables de boucle batch (%%VAR ou %VAR%) + if not svc.startswith("%"): + sc_seen.setdefault((op_sc, svc), []).append(lineno) + + # ── 3. schtasks /Change (/Query && /Change sur la même ligne) ───────── + if not is_echo_line and re.search(r"\bschtasks\b", stripped, re.IGNORECASE) \ + and re.search(r"/Change\b", stripped, re.IGNORECASE): + # Collecter les TN uniques sur cette ligne (set → évite double-comptage + # lorsque /Query et /Change partagent le même /TN sur une seule ligne) + tns_on_line = set() + for m in re.finditer(r"/TN\s+\"([^\"]+)\"", stripped, re.IGNORECASE): + tns_on_line.add(m.group(1).lower()) + if not tns_on_line: + # Fallback : TN sans guillemets + for m in re.finditer(r"/TN\s+([^\s\/][^\s]*)", stripped, re.IGNORECASE): + tns_on_line.add(m.group(1).lower()) + for tn in tns_on_line: + task_seen.setdefault(tn, []).append(lineno) + + # ── 4. Entrées hosts (echo 0.0.0.0 / 127.0.0.1 DOMAIN) ────────────── + # Capturées sur les lignes echo (ajout dynamique dans le script) + m_hosts = re.search( + r"\becho\s+(?:0\.0\.0\.0|127\.0\.0\.1)\s+([^\s\>\|\&\"\']+)", + stripped, re.IGNORECASE + ) + if m_hosts: + domain = m_hosts.group(1).lower() + hosts_seen.setdefault(domain, []).append(lineno) + + # ── 5. del (suppression de fichiers) ───────────────────────────────── + if not is_echo_line and re.search(r"\bdel\b", stripped, re.IGNORECASE): + # Chemin entre guillemets + m_del = re.search(r"\bdel\b[^\"]*\"([^\"]+)\"", stripped, re.IGNORECASE) + if not m_del: + # Chemin sans guillemets : del /f /q /s path + m_del = re.search( + r"\bdel\b(?:\s+/\w+)*\s+([^\s\>\|\&\"\']+)", stripped, re.IGNORECASE + ) + if m_del: + path = m_del.group(1).lower() + del_seen.setdefault(path, []).append(lineno) + + errors = [] + + def _report(seen, category, label_fn): + for sig, linenos in sorted(seen.items(), key=lambda x: x[1][0]): + if len(linenos) > 1: + nums = ", ".join(str(n) for n in linenos) + errors.append( + f" [{category}] doublon ligne(s) {nums} — {label_fn(sig)}" + ) + + _report(reg_seen, "REG", lambda s: f'reg {s[0]} "{s[1]}" /v {s[2]}') + _report(sc_seen, "SC", lambda s: f"sc {s[0]} {s[1]}") + _report(task_seen, "TASK", lambda s: f'/TN "{s}"') + _report(hosts_seen, "HOSTS", lambda s: f"0.0.0.0 {s}") + _report(del_seen, "DEL", lambda s: f'del "{s}"') + + return errors + + def write_github_summary(tests_results, passed, failed): """Écrit un rapport markdown dans $GITHUB_STEP_SUMMARY si disponible.""" import os @@ -1094,6 +1629,65 @@ def main(): test_conditional_services_guarded(active_lines)), ("47 Marqueur hosts positionne avant les premieres entrees 0.0.0.0 en Section 16", test_hosts_marker_before_entries(content)), + # ── Tests v7 — optimisations 25H2 complémentaires ──────────────────────── + ("48 Recall 25H2 cles complementaires (DisableRecallSnapshots TurnOffSavingSnapshots RecallFeatureEnabled HKCU)", + test_recall_complementary_keys(content)), + ("49 IA Windows 25H2 master switch (EnableWindowsAI AllowOnDeviceML DisableWinMLFeatures DisableCopilotService)", + test_windows_ai_master_switch(content)), + ("50 Vie privee reseau et telemetrie systeme (POWERSHELL_TELEMETRY_OPTOUT LargeSystemCache NoActiveProbe WiFiSense InkWorkspace CopilotButton)", + test_network_privacy_optimizations(content)), + # ── Tests v7 (suite) — service IA Fabric ───────────────────────────── + ("51 Service v7 desactive (WSAIFabricSvc Windows AI Fabric)", + test_new_services_v7_disabled(content)), + # ── Tests v8 — pagefile, AppCompat GPO, securite reseau, presse-papiers ── + ("52 Pagefile fixe 6 Go (registre PagingFiles 6144 6144)", + test_pagefile_6gb(content)), + ("53 AppCompat GPO presentes (DisableUAR DisableInventory DisablePCA)", + test_appcompat_gpo(content)), + ("54 Securite reseau TCP/IP (DisableIPSourceRouting EnableICMPRedirect WPAD LLMNR SMBv1)", + test_network_security_tcp(content)), + ("55 Presse-papiers cross-device et CDP desactives (AllowCrossDeviceClipboard DisableCdp)", + test_clipboard_cross_device_cdp(content)), + # ── Tests v9 — optimisations obligatoires complémentaires ──────────── + ("56 Son au demarrage desactive (DisableStartupSound=1)", + test_startup_sound_disabled(content)), + ("57 Assistance a distance desactivee (fAllowToGetHelp=0 fAllowFullControl=0)", + test_remote_assistance_disabled(content)), + ("58 AppPrivacy 14 permissions bloquees (LetAppsAccess*=2)", + test_app_privacy_permissions(content)), + ("59 AutoPlay/AutoRun desactives (NoDriveTypeAutoRun=255)", + test_autoplay_disabled(content)), + ("60 SFC et DISM presents en section 19b (integrite systeme)", + test_sfc_dism_section19b(content)), + ("61 Advertising ID desactive (AdvertisingInfo DisabledByGroupPolicy=1)", + test_advertising_id_disabled(content)), + # ── Tests v10 — optimisations obligatoires manquantes ───────────────────── + ("63 Cortana et Search cloud desactives (AllowCortana CortanaConsent AllowCloudSearch ConnectedSearchUseWeb)", + test_cortana_search_cloud_disabled(content)), + ("64 Localisation vie privee 3 cles (DisableLocationScripting DisableWindowsLocationProvider DisableSensors)", + test_location_privacy_keys(content)), + ("65 MinFreeSystemCommit present (liberation memoire agressive 1 Go RAM)", + test_min_free_system_commit(content)), + ("66 ContentDeliveryManager blocage reinstall silencieux (SilentInstalledAppsEnabled ContentDeliveryAllowed)", + test_content_delivery_manager(content)), + ("67 SIUF feedback periode zero (PeriodInNanoSeconds=0 HKCU)", + test_siuf_period_zero(content)), + ("68 Maintenance automatique Windows desactivee (MaintenanceDisabled=1)", + test_maintenance_disabled(content)), + ("69 Start Menu tracking desactive (Start_TrackProgs=0 Start_TrackDocs=0)", + test_start_menu_tracking_off(content)), + # ── Tests v11 — performance CPU, Search/Notifications, WER, UI vie privée ── + ("70 Performance CPU (SystemResponsiveness=10 PowerThrottlingOff=1)", + test_cpu_performance_settings(content)), + ("71 Search Highlights et Notifications (EnableDynamicContentInWSB ToastEnabled DisableSearchBoxSuggestions)", + test_search_notifications_ui(content)), + ("72 WER desactive (DontSendAdditionalData LoggingDisabled DontShowUI)", + test_wer_disabled(content)), + ("73 UI vie privee (GameDVR_FSEBehavior AllowProjectionToPC PreventHandwritingDataSharing ShellFeedsTaskbarViewMode)", + test_ui_privacy_settings(content)), + # ── Test 62 — Doublons de commandes ─────────────────────────────────── + ("62 Aucune commande en doublon (reg add/del, sc stop/config/failure, schtasks, hosts, del)", + test_no_duplicate_commands(active_lines)), ] passed = 0 diff --git a/.github/workflows/validate.yml b/.github/workflows/validate.yml index 2d47b48..dc4bf50 100644 --- a/.github/workflows/validate.yml +++ b/.github/workflows/validate.yml @@ -9,7 +9,7 @@ on: jobs: validate: - name: "🔍 45 vérifications automatiques" + name: "🔍 71 vérifications automatiques" runs-on: ubuntu-latest steps: @@ -21,7 +21,7 @@ jobs: with: python-version: "3.x" - - name: "🧪 Validation statique (45 tests)" + - name: "🧪 Validation statique (71 tests)" run: | echo "## 🚀 Démarrage de la validation..." >> $GITHUB_STEP_SUMMARY echo "" >> $GITHUB_STEP_SUMMARY diff --git a/prerequis_WIN11.md b/prerequis_WIN11.md index cb9d9cc..1b4c817 100644 --- a/prerequis_WIN11.md +++ b/prerequis_WIN11.md @@ -233,6 +233,7 @@ Ces services ne doivent **jamais** être désactivés : | `NetSetupSvc` | Network Setup Service — ne tourne qu'à la configuration réseau initiale, inutile post-setup | | `RpcLocator` | Remote Procedure Call Locator — service déprécié depuis Vista, inutile sur réseau moderne | | `UmRdpService` | RDP User Mode Port Redirector — conditionnel `NEED_RDP=0` (inutile si RDP désactivé) | +| `WSAIFabricSvc` | Windows AI Fabric Service — hôte COM infrastructure IA locale (WorkloadsSessionHost), consomme GPU/NPU en continu, inutile sur PC sans NPU (1 Go RAM) | > ⚠️ `WSearch` : **NE PAS ajouter à cette liste** — toujours conservé sans exception diff --git a/win11-setup.bat b/win11-setup.bat index eed07d3..105caac 100644 --- a/win11-setup.bat +++ b/win11-setup.bat @@ -169,16 +169,11 @@ reg add "HKCU\SOFTWARE\Microsoft\AppSettings" /v Skype-UserConsentAccepted /t RE reg add "HKCU\SOFTWARE\Microsoft\Windows\CurrentVersion\UserProfileEngagement" /v AccountNotifications /t REG_DWORD /d 0 /f >nul 2>&1 :: Appels téléphoniques — accès apps UWP refusé reg add "HKCU\SOFTWARE\Microsoft\Windows\CurrentVersion\CapabilityAccessManager\ConsentStore\phoneCall" /v Value /t REG_SZ /d Deny /f >nul 2>&1 -:: Recherche cloud désactivée -reg add "HKLM\SOFTWARE\Policies\Microsoft\Windows\Windows Search" /v AllowCloudSearch /t REG_DWORD /d 0 /f >nul 2>&1 :: OneDrive — policy non écrite (conservé, démarrage géré par l'utilisateur) :: Event Transcript — désactiver la base de données locale des événements télémétrie (réduit I/O disque) reg add "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Diagnostics\DiagTrack\EventTranscriptKey" /v EnableEventTranscript /t REG_DWORD /d 0 /f >nul 2>&1 :: MRT — ne pas remonter les résultats d'analyse d'infection au cloud Microsoft reg add "HKLM\SOFTWARE\Policies\Microsoft\MRT" /v DontReportInfectionInformation /t REG_DWORD /d 1 /f >nul 2>&1 -:: Tailored Experiences — désactiver les recommandations personnalisées basées sur les données de diagnostic (HKLM) -reg add "HKLM\SOFTWARE\Policies\Microsoft\Windows\CloudContent" /v DisableTailoredExperiencesWithDiagnosticData /t REG_DWORD /d 1 /f >nul 2>&1 - :: Desktop Analytics — désactiver le traitement des données analytiques locales reg add "HKLM\SOFTWARE\Policies\Microsoft\Windows\DataCollection" /v EnableDesktopAnalyticsProcessing /t REG_DWORD /d 0 /f >nul 2>&1 echo [%date% %time%] Section 6 : Telemetrie/AI/Copilot/Recall/SIUF/CEIP/Defender/DataCollection OK >> "%LOG%" @@ -450,7 +445,6 @@ reg add "HKLM\SYSTEM\CurrentControlSet\Services\LanmanServer\Parameters" /v SMB1 :: Note: DisableWindowsSpotlightFeatures interdit (prerequis_WIN11.md — Spotlight conservé) reg add "HKCU\SOFTWARE\Policies\Microsoft\Windows\CloudContent" /v DisableWindowsSpotlightOnActionCenter /t REG_DWORD /d 1 /f >nul 2>&1 reg add "HKCU\SOFTWARE\Policies\Microsoft\Windows\CloudContent" /v DisableWindowsSpotlightOnSettings /t REG_DWORD /d 1 /f >nul 2>&1 -reg add "HKCU\SOFTWARE\Policies\Microsoft\Windows\CloudContent" /v DisableTailoredExperiencesWithDiagnosticData /t REG_DWORD /d 1 /f >nul 2>&1 :: Notifications sync provider — désactiver les pubs OneDrive/tiers dans l'Explorateur reg add "HKCU\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\Advanced" /v ShowSyncProviderNotifications /t REG_DWORD /d 0 /f >nul 2>&1 @@ -516,7 +510,7 @@ reg add "HKCU\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\Advanced" /v Sh :: Démarrer — arrêter le suivi programmes et documents récents reg add "HKCU\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\Advanced" /v Start_TrackProgs /t REG_DWORD /d 0 /f >nul 2>&1 -reg add "HKCU\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\Advanced" /v Start_TrackDocs /t REG_DWORD /d 1 /f >nul 2>&1 +reg add "HKCU\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\Advanced" /v Start_TrackDocs /t REG_DWORD /d 0 /f >nul 2>&1 :: Démarrer — masquer apps récemment ajoutées (HKLM policy) reg add "HKLM\SOFTWARE\Policies\Microsoft\Windows\Explorer" /v HideRecentlyAddedApps /t REG_DWORD /d 1 /f >nul 2>&1 @@ -688,6 +682,7 @@ reg add "HKLM\SYSTEM\CurrentControlSet\Services\Recall" /v Start /t REG_DWORD /d reg add "HKLM\SYSTEM\CurrentControlSet\Services\WindowsAIService" /v Start /t REG_DWORD /d 4 /f >nul 2>&1 reg add "HKLM\SYSTEM\CurrentControlSet\Services\WinMLService" /v Start /t REG_DWORD /d 4 /f >nul 2>&1 reg add "HKLM\SYSTEM\CurrentControlSet\Services\CoPilotMCPService" /v Start /t REG_DWORD /d 4 /f >nul 2>&1 +reg add "HKLM\SYSTEM\CurrentControlSet\Services\WSAIFabricSvc" /v Start /t REG_DWORD /d 4 /f >nul 2>&1 :: Cloud clipboard / sync cross-device (cbdhsvc conservé — requis pour Win+V historique local) reg add "HKLM\SYSTEM\CurrentControlSet\Services\CDPUserSvc" /v Start /t REG_DWORD /d 4 /f >nul 2>&1 reg add "HKLM\SYSTEM\CurrentControlSet\Services\DevicesFlowUserSvc" /v Start /t REG_DWORD /d 4 /f >nul 2>&1 @@ -830,6 +825,10 @@ for %%S in (AppReadiness WorkFoldersSvc RmSvc SgrmBroker NPSMSvc AssignedAccessM for %%S in (NetSetupSvc RpcLocator) do ( sc query %%S >nul 2>&1 && sc stop %%S >nul 2>&1 ) +:: Arrêt immédiat des nouveaux services v7 +for %%S in (WSAIFabricSvc) do ( + sc query %%S >nul 2>&1 && sc stop %%S >nul 2>&1 +) if "%NEED_RDP%"=="0" sc stop UmRdpService >nul 2>&1 echo [%date% %time%] Section 15 : sc stop envoye aux services listes >> "%LOG%" :: Paramètres de récupération DiagTrack — Ne rien faire sur toutes défaillances