How to inject vioscsi driver into Windows install.win & boot.win using linux tools only ?

shodan

Active Member
Sep 1, 2022
143
38
33
Hi,

I am trying to create a windows installer that has the virtio drivers builtin, for fully automatic and unattended installation.

In particular I am trying to inject the driver vioscsi into boot.wim and then install.wim

I can unpack and repack the iso.

I can inject actual driver files into the wim files

I think all that is left is to create the registery keys in the registery hive files,


The keys that need to be created, if I had a "reg add" command

Code:
REG ADD "HKLM\SYSTEM\CurrentControlSet\Services\vioscsi" /v Start /t REG_DWORD /d 0 /f
REG ADD "HKLM\SYSTEM\CurrentControlSet\Services\vioscsi" /v Type /t REG_DWORD /d 1 /f
REG ADD "HKLM\SYSTEM\CurrentControlSet\Services\vioscsi" /v ErrorControl /t REG_DWORD /d 1 /f
REG ADD "HKLM\SYSTEM\CurrentControlSet\Services\vioscsi" /v ImagePath /t REG_EXPAND_SZ /d System32\drivers\vioscsi.sys /f
REG ADD "HKLM\SYSTEM\CurrentControlSet\Services\vioscsi" /v LoadOrderGroup /t REG_SZ /d "SCSI miniport" /f

REG ADD "HKLM\SYSTEM\CurrentControlSet\Services\EventLog\System\vioscsi" /v EventMessageFile /t REG_EXPAND_SZ /d %SystemRoot%\System32\IoLogMsg.dll /f
REG ADD "HKLM\SYSTEM\CurrentControlSet\Services\EventLog\System\vioscsi" /v TypesSupported /t REG_DWORD /d 7 /f

REG ADD "HKLM\SYSTEM\CurrentControlSet\Services\vioscsi\Parameters" /v BusType /t REG_DWORD /d 10 /f

REG ADD "HKLM\SYSTEM\CurrentControlSet\Services\vioscsi\Parameters\PnpInterface" /v 5 /t REG_DWORD /d 1 /f

REG ADD "HKLM\SYSTEM\CurrentControlSet\Services\vioscsi\Parameters\Interrupt Management\MessageSignaledInterruptProperties" /v MSISupported /t REG_DWORD /d 1 /f
REG ADD "HKLM\SYSTEM\CurrentControlSet\Services\vioscsi\Parameters\Interrupt Management\MessageSignaledInterruptProperties" /v MessageNumberLimit /t REG_DWORD /d 258 /f

REG ADD "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Setup\PnpLockdownFiles\%SystemRoot%/System32/drivers/vioscsi.sys" /v Class /t REG_DWORD /d 5 /f
### REG ADD "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Setup\PnpLockdownFiles\%SystemRoot%/System32/drivers/vioscsi.sys" /v Owners /t REG_BINARY /d <hex_value_of_inf_file> /f
REG ADD "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Setup\PnpLockdownFiles\%SystemRoot%/System32/drivers/vioscsi.sys" /v Source /t REG_EXPAND_SZ /d %SystemRoot%\System32\DriverStore\FileRepository\vioscsi.inf_amd64 /f

REG ADD "HKLM\SYSTEM\DriverDatabase" /v OemInfMap /t REG_BINARY /d e0 /f

REG ADD "HKLM\SYSTEM\DriverDatabase\DeviceIds\PCI\VEN_1AF4&DEV_1004" /v vioscsi.inf /t REG_BINARY /d 02FF0000 /f
REG ADD "HKLM\SYSTEM\DriverDatabase\DeviceIds\PCI\VEN_1AF4&DEV_1048" /v vioscsi.inf /t REG_BINARY /d 02FF0000 /f

