Creating a brand new Windows 11 qube in Qubes

I’ve got Qubes OS up and running and I love it! But Qubes mostly comes with Linux distros and I wanted a Windows qube. The existing install instructions I found on forum.qubes-os.org were pretty good…but didn’t capture the whole experience, offer enough detail, and a few cases, had the steps slightly out of order that didn’t work for me. So, I’m creating this for anyone who wants to make a brand new Microsoft Windows 11 qube from the Windows install media, here’s what I did (your experience may vary):

You will need to get Windows 11 install media if you don’t have it already
I went to www.microsoft.com and downloaded the Windows install ISO media (it’s downloadable for free (Download Windows 11)) to my regular computer (or you can to another existing qube)

Note: Have your Windows activation key handy for the install. I had to purchase a 2nd Windows activation key for the Qubes VM even though I was installing it on the same Dell laptop that came with Windows. The Dell Windows 11 license doesn’t work in Qubes. You can purchase a Windows 11 license here: https://www.microsoft.com/en-us/d/windows-11-home for $139.

I plugged in an available USB key (needs to be 6GB or bigger)
You will need to format the USB key using ExFAT if you don’t have a USB key that will take a 5.0GB file (the FAT default can only hold 2GB/4GB files). I formatted it using Windows File Explorer.
Then I copied the Windows install media ISO to the newly formatted USB key
I inserted the Windows ISO USB key into Qubes computer USB slot

Followed these instructions to start with:How to install Windows qubes in Qubes OS | Qubes OS to create new Windows qube
I named my Windows qube Windowsvm during the creation
Follow these instructions to the point where you will boot on your USB ISO.

I could not get the Windows USB install media to boot in the new WindowsVM qube even though the USB ISO image booted just fine on my non-Qubes computers.
So I decided to copy the ISO file to an existing qube on my Qubes computer. I choose to use the Personal qube:
On Qubes, Using Qubes manager
I went into Settings on the Personal qube
I had to increase the Private storage max size from 2.0GB to 6.0 GB (you need more space for Windows ISO file).
Note: Although once you increase the size of a qube there can be issues shrinking it again after temporary use…so keep that in mind.

I started Personal qube in Qubes
I mounted the Windows ISO USB key to Personal qube
I used the File Manager app in the Personal qube to copy ISO to Personal /home/user

On the WindowsVM, I opened Settings and choose Advanced,“Boot qube from CDROM”, then choose “from file in qube” and point it to the ISO image on Personal qube and click on OK
Windows VM qubes will start automatically and Windows will begin to boot

At the first Windows install screen that asks you to select something, you have to modify the Windows registry to disable checks for the TPM chip (Qubes Xen doesn’t support TPM 2.0 yet), Secure Boot, and a RAM check. Follow these instructions before selecting any items or hitting ENTER to continue on the install screen. [The official Qubes-os.org instructions had this part too late in the install process. You need to do it as soon as you can.]

Hit Fn+Shift-F10 (or Shift-F10)…whatever works for you.
Type in regedt32.exe to start the registry editor.
Then move to the key HKEY_LOCAL_MACHINE\SYSTEM\Setup
Right-click Setup, choose New, Key, then create the key LabConfig
Right-click on LabConfig, choose New, DWORD (32-bit value), and type in BypassTPMCheck and set value = 1. Repeat twice more with BypassSecureBootCheck and BypassRAMCheck
Close the registry editor and console windows.
[Note: Microsoft can update their install procedures at anytime to invalidate these hack arounds]

When the install finishes, the WindowsVM qube will simply shutdown
Modify your WindowsVM qube settings to ensure you will have Internet connectivity to continue the install (if you don’t already).

Note: My Qube laptop’s wireless driver doesn’t work (yet), so I had to add my USB tethered Internet connection to my net-sys qube.

During the Windows install, Windows will shutdown the WindowsVM a handful of times. Each time Windows shutsdown the VM, just restart it.

This part of the install process can take a long time through many restarts.

But eventually the Windows install will start like regular, you will be prompted to type in various things and to click on many things. Choose whatever you want to finish the install.

8 Likes

I recommend to make a clone of the freshly working / finished windows installation, so it’s easy to duplicate it or restore it in case of problem.

7 Likes

You may have tried looking for your license in the registry for the below string, which was of no use in your situation (?), but maybe it’ll help others.

I was able to re-use my Windows 11 key.

