tis-windows11-requirements

2025.8.14-22
Vérifie la configuration minimale requise pour l'installation de Windows 11
1664 téléchargements
Télécharger
Voir le résultat de la construction Voir l'analyse de VirusTotal
tis-windows11-requirements icon

tis-windows11-requirements

Le package tis-windows11-requirements est conçu pour vérifier les prérequis de Windows 11 sur les postes de travail Windows 10. Il fournit un état détaillé des différents prérequis dans la console WAPT sous l'onglet des données d'audit, indiquant clairement si chaque prérequis est respecté ou non. Résultats possibles

Deux types de résultats peuvent être affichés :

  • OK → L'exigence est satisfaite.
  • ERROR → L'exigence n'est pas satisfaite.

Dans les cas où une exigence n'est pas satisfaite, des informations supplémentaires seront fournies pour aider à comprendre le problème.


Vidéo d'explication

Pour une explication détaillée du fonctionnement de ce paquet, vous pouvez regarder la vidéo suivante :

package           : tis-windows11-requirements
version           : 2025.8.14-22
architecture      : all
section           : base
priority          : optional
name              : Windows 11 Requirements
categories        : System and network
maintainer        : WAPT Team,Tranquil IT,Joffrey Le Piquet
description       : Checks the minimum system requirements for installing Windows 11
depends           : 
conflicts         : 
maturity          : PROD
locale            : all
target_os         : windows
min_wapt_version  : 2.1
sources           : 
installed_size    : 54419
impacted_process  : 
description_fr    : Vérifie la configuration minimale requise pour l'installation de Windows 11
description_pl    : Sprawdza minimalne wymagania systemowe dla instalacji systemu Windows 11
description_de    : Überprüft die Mindestsystemanforderungen für die Installation von Windows 11
description_es    : Comprueba los requisitos mínimos del sistema para instalar Windows 11
description_pt    : Verifica os requisitos mínimos do sistema para a instalação do Windows 11
description_it    : Verifica i requisiti minimi di sistema per l'installazione di Windows 11
description_nl    : Controleert de minimale systeemvereisten voor de installatie van Windows 11
description_ru    : Проверяет минимальные системные требования для установки Windows 11
audit_schedule    : 
editor            : 
keywords          : 
licence           : 
homepage          : https://techcommunity.microsoft.com/t5/microsoft-endpoint-manager-blog/understanding-readiness-for-windows-11-with-microsoft-endpoint/ba-p/2770866
package_uuid      : 8da9c51c-d5a4-4d9e-8a67-84ff5ca0a62a
valid_from        : 
valid_until       : 
forced_install_on : 
changelog         : 
min_os_version    : 10.0.18362
max_os_version    : 
icon_sha256sum    : 9ccd55c246c5266669ff70a6e62c1e315666114c6d3f854071b6ff22fe48612b
signer            : Tranquil IT
signer_fingerprint: 8c5127a75392be9cc9afd0dbae1222a673072c308c14d88ab246e23832e8c6bb
signature_date    : 2025-08-18T14:13:18.000000
signed_attributes : package,version,architecture,section,priority,name,categories,maintainer,description,depends,conflicts,maturity,locale,target_os,min_wapt_version,sources,installed_size,impacted_process,description_fr,description_pl,description_de,description_es,description_pt,description_it,description_nl,description_ru,audit_schedule,editor,keywords,licence,homepage,package_uuid,valid_from,valid_until,forced_install_on,changelog,min_os_version,max_os_version,icon_sha256sum,signer,signer_fingerprint,signature_date,signed_attributes
signature         : SnJ9fOgf+f/N90aNdKxbpENDyA/YRnZE9WnKNfA/OKB760cfN73cgIBhUV/MhmoicnOnAerqhB0QlfC7k2F5brI1/Ld41D1J0pOPX6Bu5DDvSX//LrOpKIY1tYhsvAfgoGmE2NI5FC+jKS3tW3v2S4pDgBfIJ2A8Baie88g0tWBaSifJkywOgGYHUR7jNJ8bsMm3TI0bUm9IKR+pEZjgyeokc2llC/P/pkLXMjWZIuDIS6YwtixVEllZuPBC6HgPTWWTDFsX3pRNZLZeiweyxBp4p8vp5m8DotHjKnRvH0VtcNw5tC6EDhronjRomlWmJGdOmh34UEYmTNr6Wpg5eg==
# -*- coding: utf-8 -*-
from setuphelpers import *
from math import *
import json

json_source = "cpu_w11.json"
result_dict = {}

def install():
    print("Copying: %s to: %s" % (json_source, persistent_dir))
    filecopyto(json_source, persistent_dir)