REG ADD "HKLM\SYSTEM\DriverDatabase\DriverPackages\vioscsi.inf_amd64_78d23e29bdcf3e06" /v Catalog /t REG_SZ /d vioscsi.cat /f
REG ADD "HKLM\SYSTEM\DriverDatabase\DriverPackages\vioscsi.inf_amd64_78d23e29bdcf3e06" /v InfName /t REG_SZ /d vioscsi.inf /f
### REG ADD "HKLM\SYSTEM\DriverDatabase\DriverPackages\vioscsi.inf_amd64_78d23e29bdcf3e06" /v OemPath /t REG_SZ /d C:\Users\<username>\Downloads\drivers /f
REG ADD "HKLM\SYSTEM\DriverDatabase\DriverPackages\vioscsi.inf_amd64_78d23e29bdcf3e06" /v Provider /t REG_SZ /d "Red Hat, Inc." /f
###REG ADD "HKLM\SYSTEM\DriverDatabase\DriverPackages\vioscsi.inf_amd64_78d23e29bdcf3e06" /v SignerName /t REG_SZ /d "<signature_info>" /f
REG ADD "HKLM\SYSTEM\DriverDatabase\DriverPackages\vioscsi.inf_amd64_78d23e29bdcf3e06" /v SignerScore /t REG_DWORD /d 218103812 /f
###REG ADD "HKLM\SYSTEM\DriverDatabase\DriverPackages\vioscsi.inf_amd64_78d23e29bdcf3e06" /v Version /t REG_BINARY /d <binary_version_data> /f

REG ADD "HKLM\SYSTEM\DriverDatabase\DriverPackages\vioscsi.inf_amd64_78d23e29bdcf3e06" /v Class /t REG_SZ /d "SCSIAdapter" /f
REG ADD "HKLM\SYSTEM\DriverDatabase\DriverPackages\vioscsi.inf_amd64_78d23e29bdcf3e06" /v ClassGUID /t REG_SZ /d "{4D36E97B-E325-11CE-BFC1-08002BE10318}" /f
REG ADD "HKLM\SYSTEM\DriverDatabase\DriverPackages\vioscsi.inf_amd64_78d23e29bdcf3e06" /v DriverVer /t REG_SZ /d "07/15/2024,100.95.104.26200" /f
REG ADD "HKLM\SYSTEM\DriverDatabase\DriverPackages\vioscsi.inf_amd64_78d23e29bdcf3e06" /v Provider /t REG_SZ /d "Red Hat, Inc." /f

REG ADD "HKLM\SYSTEM\DriverDatabase\DeviceIds\PCI\VEN_1AF4&DEV_1004&SUBSYS_00081AF4&REV_00" /v vioscsi.inf /t REG_BINARY /d 01FF0000 /f
REG ADD "HKLM\SYSTEM\DriverDatabase\DeviceIds\PCI\VEN_1AF4&DEV_1048&SUBSYS_11001AF4&REV_01" /v vioscsi.inf /t REG_BINARY /d 01FF0000 /f


But I would like to create cleaner, more reusable shell function for adding each node/key/values


Here is an untested attempt of ths reg_add shellfunction
Code:
reg_add() {
    local hive_file="$1"
    local registry_path="$2"
    local value_name="$3"
    local value_type="$4"
    local value_data="$5"

    if [[ -z "$hive_file" || -z "$registry_path" || -z "$value_name" || -z "$value_type" || -z "$value_data" ]]; then
        echo "Usage: reg_add /path/to/hive/file \"[registry_path]\" value_name value_type value_data"
        return 1
    fi

    # Convert the registry path for hivexsh
    local hive_path
    hive_path=$(echo "$registry_path" | sed -e 's/^\[//' -e 's/\]$//' -e 's|\\|/|g')

    # Run hivexsh commands
    hivexsh -w "$hive_file" <<EOF
cd $hive_path
setval 1
$value_name
$value_type:$value_data
commit
exit
EOF

    if [[ $? -eq 0 ]]; then
        echo "Successfully added \"$value_name\" to \"$registry_path\" in \"$hive_file\"."
    else
        echo "Failed to add \"$value_name\" to \"$registry_path\" in \"$hive_file\"."
        return 1
    fi
}

So we might then have a single shell function to just add vioscsi to a specified hive

Code:
#!/bin/bash

