Saltar al contenido principal
Este artículo detalla el proceso para verificar qué dispositivos Windows 10 son elegibles para una actualización a Windows 11 y iniciar automáticamente esa actualización usando políticas FleetDM y scripts de PowerShell. El procedimiento incluye:
  • Detectar y almacenar los componentes necesarios del sistema (TPM 2.0 y arranque seguro) en el registro;
  • Validar los requisitos de hardware y software para determinar la elegibilidad para la actualización;
  • Ejecutar una descarga automatizada y una instalación silenciosa de Windows 11 en dispositivos compatibles.

1. Clasificar dispositivos con TPM y arranque seguro presentes

1.1. Cree la política de detección (registro FleetDM)

Utilice la siguiente consulta para verificar la presencia de claves de registro que almacenarán el estado de TPM y Arranque seguro:
SELECT 1 WHERE EXISTS (
      SELECT 1 FROM registry
      WHERE path = 'HKEY_LOCAL_MACHINE\Software\FleetDM\TPMVersion'
    )
    AND EXISTS (
      SELECT 1 FROM registry
      WHERE path = 'HKEY_LOCAL_MACHINE\Software\FleetDM\SecureBoot'
    );

1.2. Ejecute el script asociado (rellene el registro)

Adjunte este script de PowerShell a la política anterior. Detecta la versión de TPM y el estado de arranque seguro y luego los escribe en el registro Windows para FleetDM.
$TPM = Get-WmiObject -Namespace "Root\CIMv2\Security\MicrosoftTpm" -Class Win32_Tpm
$SecureBoot = Confirm-SecureBootUEFI

$TPMVersion = $TPM.SpecVersion
$SecureBootEnabled = if ($SecureBoot) { 1 } else { 0 }

# Write values to the registry (example)
New-Item -Path "HKLM:\Software\FleetDM" -Force | Out-Null
Set-ItemProperty -Path "HKLM:\Software\FleetDM" -Name "TPMVersion" -Value $TPMVersion
Set-ItemProperty -Path "HKLM:\Software\FleetDM" -Name "SecureBoot" -Value $SecureBootEnabled
Resultado esperado: HKLM\Software\FleetDM\TPMVersion y HKLM\Software\FleetDM\SecureBoot se crean/actualizan.

2. Evaluar la elegibilidad de un dispositivo Windows 10 para Windows 11

Cree la siguiente política para validar los requisitos mínimos (RAM, núcleos de CPU, arquitectura, TPM 2.0, arranque seguro) y excluir dispositivos que no cumplan.
SELECT 1 FROM os_version as os JOIN system_info as si WHERE
    os.name NOT LIKE 'Microsoft Windows 10%'
    OR si.physical_memory < 4 * 1024 * 1024 * 1024
    OR si.cpu_physical_cores < 2
    OR si.cpu_type NOT LIKE '%x86_64%'
    OR NOT EXISTS (
      SELECT * FROM registry
      WHERE path = 'HKEY_LOCAL_MACHINE\Software\FleetDM\TPMVersion'
        AND data LIKE '2%'
    )
    OR NOT EXISTS (
      SELECT * FROM registry
      WHERE path = 'HKEY_LOCAL_MACHINE\Software\FleetDM\SecureBoot'
        AND data = '1'
    );
Interpretation: the query returns 1 if the device is not a compliant Windows 10. Use it as a non-compliance policy to keep only eligible devices (those for which the query does not return 1).

3. Active la actualización Windows 11 (dispositivos elegibles)

Adjunte el siguiente script de implementación a los dispositivos compatibles. Descarga la ISO Windows 11, monta la imagen, copia las fuentes localmente y programa una configuración silenciosa en SISTEMA.
# Imports
Import-Module BitsTransfer

# Variables
$uri = "https://production-bucket-public-files.s3.eu-west-3.amazonaws.com/Win11_24H2_French_x64.iso" # French locale — replace with the appropriate locale ISO for your region
$destination = "C:\Win11.iso"
$log = "C:\logs\download_win11_iso.log"

# Create the logs folder if it doesn't exist
if (-not (Test-Path -Path "C:\logs")) {
    New-Item -Path "C:\logs" -ItemType Directory | Out-Null
}

# Start the download
try {
    "`n[$(Get-Date)] Starting download..." | Out-File -Append $log
    if (-not (Test-Path $destination)){
      Start-BitsTransfer -Source $uri -Destination $destination
    }
    "`n[$(Get-Date)] Download completed successfully." | Out-File -Append $log
} catch {
    "`n[$(Get-Date)] Error during download: $_" | Out-File -Append $log
}

# Additional variables
$isoPath = "C:\Win11.iso"
$setupFolder = "C:\Temp\Win11Files"
$taskName = "Win11SilentUpgrade"

# Step 1 - Mount the ISO
Mount-DiskImage -ImagePath $isoPath -PassThru | Out-Null
Start-Sleep -Seconds 2
$vol = Get-Volume -DiskImage (Get-DiskImage -ImagePath $isoPath)
$driveLetter = $vol.DriveLetter

# Step 2 - Copy ISO content locally
New-Item -ItemType Directory -Force -Path $setupFolder | Out-Null
Copy-Item "$driveLetter`:\*" -Destination $setupFolder -Recurse

# Unmount the ISO
Dismount-DiskImage -ImagePath $isoPath

# Step 3 - Create and schedule the installation task
$action = New-ScheduledTaskAction -Execute "C:\Temp\Win11Files\setup.exe" -Argument "/auto upgrade /migratedrivers none /resizerecoverypartition enable /dynamicupdate disable /eula accept /quiet /noreboot /uninstall disable /compat ignorewarning /copylogs C:\logs\WinSetup.log"
$principal = New-ScheduledTaskPrincipal -UserId "SYSTEM" -LogonType ServiceAccount -RunLevel Highest
$task = New-ScheduledTask -Action $action -Principal $principal -Trigger (New-ScheduledTaskTrigger -Once -At (Get-Date).AddMinutes(1))

Register-ScheduledTask -TaskName $taskName -InputObject $task -Force

# Step 4 - Start the task immediately
Start-ScheduledTask -TaskName $taskName