def audit():

    audit_status = "OK"

    audit_status = set_audit_status(audit_status,check_tpm_state())
    audit_status = set_audit_status(audit_status,check_free_space())
    audit_status = set_audit_status(audit_status,check_free_space_efi())
    audit_status = set_audit_status(audit_status,check_memory_space())
    audit_status = set_audit_status(audit_status,is_secure_boot_capable())
    audit_status = set_audit_status(audit_status,check_CPU_compatibility())

    if audit_status == "OK":
        result = "CAPABLE"
        WAPT.write_audit_data_if_changed("w11-requirements", "result", result)
        WAPT.write_audit_data_if_changed("w11-requirements", "audit_data", result_dict)
    else:
        result = "NOT CAPABLE"
        WAPT.write_audit_data_if_changed("w11-requirements", "result", result)
        WAPT.write_audit_data_if_changed("w11-requirements", "audit_data", result_dict)

    return audit_status

def check_tpm_state():

    dict_tpm = {}
    audit_tpm = "OK"
    get_tpm = run_powershell("Get-Tpm")

    if get_tpm["TpmPresent"] == False:
        print("ERROR: No TPM chip found on this system")
        audit_tpm = "ERROR"
        dict_tpm['TpmVersion'] = audit_tpm

    else:
        get_tpm_version = run_powershell("Get-WmiObject -Class Win32_Tpm -Namespace root\CIMV2\Security\MicrosoftTpm | Select-Object -Property SpecVersion")
        tpm_version = get_tpm_version["SpecVersion"].split(",")[0]
        if tpm_version != "2.0":
            print("ERROR: TPM chip not in version 2.0")
            audit_tpm = "ERROR"
            dict_tpm['TpmVersion'] = audit_tpm
        else:
            print("OK: TPM chip in version 2.0")
            audit_tpm = "OK"
            dict_tpm['TpmVersion'] = audit_tpm

    result_dict['TPM'] = dict_tpm
    return audit_tpm

def check_free_space():

    dict_disk = {}
    audit_disk = "OK"

    free_space = get_disk_free_space(systemdrive)
    free_space_GB = round(free_space / (1024**3),2)

    if free_space_GB <= 64:
        need_free = round((64 - free_space_GB),2)
        print("ERROR: Not enough space disk available")
        print(f'Need 64 GB, currently available {free_space_GB} GB')
        print(f'Need to free up {need_free} GB')
        audit_disk = "ERROR"
        dict_disk['Space Available'] = audit_disk
    else:
        print("OK: Enough space disk available")
        audit_disk = "OK"
        dict_disk['Space Available'] = audit_disk

    result_dict['Disk'] = dict_disk
    return audit_disk

def check_free_space_efi():

    dict_uefi = {}
    audit_efi = "OK"
    audit_space_efi = "OK"

    #{6F8CFC1A-0000-0000-0000-100000000000} - BIOS GUID
    #{c12a7328-f81f-11d2-ba4b-00a0c93ec93b} - UEFI GUID

    size_remaining = run_powershell("Get-Volume -UniqueId \"\\\\?\\Volume$(((Get-Partition).Where{$_.GptType -eq '{c12a7328-f81f-11d2-ba4b-00a0c93ec93b}'}.Guid))\\\" | Select-Object SizeRemaining")

    if size_remaining is None:
        print("ERROR: No EFI partition, check BIOS configuration")
        audit_efi = "ERROR"
        result_dict['UEFI - Activation'] = audit_efi
    else:
        free_space = size_remaining['SizeRemaining']
        free_space_efi = round(free_space / (1024**2),2)

        if free_space_efi <= 15:
            need_free = round((15 - free_space_efi),2)
            print("ERROR: Not enough space available on EFI Partition")
            print(f'Need 15 MB, currently available {free_space_efi} MB')
            print(f'Need to free up {need_free} MB')
            audit_efi = "OK"
            audit_space_efi = "ERROR"
            dict_uefi['Activation'] = audit_efi
            dict_uefi['Space Available'] = audit_space_efi
            result_dict['UEFI'] = dict_uefi
        else:
            print("OK: Enough space available on EFI Partition")
            print(f"{free_space_efi} MB available")
            audit_efi = "OK"
            audit_space_efi = "OK"
            dict_uefi['Activation'] = audit_efi
            dict_uefi['Space Available'] = audit_space_efi
            result_dict['UEFI'] = dict_uefi

    return audit_efi

def check_memory_space():

    dict_ram = {}
    audit_memory = "OK"

    total_memory = ceil(memory_status().ullTotalPhys / (1024**3))

    if total_memory < 4:
        print("ERROR: Not enough memory available")
        print(f'Need 4 GB of memory, currently {total_memory} GB')
        audit_memory = "ERROR"
        dict_ram['Total Memory'] = audit_memory
    else:
        print("OK: Enough memory available")
        audit_memory = "OK"
        dict_ram['Total Memory'] = audit_memory

    result_dict['RAM'] = dict_ram
    return audit_memory