# Function to add vioscsi-related registry entries to a hive file
add_vioscsi_to_hive() {
    local hive_file="$1"

    if [[ -z "$hive_file" ]]; then
        echo "Usage: add_vioscsi_to_hive /path/to/hive"
        return 1
    fi

    if [[ ! -f "$hive_file" ]]; then
        echo "Hive file '$hive_file' not found."
        return 1
    fi

    echo "Adding vioscsi keys to hive: $hive_file"

    # SYSTEM\CurrentControlSet\Services\vioscsi
    reg_add "$hive_file" "[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\vioscsi]" Start dword "00000000"
    reg_add "$hive_file" "[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\vioscsi]" Type dword "00000001"
    reg_add "$hive_file" "[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\vioscsi]" ErrorControl dword "00000001"
    reg_add "$hive_file" "[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\vioscsi]" ImagePath hex(2) "53,79,73,74,65,6d,33,32,5c,64,72,69,76,65,72,73,5c,76,69,6f,73,63,73,69,2e,73,79,73"
    reg_add "$hive_file" "[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\vioscsi]" LoadOrderGroup string "SCSI miniport"

    # SYSTEM\CurrentControlSet\Services\EventLog\System\vioscsi
    reg_add "$hive_file" "[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\EventLog\System\vioscsi]" EventMessageFile hex(2) "25,53,79,73,74,65,6d,52,6f,6f,74,25,5c,53,79,73,74,65,6d,33,32,5c,49,6f,4c,6f,67,4d,73,67,2e,64,6c,6c"
    reg_add "$hive_file" "[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\EventLog\System\vioscsi]" TypesSupported dword "00000007"

    # SYSTEM\CurrentControlSet\Services\vioscsi\Parameters
    reg_add "$hive_file" "[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\vioscsi\Parameters]" BusType dword "0000000A"

    # SYSTEM\CurrentControlSet\Services\vioscsi\Parameters\PnpInterface
    reg_add "$hive_file" "[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\vioscsi\Parameters\PnpInterface]" 5 dword "00000001"

    # SYSTEM\CurrentControlSet\Services\vioscsi\Parameters\Interrupt Management\MessageSignaledInterruptProperties
    reg_add "$hive_file" "[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\vioscsi\Parameters\Interrupt Management\MessageSignaledInterruptProperties]" MSISupported dword "00000001"
    reg_add "$hive_file" "[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\vioscsi\Parameters\Interrupt Management\MessageSignaledInterruptProperties]" MessageNumberLimit dword "00000102"

    # SOFTWARE\Microsoft\Windows\CurrentVersion\Setup\PnpLockdownFiles
    reg_add "$hive_file" "[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Setup\PnpLockdownFiles\%SystemRoot%/System32/drivers/vioscsi.sys]" Class dword "00000005"
    reg_add "$hive_file" "[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Setup\PnpLockdownFiles\%SystemRoot%/System32/drivers/vioscsi.sys]" Source hex(2) "25,53,79,73,74,65,6d,52,6f,6f,74,25,5c,53,79,73,74,65,6d,33,32,5c,44,72,69,76,65,72,53,74,6f,72,65,5c,46,69,6c,65,52,65,70,6f,73,69,74,6f,72,79,5c,76,69,6f,73,63,73,69,2e,69,6e,66,5f,61,6d,64,36,34"

    # SYSTEM\DriverDatabase
    reg_add "$hive_file" "[HKEY_LOCAL_MACHINE\SYSTEM\DriverDatabase]" OemInfMap hex "e0"

    # SYSTEM\DriverDatabase\DeviceIds
    reg_add "$hive_file" "[HKEY_LOCAL_MACHINE\SYSTEM\DriverDatabase\DeviceIds\PCI\VEN_1AF4&DEV_1004]" vioscsi.inf hex "02FF0000"
    reg_add "$hive_file" "[HKEY_LOCAL_MACHINE\SYSTEM\DriverDatabase\DeviceIds\PCI\VEN_1AF4&DEV_1048]" vioscsi.inf hex "02FF0000"

    # SYSTEM\DriverDatabase\DriverPackages
    reg_add "$hive_file" "[HKEY_LOCAL_MACHINE\SYSTEM\DriverDatabase\DriverPackages\vioscsi.inf_amd64_78d23e29bdcf3e06]" Catalog string "vioscsi.cat"
    reg_add "$hive_file" "[HKEY_LOCAL_MACHINE\SYSTEM\DriverDatabase\DriverPackages\vioscsi.inf_amd64_78d23e29bdcf3e06]" InfName string "vioscsi.inf"
    reg_add "$hive_file" "[HKEY_LOCAL_MACHINE\SYSTEM\DriverDatabase\DriverPackages\vioscsi.inf_amd64_78d23e29bdcf3e06]" Provider string "Red Hat, Inc."
    reg_add "$hive_file" "[HKEY_LOCAL_MACHINE\SYSTEM\DriverDatabase\DriverPackages\vioscsi.inf_amd64_78d23e29bdcf3e06]" SignerScore dword "0D000004"
    reg_add "$hive_file" "[HKEY_LOCAL_MACHINE\SYSTEM\DriverDatabase\DriverPackages\vioscsi.inf_amd64_78d23e29bdcf3e06]" Class string "SCSIAdapter"
    reg_add "$hive_file" "[HKEY_LOCAL_MACHINE\SYSTEM\DriverDatabase\DriverPackages\vioscsi.inf_amd64_78d23e29bdcf3e06]" ClassGUID string "{4D36E97B-E325-11CE-BFC1-08002BE10318}"
    reg_add "$hive_file" "[HKEY_LOCAL_MACHINE\SYSTEM\DriverDatabase\DriverPackages\vioscsi.inf_amd64_78d23e29bdcf3e06]" DriverVer string "07/15/2024,100.95.104.26200"

    # SYSTEM\DriverDatabase\DeviceIds\PCI with SUBSYS
    reg_add "$hive_file" "[HKEY_LOCAL_MACHINE\SYSTEM\DriverDatabase\DeviceIds\PCI\VEN_1AF4&DEV_1004&SUBSYS_00081AF4&REV_00]" vioscsi.inf hex "01FF0000"
    reg_add "$hive_file" "[HKEY_LOCAL_MACHINE\SYSTEM\DriverDatabase\DeviceIds\PCI\VEN_1AF4&DEV_1048&SUBSYS_11001AF4&REV_01]" vioscsi.inf hex "01FF0000"

    echo "Finished adding vioscsi keys to hive: $hive_file"
}