I don’t have a Dell, like OP (mine’s is a used business model HP laptop with a stand-alone license), and my genuine copy of Windows was passed down from Windows 7, though the key changed, but I was able to find my key from a bare-bones install of Windows 11.

\HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\SoftwareProtectionPlatform in there, the string “BackupProductKeyDefault” may contain your license, as it did for me.

Edit: I rebooted right after updating the license. Not sure if it’s necessary, but it worked…

I did try to use a Windows 10 key that I had running in another machine, which was also passed down through the same Windows 7 license mentioned above, but it did not work. I had to copy it from a genuine Windows 11 build. Obviously the key changed from when used in Windows 10 via update to Windows 11 a while back.

1 Like

Semi-automated script to install Windows 11.

#!/bin/bash

################################################################################
# File Name    : qubes-windows11-attended.sh
# Description  : Attended Windows 11 installer for Qubes OS R4.3 with QWT support.
#                Creates a Debian-based management VM (windows-mgmt) with browser
#                for ISO download or USB attachment. Automates Windows StandaloneVM
#                creation with optimized settings and provides interactive guidance
#                for QWT installation including graphics driver warnings and backup
#                options. Also downloads and verifies the winutil debloater script
#                from Chris Titus Tech's GitHub repository.
# Usage        : • Transfer to dom0:
#                qvm-run -p appvm 'cat ~/qubes-windows11-attended.sh' > ~/qubes-windows11-attended.sh
#                • Make executable:
#                chmod +x ~/qubes-windows11-attended.sh
#                • Run:
#                bash ~/qubes-windows11-attended.sh
# Author       : Me and the bois
# License      : Free of charge, no warranty
# Last edited  : 2026-04-11
################################################################################

# Safety first
set -euo pipefail

# Management VM Configuration
MGMT_VM="windows-mgmt"               # For manual ISO download
CUSTOM_TEMPLATE="windows-mgmt-template"
BASE_TEMPLATE="debian-13-minimal"
ISO_PATH="/home/user/windows11.iso"  # Stored in the management VM
STORAGE_SIZE="10"
NET_VM="sys-firewall"                # Default network VM

# Windows 11 Configuration
VM_NAME="windows11"
VM_LABEL="orange"
WIN_NET_VM=""
WIN_STORAGE_SIZE="56"   # GiB (Windows 11 requires 56GiB minimum)
WIN_MEMORY="4096"       # MB (Windows 11 requires 4GB minimum)
WIN_MAXMEM="4096"       # MB (don't use memory balancing)
WIN_VCPUS="2"           # CPU cores (Windows 11 benefits from 4)
DEFAULT_USER="user"     # Set actual username

# QWT Configuration
INSTALL_QWT="yes"       # QWT installation
BACKUP_BEFORE_QWT="no"  # Create backup before QWT installation (recommended)

# Debloater configuration
DEBLOATER_SOURCE_URL="https://api.github.com/repos/ChrisTitusTech/winutil/releases/latest"
DEBLOATER_FILE="winutil.ps1"

# Check if running in dom0
check_dom0() {
  if ! command -v qvm-check &>/dev/null; then
    echo "ERROR: This script must be run in dom0"
    echo "Please copy this script to dom0 and run it there"
    exit 1
  fi
}

# Ask user about QWT installation
ask_qwt_installation() {
  clear
  echo ""
  echo "        QUBES WINDOWS TOOLS (QWT) OPTION"
  echo ""
  echo "Qubes Windows Tools provide better integration:"
  echo "  • Copy/paste between qubes"
  echo "  • File sharing"
  echo "  • USB device attachment"
  echo "  • Block device attachment"
  echo "  • Automatic networking"
  echo "  • Time synchronization"
  echo "  • Seamless mode (EXPERIMENTAL for Windows 10/11)"
  echo ""
  echo "Qubes R4.3 has built-in QWT support (version 4.2.2)"
  echo "  QWT will be available via: qvm-start $VM_NAME --install-windows-tools"
  echo ""
  echo "IMPORTANT NOTES (based on Qubes documentation):"
  echo "  • The graphics driver for Windows 11 is EXPERIMENTAL"
  echo "  • May cause weird display effects (e.g., windows displayed twice)"
  echo "  • Switching to/from seamless mode may cause trouble"
  echo "  • Changing screen resolution may be problematic"
  echo "  • It's SAFER to install WITHOUT the graphics driver first"
  echo "  • You can add the graphics driver later via Change installation"
  echo "  • Xen PV disk drivers are NOT installed by default (can cause BSOD)"
  echo "  • For Windows 11 25H2: windows may be displayed twice"
  echo "  • Create a backup before installing QWT (HIGHLY RECOMMENDED)"
  echo ""

  read -p "Do you want to install QWT after Windows setup? (Y/n): " confirm
  if [[ "$confirm" =~ ^[Nn]$ ]]; then
    INSTALL_QWT="no"
    echo "Skipping QWT installation"
  else
    INSTALL_QWT="yes"
    echo "QWT will be installed using: qvm-start $VM_NAME --install-windows-tools"

    read -p "Create backup before QWT installation? (Y/n): " backup_confirm
    if [[ ! "$backup_confirm" =~ ^[Nn]$ ]]; then
      BACKUP_BEFORE_QWT="yes"
      echo "Backup will be created before QWT installation"
    else
      BACKUP_BEFORE_QWT="no"
      echo "No backup will be created (not recommended)"
    fi
  fi

  read -p "Press Enter to continue..."
}