def is_secure_boot_capable():

    dict_SB = {}
    audit_SB = "OK"

    try:
        secureboot_state = run_powershell("Confirm-SecureBootUEFI")
    except:
        print("SecureBoot not available")
        audit_SB = "ERROR"
        result_dict['SecureBoot'] = audit_SB
        return audit_SB

    # Check the value of the SecureBootEnabled property
    if secureboot_state == False:
        print("OK: SecureBoot is available and not enabled")
        audit_SB = "OK"
        result_dict['SecureBoot'] = audit_SB
    else:
        print("OK: SecureBoot is available and enabled")
        audit_SB = "OK"
        result_dict['SecureBoot'] = audit_SB

    return audit_SB

def check_CPU_compatibility():

    dict_cpu = {}
    audit_cpu_comp = "OK"

    wmi = wmi_info(keys=['Win32_Processor'])['Win32_Processor']

    if isinstance(wmi,list):
        wmi = wmi[0]

    cores = wmi['NumberOfCores']
    max_clock_speed = wmi['MaxClockSpeed']
    max_clock_speed_GHz = round(max_clock_speed / (1024),2)
    cpu_full_name = wmi['Name']
    cpu_manufacturer = wmi['Manufacturer'].lower()

    if 'amd' in cpu_manufacturer:
        cpu_manufacturer = 'amd'
    elif 'intel' in cpu_manufacturer:
        cpu_manufacturer = 'intel'
    elif 'qualcomm' in cpu_manufacturer:
        cpu_manufacturer = 'qualcomm'

    json_file = makepath(persistent_dir, json_source)
    with open(json_file) as f:
        data = json.load(f)

    cpu_compatible = False
    for cpu_brand, cpu_model in data[cpu_manufacturer]:
        
        cpu_full_name_tmp = cpu_full_name.replace('(R)', '').replace('(TM)', '').lower()
        cpu_brand = cpu_brand.lower()
        cpu_model = cpu_model.lower()
        
        # To handle this : Ultra 5 125U or Ultra 5-125U / i5-10210U
        if cpu_manufacturer == 'intel':
            cpu_model = cpu_model.replace('-', ' ')
            cpu_full_name_tmp = cpu_full_name_tmp.replace('-', ' ')
        
        reconstructed_cpu_full_name = ' '.join([cpu_manufacturer, cpu_brand if cpu_brand else '', cpu_model])
        if reconstructed_cpu_full_name in cpu_full_name_tmp:
            cpu_compatible = True
            break

    if cpu_compatible:
        print(f"OK: Your processor {cpu_full_name} is compatible")
        audit_cpu = "OK"
        dict_cpu['Model'] = audit_cpu
        audit_cpu_comp = set_audit_status(audit_cpu_comp, audit_cpu)
    else:
        print(f"ERROR: Your processor {cpu_full_name} is not compatible")
        audit_cpu = "ERROR"
        dict_cpu['Model'] = audit_cpu
        audit_cpu_comp = set_audit_status(audit_cpu_comp, audit_cpu)

    if cores < 2:
        print(f"ERROR: Need 2 cores minimum, currently {cores} cores on your CPU")
        audit_cores = "ERROR"
        dict_cpu['Cores'] = audit_cores
        audit_cpu_comp = set_audit_status(audit_cpu_comp, audit_cores)
    else:
        print(f"OK: Currently {cores} cores on your CPU")
        audit_cores = "OK"
        dict_cpu['Cores'] = audit_cores
        audit_cpu_comp = set_audit_status(audit_cpu_comp, audit_cores)

    if max_clock_speed < 1000:
        print(f"ERROR: Frequency under 1GHz, currently {max_clock_speed_GHz}GHz")
        audit_clock = "ERROR"
        dict_cpu['Frequency'] = audit_clock
        audit_cpu_comp = set_audit_status(audit_cpu_comp, audit_clock)
    else:
        print(f"OK: Currently {max_clock_speed_GHz}GHz")
        audit_clock = "OK"
        dict_cpu['Frequency'] = audit_clock
        audit_cpu_comp = set_audit_status(audit_cpu_comp, audit_clock)

    result_dict['CPU'] = dict_cpu
    return audit_cpu_comp

def set_audit_status(old_audit_status, new_audit_status):
    """Maintain higher criticality for audit status."""
    audit_level = {"OK": 0, "WARNING": 1, "ERROR": 2}

    old_status = old_audit_status.upper().strip()
    new_status = new_audit_status.upper().strip()

    if audit_level.get(new_status, -1) > audit_level.get(old_status, -1):
        return new_status
    else:
        return old_audit_status
# -*- coding: utf-8 -*-
from setuphelpers import *
from setupdevhelpers import *
import json
import re