I have created a shell function which can inject drivers files to all "image indexes" in the wim file

Code:
inject_filesandfolders_to_all_wim_images iso-master/sources/boot.wim \
virtio-unzipped/vioscsi/w10/amd64/vioscsi.cat /windows/inf \
virtio-unzipped/vioscsi/w10/amd64/vioscsi.inf /windows/inf \
virtio-unzipped/vioscsi/w10/amd64/vioscsi.sys /windows/system32/drivers


Shell function not fully tested
Code:
inject_filesandfolders_to_all_wim_images() { local wim_file="$1"; shift; local dest_folder="/"; local sources=(); for arg in "$@"; do [ -e "$arg" ] && sources+=("$arg") || { [ ${#sources[@]} -gt 0 ] && { dest_folder="$arg"; for source in "${sources[@]}"; do for i in $(seq 1 "$(wimlib-imagex info "$wim_file" | grep -i "Image Count" | awk '{print $NF}')"); do [ -d "$source" ] && echo "Injecting folder $source into image index $i at $dest_folder..." && wimlib-imagex update "$wim_file" $i --command="add $source $dest_folder" || [ -f "$source" ] && echo "Injecting file $source into image index $i at $dest_folder/$(basename "$source")..." && wimlib-imagex update "$wim_file" $i --command="add $source $dest_folder/$(basename "$source")"; done; done; sources=(); }; dest_folder="$arg"; }; done; [ ${#sources[@]} -gt 0 ] && { for source in "${sources[@]}"; do for i in $(seq 1 "$(wimlib-imagex info "$wim_file" | grep -i "Image Count" | awk '{print $NF}')"); do [ -d "$source" ] && echo "Injecting folder $source into image index $i at /..." && wimlib-imagex update "$wim_file" $i --command="add $source /" || [ -f "$source" ] && echo "Injecting file $source into image index $i at /$(basename "$source")..." && wimlib-imagex update "$wim_file" $i --command="add $source /$(basename "$source")"; done; done; }; }


then I repack the iso

create_windows_iso /mnt/iso/template/win10-repack/iso-master /mnt/iso/template/iso/Win10_22H2_EnglishInternational_x64_unattended-2025-1-10.iso

shell function not fully tested
Code:
create_windows_iso() { local src_folder="$1" out_iso="$2"; xorriso -as mkisofs -iso-level 3 -full-iso9660-filenames -volid "CCCOMA_X64FRE_EN-GB_DV9" -output "$out_iso" -eltorito-boot boot/etfsboot.com -eltorito-catalog boot/boot.cat -no-emul-boot -boot-load-size 8 -boot-info-table -eltorito-alt-boot -e efi/microsoft/boot/efisys.bin -no-emul-boot -boot-load-size 1 -isohybrid-gpt-basdat "$src_folder"; }

Code:
get_wim_image_count() { wimlib-imagex info "$1" | grep -i "Image Count" | awk '{print $NF}'; }

mount_wim_image() { local wim_file="$1" index="$2" mount_point="$3/$index"; [ -d "$mount_point" ] && [ "$(ls -A "$mount_point" 2>/dev/null)" ] && { echo "Error: Mount point $mount_point is not empty"; return 1; }; mkdir -p "$mount_point"; wimlib-imagex mount "$wim_file" "$index" "$mount_point" --rw; }

mount_wim_image() { local wim_file="$1" index="$2" mount_point="$3/$index"; [ -d "$mount_point" ] && [ "$(ls -A "$mount_point" 2>/dev/null)" ] && { echo "Error: Mount point $mount_point is not empty"; return 1; }; mkdir -p "$mount_point"; wimlib-imagex mount "$wim_file" "$index" "$mount_point" --rw; }


And now putting it all together

Code:
unpack_iso /mnt/iso/template/iso/virtio-win-0.1.262.iso /mnt/iso/template/win10-repack/virtio-unzipped

unpack_iso /mnt/iso/template/iso/Win10_22H2_EnglishInternational_x64.iso /mnt/iso/template/win10-repack/iso-master
inject_filesandfolders_to_all_wim_images iso-master/sources/boot.wim virtio-unzipped/vioscsi/w10/amd64/vioscsi.cat /windows/inf virtio-unzipped/vioscsi/w10/amd64/vioscsi.inf windows/inf virtio-unzipped/vioscsi/w10/amd64/vioscsi.sys /windows/system32/drivers
inject_filesandfolders_to_all_wim_images iso-master/sources/install.wim virtio-unzipped/vioscsi/w10/amd64/vioscsi.cat /windows/inf virtio-unzipped/vioscsi/w10/amd64/vioscsi.inf windows/inf virtio-unzipped/vioscsi/w10/amd64/vioscsi.sys /windows/system32/drivers

for i in $(seq 1 "$(get_wim_image_count iso-master/sources/boot.wim)"); do
   mount_wim_image iso-master/sources/boot.wim $i /mnt/iso/template/win10-repack/wim-mounts/boot/
   add_vioscsi_to_hive wim-mounts/boot/windows/System32/Config/SYSTEM
   unmount_wim_image iso-master/sources/boot.wim $i /mnt/iso/template/win10-repack/wim-mounts/boot/
done

for i in $(seq 1 "$(get_wim_image_count iso-master/sources/install.wim)"); do
   mount_wim_image iso-master/sources/install.wim $i /mnt/iso/template/win10-repack/wim-mounts/install/
   add_vioscsi_to_hive wim-mounts/install/windows/System32/Config/SYSTEM
   unmount_wim_image iso-master/sources/install.wim $i /mnt/iso/template/win10-repack/wim-mounts/install/
done

create_windows_iso /mnt/iso/template/win10-repack/iso-master /mnt/iso/template/iso/Win10_22H2_EnglishInternational_x64_unattended-2025-1-10.iso
 
I was curious, why did distrobuilder windows repack did not use this special folder

https://github.com/lxc/distrobuilder/tree/main/windows

And I now realize, they skip the installer entirely.

We just create the filesystems and unpack install.wim directly into it, skipping the installer, at least the first step !

I did want a win10 iso that can cd/usb/net-boot and install windows to a baremetal/iscsi/VM but now I think for VMs it might be faster to skip portions of the installer if possible.


I also wish to incorporate
Microsoft-Windows-EMS-SAC-Desktop-Tools-FoD-Package~31bf3856ad364e35~amd64~~.cab

So that I can send terminal commands over serial to the running windows instance
 
Last edited:
Maybe sysprep later, but for now I want a one-click "original iso to fully automated, finished install" function.
Maybe I can automate this sysprep and then clone the WIMs.

Just gave a try to the $WinPeDriver$ method

Here is how that went

Code:
check_dependencies() { for cmd in 7zz xorriso wimlib-imagex dumpet isoinfo libwin-hivex-perl; do which "$cmd" >/dev/null 2>&1 || { echo "Installing missing package: $cmd"; apt-get install -qq -y 7zip xorriso wimtools libwim-doc libhivex-bin; }; done; }
create_windows_repack_folder() { [ -z "$1" ] && echo "Usage: create_windows_repack_folder /path/to/base/folder" && return 1; base="$1"; for folder in iso-master wim-mounts unattend-file virtio-unzipped; do mkdir -p "$base/$folder" || { echo "Failed to create $base/$folder"; return 1; }; done; echo "Folders created successfully in $base"; }
unpack_iso() { 7zz x "$1" -o"$2"; }
copy_virtio_drivers_to_winpedriver() { [ "$#" -lt 2 ] && { echo "Usage: copy_virtio_drivers_to_winpedriver <base_folder> <driver_name1> [driver_name2 ...]"; return 1; }; local base_folder="$1"; shift; local virtio_source="$base_folder/virtio-unzipped" dest_base="$base_folder/iso-master/\$WinPeDriver\$"; for driver in "$@"; do source_path="$virtio_source/$driver/w10/amd64"; dest_path="$dest_base/$driver/"; [ -d "$source_path" ] && { mkdir -p "$dest_path"; cp -r "$source_path"/* "$dest_path"; echo "Copied $source_path to $dest_path"; } || echo "Source path $source_path does not exist, skipping $driver"; done; }
create_windows_iso() { local src_folder="$1" out_iso="$2"; xorriso -as mkisofs -iso-level 3 -full-iso9660-filenames -volid "CCCOMA_X64FRE_EN-GB_DV9" -output "$out_iso" -eltorito-boot boot/etfsboot.com -eltorito-catalog boot/boot.cat -no-emul-boot -boot-load-size 8 -boot-info-table -eltorito-alt-boot -e efi/microsoft/boot/efisys.bin -no-emul-boot -boot-load-size 1 -isohybrid-gpt-basdat "$src_folder"; }
create_win10_vm() { local VM_ID="$1" VM_NAME="$2" VM_MEMORY="${3:-8000}" VM_CORES="${4:-8}" VM_DISK_SIZE="${5:-32}" VM_TEMPLATE_FILENAME="${6:-Win10_22H2_EnglishInternational_x64_unattended-latest.iso}" VM_VIRTIO_FILENAME="${7:-virtio-win-0.1.262.iso}" VM_OS_TYPE="win10" VM_AGENT="1" VM_SOCKETS="1" VM_STORAGE_DISK="local-lvm" VM_STORAGE_ISO="lvm-iso" VM_NETWORK_BRIDGE="vmbr0" VM_EFIDISK_SIZE="4M" VM_MAC_ADDRESS=$(printf '52:54:00:%02X:%02X:%02X' $((RANDOM%256)) $((RANDOM%256)) $((RANDOM%256))); local CMD="qm create \"$VM_ID\" --name \"$VM_NAME\" --memory \"$VM_MEMORY\" --sockets \"$VM_SOCKETS\" --cores \"$VM_CORES\" --numa 0 --bios ovmf --machine pc-q35-7.1 --efidisk0 \"$VM_STORAGE_DISK:0,size=$VM_EFIDISK_SIZE,efitype=4m,pre-enrolled-keys=1\" --scsi0 \"$VM_STORAGE_DISK:$VM_DISK_SIZE,backup=0,cache=writeback,discard=on,iothread=1\" --ide0 \"$VM_STORAGE_ISO:iso/$VM_VIRTIO_FILENAME,media=cdrom\" --ide2 \"$VM_STORAGE_ISO:iso/$VM_TEMPLATE_FILENAME,media=cdrom\" --net0 \"e1000=$VM_MAC_ADDRESS,bridge=$VM_NETWORK_BRIDGE\" --scsihw virtio-scsi-single --boot \"order=scsi0\" --bootdisk \"scsi0\" --agent \"enabled=$VM_AGENT\" --ostype \"$VM_OS_TYPE\""; [ -n "$VM_UUID" ] && CMD+=" --smbios1 uuid=$VM_UUID"; [ -n "$VM_VMGENID" ] && CMD+=" --vmgenid $VM_VMGENID"; echo "Executing: $CMD"; eval "$CMD"; }

check_dependencies
create_windows_repack_folder /mnt/iso/template/win10-repack
unpack_iso /mnt/iso/template/iso/Win10_22H2_EnglishInternational_x64.iso /mnt/iso/template/win10-repack/iso-master
unpack_iso /mnt/iso/template/iso/virtio-win-0.1.262.iso /mnt/iso/template/win10-repack/virtio-unzipped
copy_virtio_drivers_to_winpedriver /mnt/iso/template/win10-repack viofs vioserial viorng qxldod viogpudo NetKVM pvpanic vioinput fwcfg Balloon viostor sriov vioscsi qemupciserial viomem
create_windows_iso /mnt/iso/template/win10-repack/iso-master /mnt/iso/template/iso/Win10_22H2_EnglishInternational_x64_unattended-latest.iso
create_win10_vm 1770 wintest1


Problems with that are
1. boot order missing ide2 to boot
2. Still need to "press a key to enter setup"
3. drivers aren't loaded

1737847977841.png

Why aren't the drivers loading ?

It appears the "$" characters have been replaced with "_" characters

1737848037795.png

Looking at the actual folder structure in the folder iso-master

Code:
root@proxmox:/mnt/iso/template/win10-repack/iso-master# ls
'$WinPeDriver$'   autorun.inf   boot   bootmgr   bootmgr.efi   efi   setup.exe   sources   support
root@proxmox:/mnt/iso/template/win10-repack/iso-master# find "\$WinPeDriver\$"/
$WinPeDriver$/
$WinPeDriver$/viomem
$WinPeDriver$/viomem/viomem.pdb
$WinPeDriver$/viomem/viomem.sys
$WinPeDriver$/viomem/viomem.inf
$WinPeDriver$/viomem/viomem.cat
$WinPeDriver$/qemupciserial
$WinPeDriver$/qemupciserial/qemupciserial.cat
$WinPeDriver$/qemupciserial/qemupciserial.inf
$WinPeDriver$/vioscsi
$WinPeDriver$/vioscsi/vioscsi.sys
$WinPeDriver$/vioscsi/vioscsi.cat
....

Looks good here, but strangely, the iso is wrong ??

So I went and mounted the iso file

Code:
root@proxmox:/mnt/iso/template/iso# mount -o loop /mnt/iso/template/iso/Win10_22H2_EnglishInternational_x64_unattended-latest.iso /mnt/test
mount: /mnt/test: WARNING: source write-protected, mounted read-only.
root@proxmox:/mnt/iso/template/iso# cd /mnt/test
root@proxmox:/mnt/test# ls
'$WinPeDriver$'   autorun.inf   boot   bootmgr   bootmgr.efi   efi   setup.exe   sources   support
root@proxmox:/mnt/test# find "\$WinPeDriver\$"/
$WinPeDriver$/
$WinPeDriver$/Balloon
$WinPeDriver$/Balloon/balloon.cat
$WinPeDriver$/Balloon/balloon.inf
$WinPeDriver$/Balloon/balloon.pdb
$WinPeDriver$/Balloon/balloon.sys
$WinPeDriver$/Balloon/blnsvr.exe
$WinPeDriver$/Balloon/blnsvr.pdb
$WinPeDriver$/fwcfg
$WinPeDriver$/fwcfg/fwcfg.cat
$WinPeDriver$/fwcfg/fwcfg.inf
$WinPeDriver$/fwcfg/fwcfg.pdb
$WinPeDriver$/fwcfg/fwcfg.sys
$WinPeDriver$/NetKVM

Strangely the iso is also fine, I wonder why ...


1737848483255.png
 
put only minimal drivers in $WinpeDriver$
netkvm and vioscsi
Then install with FirstLogonCommands of Autounattend.xml :
qemu drivers (win-gt.msi) and qemu agent (qemu-ga.msi)

edit : seems missing option ( joliet or udf version) for iso creation to fix missing $
Microsoft cdimage.exe use :
-u2 : Produces an ISO image that has only the Universal Disk Format (UDF) file system on it.

-udfver102 : Writes UDF revision 1.02 (Supported: Windows 98 and later)
 
Last edited:

About

The Proxmox community has been around for many years and offers help and support for Proxmox VE, Proxmox Backup Server, and Proxmox Mail Gateway.
We think our community is one of the best thanks to people like you!

Get your subscription!

The Proxmox team works very hard to make sure you are running the best software and getting stable updates and security enhancements, as well as quick enterprise support. Tens of thousands of happy customers have a Proxmox subscription. Get yours easily in our online shop.

Buy now!