# Function to download debloater
download_debloater() {
  clear
  echo -e "\n[Downloading] Windows debloater tool..."

  if ! qvm-check "$MGMT_VM" 2>/dev/null; then
    echo "Management VM doesn't exist yet - will download after creation"
    return 0
  fi

  if ! qvm-check --running "$MGMT_VM" 2>/dev/null; then
    echo "Starting $MGMT_VM..."
    qvm-start "$MGMT_VM"
    sleep 5
  fi

  echo "Fetching latest release information..."

  local RELEASE_JSON
  RELEASE_JSON=$(qvm-run -p "$MGMT_VM" "curl -sL --tlsv1.2 --http1.1 '$DEBLOATER_SOURCE_URL'")

  if echo "$RELEASE_JSON" | grep -q "API rate limit exceeded"; then
    echo -e "\nWARNING: Failed to fetch release info from API (rate limited)" >&2
    echo "You can manually download later"
    return 0
  fi

  local DOWNLOAD_URL
  DOWNLOAD_URL=$(echo "$RELEASE_JSON" | jq -r '.assets[] | select(.name == "winutil.ps1") | .browser_download_url' | head -n 1)

  if [[ -z "$DOWNLOAD_URL" || "$DOWNLOAD_URL" == "null" ]]; then
    echo "WARNING: Could not find download URL" >&2
    return 0
  fi

  echo "Downloading from: $DOWNLOAD_URL"

  qvm-run -p "$MGMT_VM" "curl -L -o '/home/user/$DEBLOATER_FILE' '$DOWNLOAD_URL'"

  echo "Windows debloater downloaded to $MGMT_VM:/home/user/$DEBLOATER_FILE"
  echo ""
}

# Create management VM for Windows ISO
create_mgmt_vm() {
  clear
  echo "Step 1/7: Creating management VM for Windows ISO download..."

  # Check if management VM already exists
  if qvm-check "$MGMT_VM" 2>/dev/null; then
    echo "Management VM '$MGMT_VM' already exists"
    read -p "Recreate it? (y/N): " confirm
    if [[ "$confirm" =~ ^[Yy]$ ]]; then
      echo "Removing existing management VM..."
      qvm-shutdown --wait "$MGMT_VM" 2>/dev/null || true
      qvm-remove --force "$MGMT_VM"
    else
      echo "Using existing management VM"
      download_debloater
      return 0
    fi
  fi

  # Create new management VM if it doesn't exist or user chose to recreate
  if ! qvm-check "$BASE_TEMPLATE" 2>/dev/null; then
    echo "Installing $BASE_TEMPLATE..."
    sudo qubes-dom0-update --template="$BASE_TEMPLATE" || true
  fi

  echo "Creating custom builder template..."
  if qvm-check "$CUSTOM_TEMPLATE" 2>/dev/null; then
    echo "Removing existing custom template..."
    qvm-shutdown --wait "$CUSTOM_TEMPLATE" 2>/dev/null || true
    qvm-remove --force "$CUSTOM_TEMPLATE"
  fi

  qvm-clone "$BASE_TEMPLATE" "$CUSTOM_TEMPLATE"
  qvm-prefs "$CUSTOM_TEMPLATE" label black

  # Install tools in template (change as needed)
  echo "Installing tools in template..."
  qvm-run -p -u root "$CUSTOM_TEMPLATE" "
  apt-get install -y --no-install-recommends \
    qubes-core-agent-networking \
    qubes-core-agent-passwordless-root \
    qubes-core-agent-thunar \
    thunar-archive-plugin \
    p7zip-full unzip unrar-free \
    udisks2 polkitd exfat-fuse exfatprogs \
    gvfs gvfs-fuse \
    curl jq \
    firefox-esr \
    ca-certificates \
    xfce4-terminal"

  qvm-shutdown --wait "$CUSTOM_TEMPLATE"

  echo "Creating '$MGMT_VM' from template '$CUSTOM_TEMPLATE'..."
  qvm-create \
    --class AppVM \
    --template "$CUSTOM_TEMPLATE" \
    --label gray \
    --property netvm="$NET_VM" \
    "$MGMT_VM"

  echo "Extending private volume to ${STORAGE_SIZE}GB..."
  qvm-volume extend -f "$MGMT_VM:private" "${STORAGE_SIZE}G"

  qvm-features "$CUSTOM_TEMPLATE" menu-items "xfce4-terminal.desktop"
  qvm-features "$MGMT_VM" menu-items "firefox-esr.desktop thunar.desktop xfce4-terminal.desktop"

  echo "Management VM '$MGMT_VM' created successfully"

  download_debloater
  echo ""
}