def update_package():
    # Declaring local variables
    package_updated = False
    proxies = get_proxies_from_wapt_console()
    if not proxies:
        proxies = get_proxies()
    app_name = control.name

    json_file = "cpu_w11.json"

    base_url = 'https://learn.microsoft.com/en-us/windows-hardware/design/minimum/supported'

    brand_proco_url = [
        'windows-11-24h2-supported-amd-processors',
        'windows-11-24h2-supported-intel-processors',
        'windows-11-24h2-supported-qualcomm-processors'
    ]

    url_list = [ f"{base_url}/{brand}" for brand in brand_proco_url ]

    updated_date = None
    for url in url_list:
        date = bs_find_custom(url, "meta", "name", "updated_at", proxies=proxies).get('content', '')
        date_to_version = date.split('T', 1)[0].replace('-', '.')
        if updated_date or Version(date_to_version) > Version(updated_date):
            updated_date = date_to_version

    print(f"Latest version found for Windows 11 supported processors is {updated_date}")

    if Version(updated_date) > Version(control.get_software_version()):
        print("Update available for Windows 11 supported processors. Updating...")
        update_windows11_proco_requirements(url_list, json_file)
        package_updated = True
    else:
        print("No update available for Windows 11 supported processors.")

    control.set_software_version(updated_date)
    control.save_control_to_wapt()

    return package_updated

def replace_bad_naming_scheme(string):

    patterns = [
        r"processor",
        r"™|®",
        r"with (Radeon.*Graphics)|IPU",
        r"\(OEM Only\)",
        r"Microsoft Surface Edition",
    ]

    replace_patterns = {
        r"\s+processor\s+": '-',  # Replace ' processor ' by '-'
    }

    for pattern, replacement in replace_patterns.items():
        string = re.sub(pattern, replacement, string, flags=re.IGNORECASE)

    for pattern in patterns:
        string = re.sub(pattern, '', string, flags=re.IGNORECASE)
    string = " ".join(string.strip().split())

    return string

def bs_find_custom(url, element, attribute=None, value=None, user_agent=None, proxies=None, features="html.parser", **kwargs):
    url = str(url)
    if is_url(url):
        if user_agent:
            page = requests.get(url, proxies=proxies, headers={"User-Agent": user_agent}, **kwargs)
        else:
            page = requests.get(url, proxies=proxies, **kwargs)
    else:
        page = url
    soup = BeautifulSoup.BeautifulSoup(page.content, features=features)
    if value:
        return soup.find(element, {attribute: value})
    elif attribute:
        return soup.find(element, attrs={attribute: True})
    else:
        return soup.find(element)

def update_windows11_proco_requirements(url_list, filename):

    def table_to_list(table):
        result = []
        for row in table.find_all('tr')[1:]:
            brand = replace_bad_naming_scheme(row.find_all('td')[1].text)
            model = replace_bad_naming_scheme(row.find_all('td')[2].text)
            result.append((brand, model))
        return result

    proco_dict = dict()
    for url in url_list:
        cpu_manufacturer = url.rsplit('/')[-1].split('-')[-2]
        proco_dict[cpu_manufacturer] = sorted(table_to_list(bs_find_custom(url, 'table')))

    with open(filename, 'w') as f:
        json.dump(proco_dict, f, indent=4)
7e80f1c5dc06f72ce86fc3b24d9b8dbe9d4703f86923b2c435099a08ea29e3e1 : WAPT/README.md
dacb21eeab2773286c560bd362eb8b322ff736afaca55e19813e614844c5eacb : WAPT/README_fr.md
38d056ab130f7bf7c481c12636a4e9959de36561d3dfcbe54c6e3571bc0c1dc3 : WAPT/certificate.crt
fcd9e58a0582c5f941eca42012aeb0b132e6d34238a03f761b67ce648069f229 : WAPT/changelog.txt
cb923b290fa38ccbfdd2a07f578cced64b9e4de217b4246b9ae42a420a2d6f96 : WAPT/control
9ccd55c246c5266669ff70a6e62c1e315666114c6d3f854071b6ff22fe48612b : WAPT/icon.png
a6248bfc4419f214664c4025a23c9abb0028d8f446e5e580f893477a6e8772b6 : cpu_w11.json
69f360e7ddd1462a7039fd176ff84eb8bb726aff0101956aa48324ce337592a3 : luti.json
8c8e6eedbf5ea5526b80a7c74fa1a2c5ce50ee75db886ddec9f8acbcaa330402 : setup.py
caef17eed34bcb625bc1dc831c363a15265481e18841b88bb2ff3abab4342be0 : update_package.py
2021.11.30-4
using persistent_dir and reduce print

2021.11.30-3
improve json print

2021.11.30-2
initial package