# Display Windows ISO download instructions
show_download_instructions() {
  clear
  echo "Step 2/7: Download Windows 11 ISO"
  echo ""
  echo "     PLEASE DOWNLOAD WINDOWS 11 ISO MANUALLY"
  echo ""
  echo "1. Start the management VM: qvm-start $MGMT_VM"
  echo ""
  echo "2. In the management VM, open Firefox and download Windows 11 ISO from:"
  echo "   Official Microsoft: https://www.microsoft.com/software-download/windows11"
  echo "   Alternative: https://massgrave.dev/windows_11_links"
  echo ""
  echo "3. Save the ISO to: $ISO_PATH"
  echo "   (Important: Use exactly this path and filename)"
  echo ""
  echo "4. The winutil debloater has been saved to: /home/user/$DEBLOATER_FILE"
  echo "   You can copy it to your Windows VM after QWT installation"
  echo ""
  echo "5. Shutdown the management VM when done"
  echo ""

  read -p "Press Enter AFTER the ISO has been downloaded to $ISO_PATH in $MGMT_VM..."
}

# Verify Windows ISO exists in management VM
verify_iso() {
  clear
  echo "Step 3/7: Verifying Windows ISO..."

  if ! qvm-check "$MGMT_VM" 2>/dev/null; then
    echo "ERROR: Management VM '$MGMT_VM' does not exist"
    exit 1
  fi

  if ! qvm-check --running "$MGMT_VM" 2>/dev/null; then
    qvm-start "$MGMT_VM"
    sleep 10
  fi

  if ! qvm-run -p "$MGMT_VM" "test -f '$ISO_PATH'" 2>/dev/null; then
    echo "ERROR: ISO not found at $MGMT_VM:$ISO_PATH"
    echo ""
    echo "Please ensure:"
    echo "1. You have downloaded a Windows 11 ISO (64-bit)"
    echo "2. The ISO is placed at: $MGMT_VM:$ISO_PATH"
    echo ""
    exit 1
  fi

  echo "ISO verified successfully"
}

# Remove existing Windows VM if present
cleanup_existing() {
  clear
  echo "Step 4/7: Checking for existing Windows VM..."

  if qvm-check "$VM_NAME" 2>/dev/null; then
    echo "VM '$VM_NAME' already exists"
    read -p "Do you want to remove it? (y/N): " confirm
    if [[ "$confirm" =~ ^[Yy]$ ]]; then
      echo "Shutting down and removing '$VM_NAME'..."
      qvm-shutdown --wait "$VM_NAME" 2>/dev/null || true
      qvm-remove --force "$VM_NAME"
      echo "Existing VM removed"
    else
      echo "Keeping existing VM. Exiting."
      exit 0
    fi
  fi
}

# Create Windows StandaloneVM
create_vm() {
  clear
  echo "Step 5/7: Creating Windows 11 StandaloneVM..."

  echo "Creating StandaloneVM named '$VM_NAME' with ${WIN_STORAGE_SIZE}GiB root volume..."
  qvm-create \
    --class StandaloneVM \
    --label "$VM_LABEL" \
    --property virt_mode=hvm \
    --property kernel='' \
    "$VM_NAME"

  # New size in bytes x One billion (G)
  echo "Extending root volume to ${WIN_STORAGE_SIZE}GB..."
  qvm-volume extend "$VM_NAME:root" "${WIN_STORAGE_SIZE}G"

  # VM settings  (change as needed)
  echo "Configuring VM settings for Windows 11..."
  qvm-prefs "$VM_NAME" memory "$WIN_MEMORY"
  qvm-prefs "$VM_NAME" maxmem "$WIN_MAXMEM"
  qvm-prefs "$VM_NAME" vcpus "$WIN_VCPUS"
  qvm-prefs "$VM_NAME" netvm "$WIN_NET_VM"
  qvm-prefs "$VM_NAME" qrexec_timeout 7200
  qvm-prefs "$VM_NAME" default_user "$DEFAULT_USER"
  # Enable audio
  qvm-features "$VM_NAME" audio-model "ich6"
  # Enable USB and block device support
  qvm-features "$VM_NAME" stubdom-qrexec 1
  # Sync time with Qubes
  qvm-features "$VM_NAME" timezone localtime

  echo "VM '$VM_NAME' created successfully"

  echo ""
  echo "NOTE: Windows 11 requires TPM 2.0 which Xen doesn't support."
  echo "The installation will include instructions to bypass this requirement."
  echo ""
  read -p "Press Enter to continue..."
}

# Start Windows installation
start_installation() {
  clear
  echo "Step 6/7: Starting Windows 11 installation..."

  echo ""
  echo "========================================="
  echo "  WINDOWS 11 INSTALLATION GUIDE - PART 1 "
  echo "========================================="
  echo ""
  echo "IMPORTANT NOTES:"
  echo ""
  echo "• The Windows logo may appear briefly, then a black screen"
  echo "  with blinking cursor for a few MINUTES. This is NORMAL."
  echo "  Just wait until the installation window appears."
  echo ""
  echo "• After each reboot, the qube VM will automatically shut down."
  echo "  You will need to manually restart it from Qubes menu."
  echo ""
  echo "• Windows 11 requires TPM 2.0 bypass (instructions provided)"
  echo ""
  echo "• Microsoft Account Bypass (instructions provided)"
  echo ""
  echo "INSTALLATION STEPS:"
  echo ""
  echo "1. VM will boot from ISO - wait for Windows setup"
  echo "2. Select language and click 'Install now'"
  echo "3. Enter product key (or click 'I don't have a product key')"
  echo "4. Select Windows 11 edition (Pro)"
  echo "5. APPLY TPM BYPASS right after language selection"
  echo "   (instructions shown next)"
  echo "6. Choose 'Custom: Install Windows only (advanced)'"
  echo "7. Select the disk 0 (it will be automatically detected)"
  echo "8. Windows will copy files and shut down."
  echo ""

  read -p "Press Enter to continue..."

  clear
  echo ""
  echo "========================================="
  echo "    WINDOWS 11 TPM BYPASS"
  echo "========================================="
  echo ""
  echo "Windows 11 requires TPM 2.0, which Xen doesn't support."
  echo "You'll need to bypass this during installation:"
  echo ""
  echo "METHOD 1 - Registry Bypass (Works up to 25H2):"
  echo "  1. When you see the Windows setup window (right after language selection)"
  echo "  2. Press Shift+F10 to open Command Prompt"
  echo "  3. Type: regedit"
  echo "  4. Navigate to: HKEY_LOCAL_MACHINE\\SYSTEM\\Setup"
  echo "  5. Right-click → New → Key → Name it: LabConfig"
  echo "  6. Create 3 DWORD (32 bits) values in LabConfig:"
  echo "     • BypassTPMCheck = 1"
  echo "     • BypassSecureBootCheck = 1"
  echo "     • BypassRAMCheck = 1"
  echo "  7. Close registry editor and Command Prompt"
  echo "  8. Continue with installation"
  echo ""

  read -p "Press Enter to start the installation..."

  # Install Windows
  echo "Starting VM with ISO from $MGMT_VM:$ISO_PATH"
  qvm-start --cdrom="$MGMT_VM:$ISO_PATH" "$VM_NAME"

  echo ""
  echo "========================================="
  echo "    WINDOWS INSTALLATION - PART 2        "
  echo "========================================="
  echo ""
  echo "The VM will shut down automatically after the initial file copy."
  echo ""
  echo "WHEN THE VM SHUTS DOWN:"
  echo "  1. Start it again pressing Enter"
  echo "  2. Windows will continue installation and reboot several times"
  echo "  3. Start it again manually from qubes menu"
  echo "  4. Complete the Windows 11 setup wizard"
  echo "  5. Use '$DEFAULT_USER' as username and leave the password blank."
  echo "  6. If prompted for Microsoft account, use the bypass methods"
  echo ""
  echo "     ============================"
  echo "     WINDOWS 11 MS ACCOUNT BYPASS"
  echo "     ============================"
  echo "     Microsoft Account Bypass (For local account)"
  echo ""
  echo "     At the 'Let's Connect You To A Network' page:"
  echo "     A) Best method:"
  echo "        • Press Shift+F10 → type: start ms-cxh:localonly"
  echo "     B) OR:"
  echo "        • Disable netVM temporarily"
  echo "        • Press Shift+F10 → type: oobe\\bypassnro"
  echo "     C) OR:"
  echo "        • Press Shift+F10 → type: taskmgr"
  echo "      • Find 'Network Connection Flow' → End Task"
  echo "     D) OR:"
  echo "        • Use fake email: no@thankyou.com"
  echo ""
  echo "  7. Reach the Windows desktop"
  echo ""
  echo "NOTE:"
  echo "  It is encouraged to enable autologon for Windows HVMs."
  echo "  Use '$DEFAULT_USER' as username and leave the password blank."
  echo ""

  read -p "Press Enter to start Windows 11 installation..."
  qvm-start "$VM_NAME"

  echo ""
  echo ""
  echo "NOTE: • WINDOWS WILL CONTINUE INSTALLATION AND REBOOT SEVERAL TIMES"
  echo "      • START IT AGAIN FROM QUBES MENU"
  echo "      • KEEP YOUR VM ON, REACH THE WINDOWS DESKTOP"

  sleep 20

  echo ""
  echo ""
  echo ""
  read -p "Press Enter to start QWT options"

  # Handle QWT installation based on user choice
  if [[ "$INSTALL_QWT" == "yes" ]]; then
    install_qwt
  else
    echo ""
    echo "========================================="
    echo "    QWT INSTALLATION ENABLED"
    echo "========================================="
    echo ""
  fi
}

# Install Qubes Windows Tools using native Qubes method
install_qwt() {
  clear

  # Configure Windows for QWT
  echo ""
  echo "========================================="
  echo "    CONFIGURE WINDOWS 11 FOR QWT"
  echo "========================================="
  echo ""
  echo "If you want to install Qubes Windows Tools follow these steps."
  echo ""
  echo "IMPORTANT: Run these commands in Command Prompt as Administrator:"
  echo "  • Press WIN+R, type 'cmd', then press CTRL+SHIFT+ENTER"
  echo ""
  echo "  powercfg /h off          (Disable hibernation)"
  echo "  bcdedit /set testsigning on  (Allow test-signed drivers)"
  echo "  powershell Set-ExecutionPolicy Unrestricted -Force  (Allow scripts)"
  echo ""
  echo ""
  echo "Note: To revert ExecutionPolicy later: Set-ExecutionPolicy Default"
  echo ""

  echo "After running these commands"
  read -p "Press Enter to shut down Windows..."
  qvm-shutdown --wait "$VM_NAME"

  # Install QWT
  echo ""
  echo "========================================="
  echo "    QUBES WINDOWS TOOLS (QWT) INSTALLATION"
  echo "========================================="
  echo ""
  echo "QWT Benefits:"
  echo "  • Copy/paste between qubes"
  echo "  • File sharing"
  echo "  • USB device attachment"
  echo "  • Block device attachment (if PV disk drivers installed)"
  echo "  • Automatic networking"
  echo "  • Time synchronization"
  echo ""
  echo "IMPORTANT NOTES for Windows 11 (from Qubes documentation):"
  echo ""
  echo "• The graphics driver for Windows 11 is EXPERIMENTAL"
  echo "  - May cause windows to be displayed twice (especially 25H2+)"
  echo "  - Switching to/from seamless mode may cause trouble"
  echo "  - Changing screen resolution may be problematic"
  echo "  - Second instance can be moved to another workspace"
  echo ""
  echo "• Qubes GUI Agent:"
  echo "  - Video driver and GUI agent that enable the seamless GUI mode that"
  echo "    integrates Windows apps onto the common Qubes trusted desktop"
  echo ""
  echo "• Xen PV Disk Drivers:"
  echo "  - NOT installed by default (can cause BSOD)"
  echo "  - Enable at your own risk"
  echo "  - Without them, qvm-block won't work"
  echo ""
  echo "• RECOMMENDED: Install WITHOUT these components initially:"
  echo "  ✓ Base Xen PV Drivers (required)"
  echo "  ✗ Qubes Video Driver (EXPERIMENTAL - skip!)"
  echo "  ✗ Xen PV Disk Drivers (can cause BSOD - skip!)"
  echo "  ✓ Clipboard & File sharing (safe)"
  echo "  ✓ Move user profiles (if using as template)"
  echo ""
  echo "========================================="
  echo " KNOWN ISSUES (from Qubes documentation)"
  echo "========================================="
  echo ""
  echo "• Windows 11 25H2+: Windows may be displayed twice"
  echo "  Solution: Move second instance to another workspace"
  echo ""
  echo "• Seamless mode is experimental"
  echo "  May cause issues when switching modes"
  echo ""
  echo "• Screen resolution changes may be problematic"
  echo "  Stick to one resolution after setup"
  echo ""
  echo "• For Qubes support:"
  echo "  https://forum.qubes-os.org/"
  echo ""

  if [[ "$BACKUP_BEFORE_QWT" == "yes" ]]; then
    echo "Creating backup: ${VM_NAME}-pre-qwt"
    if qvm-check "${VM_NAME}-pre-qwt" 2>/dev/null; then
      qvm-remove --force "${VM_NAME}-pre-qwt"
    fi
    qvm-clone "$VM_NAME" "${VM_NAME}-pre-qwt"
    echo "Backup created successfully"
    echo ""
  fi

  read -p "Press Enter to start QWT installation..."

  # Check if QWT is available
  if [ -f "/usr/lib/qubes/qubes-windows-tools.iso" ]; then
    echo "Qubes Windows Tools ISO found in dom0."
  else
    echo "Qubes Windows Tools ISO not found. Installing qubes-windows-tools package..."
    echo "This may take a few minutes..."

    if ! sudo qubes-dom0-update -y qubes-windows-tools; then
      echo "ERROR: Failed to install qubes-windows-tools package!" >&2
      exit 1
    fi

    if [ ! -f "/usr/lib/qubes/qubes-windows-tools.iso" ]; then
      echo "ERROR: qubes-windows-tools package installed but ISO file is still missing!" >&2
      exit 1
    fi

    echo "Qubes Windows Tools ISO installed successfully!"
  fi

  echo ""
  echo "Starting Windows VM with --install-windows-tools flag..."
  echo ""

  if ! qvm-start "$VM_NAME" --install-windows-tools; then
    echo "ERROR: Failed to start Windows VM with QWT installation flag!" >&2
    exit 1
  fi

  echo ""
  echo "========================================="
  echo "    IN WINDOWS 11 VM - INSTALL QWT"
  echo "========================================="
  echo ""
  echo "1. Open File Explorer → This PC → CD-ROM drive"
  echo "2. Run qubes-tools-4.2.2.exe as Administrator"
  echo "3. In setup, UNCHECK these components:"
  echo "   • 'Qubes Video Driver' (EXPERIMENTAL - causes issues)"
  echo "   • 'Xen PV Disk Drivers' (can cause BSOD)"
  echo "4. CHECK these components:"
  echo "   • 'Base Xen PV Drivers' (required)"
  echo "   • 'Clipboard sender/receiver'"
  echo "   • 'File sender/receiver'"
  echo "5. Select 'Move user profiles' if using as template"
  echo "6. When asked to reboot during installation, select NO"
  echo "7. Allow all driver installation prompts"
  echo "8. After completion, shut down the VM completely"
  echo ""

  read -p "Press Enter AFTER QWT installation and shut down is COMPLETE..."

  echo "Starting VM..."
  qvm-shutdown --wait "$VM_NAME"
  qvm-start "$VM_NAME"

  echo ""
  echo "========================================="
  echo "    POST-QWT CONFIGURATION"
  echo "========================================="
  echo ""
  echo "Run these commands in dom0 to enable/disable features:"
  echo ""
  echo "• To enable seamless mode after graphics driver install:"
  echo "  qvm-features $VM_NAME gui 1"
  echo ""
  echo "  To disable:"
  echo "  qvm-features $VM_NAME gui \"\""
  echo "  qvm-features $VM_NAME gui-emulated 1"
  echo ""

  read -p "Press Enter to continue..."

  if [[ "$BACKUP_BEFORE_QWT" == "yes" ]]; then
    echo ""
    echo "Backup created: ${VM_NAME}-pre-qwt"
    echo "  To restore: qvm-remove $VM_NAME && qvm-clone ${VM_NAME}-pre-qwt $VM_NAME"
    echo ""
  fi
}

# Show final instructions
show_final_instructions() {
  clear
  echo ""
  echo "========================================="
  echo "          INSTALLATION COMPLETE!"
  echo "========================================="
  echo ""
  echo "VMs created:"
  echo "  • $MGMT_VM - Management VM (browser, file manager)"
  echo "  • $VM_NAME - Windows 11 StandaloneVM"
  echo ""

  echo "========================================="
  echo "          IMPORTANT NEXT STEPS"
  echo "========================================="

  echo "1. Windows debloater tool location:"
  echo "  • $MGMT_VM:/home/user/$DEBLOATER_FILE"
  echo "  • Copy to Windows VM:"
  echo "    Copy from $MGMT_VM to $VM_NAME using Qubes file manager"
  echo "  • Go to:"
  echo "    C:\\Users\\$DEFAULT_USER\\Documents\\QubesIncoming\\$MGMT_VM"
  echo "    Right-click the script → 'Execute with PowerShell'"
  echo ""
  echo "2. Run Windows Update (may take hours)"
  echo ""
  echo "3. Create a final backup:"
  echo "   qvm-clone $VM_NAME ${VM_NAME}-final"
  echo ""
  echo "4. If network doesn't work (DHCP issues):"
  echo "   - Check IP with: qvm-ls -n $VM_NAME"
  echo "   - Set static IP in Windows Network Settings"
  echo ""
  echo "5. Retrieve Windows product key from Linux (if pre-installed):"
  echo "   sudo strings /sys/firmware/acpi/tables/MSDM"
  echo ""
  echo "6. For better performance:"
  echo "   - Disable visual effects in Windows"
  echo "   - Disable unnecessary services"
  echo ""
  echo "7. If you installed graphics driver:"
  echo "   qvm-features $VM_NAME gui 1"
  echo ""

  if [[ "$INSTALL_QWT" == "no" ]]; then
    echo "To install QWT later:"
    echo "  qvm-start $VM_NAME --install-windows-tools"
    echo ""
  fi
}

# Main execution
main() {
  clear
  echo ""
  echo "========================================="
  echo "    Qubes Windows 11 Automated Installation"
  echo "         For Qubes OS R4.3 (stable)"
  echo "========================================="
  echo ""

  check_dom0

  echo "This script will:"
  echo "  1. Create/Use '$MGMT_VM' VM with browser for Windows 11 ISO download"
  echo "  2. Download Windows debloater tool (winutil.ps1)"
  echo "  3. Guide you to download Windows 11 ISO"
  echo "  4. Ask about Qubes Windows Tools (QWT) installation"
  echo "  5. Create a Windows 11 StandaloneVM with:"
  echo "     • Name:       $VM_NAME"
  echo "     • Root size:  ${WIN_STORAGE_SIZE}GiB (56GiB minimum)"
  echo "     • Memory:     ${WIN_MEMORY}MB (4GB minimum)"
  echo "     • CPU cores:  ${WIN_VCPUS}"
  echo "     • NetVM:      $WIN_NET_VM"
  echo "  6. Provide Windows 11 TPM/Secure Boot bypass instructions"
  echo "  7. Install QWT (optional, with safety warnings)"
  echo ""

  read -p "Proceed with installation? (y/N): " confirm
  if [[ ! "$confirm" =~ ^[Yy]$ ]]; then
    echo "Installation cancelled"
    exit 0
  fi

  create_mgmt_vm
  show_download_instructions
  verify_iso
  ask_qwt_installation
  cleanup_existing
  create_vm
  start_installation

  show_final_instructions
}

# Run main function
main "$@"

TO DO:

  • Better user choices for shut down and starts
  • More options of choice for the user
  • Another script version for Windows 11 template and disposable
2 Likes

Who even needs Windows anymore if we have Bottles and Proton?

1 Like

Look into the government offices what they are running. But perhaps this may change within the next 50 years if they are fast. :wink:

1 Like

Do you have any idea on how to get sys-whonix as a netqube for a Windows 11 Template Working?

1 Like

2 Likes