From 32b715e1a0ce85715dc685143a71d6571a48edf5 Mon Sep 17 00:00:00 2001 From: marco Date: Wed, 12 Nov 2025 14:35:22 +0100 Subject: [PATCH] Upload files to "/" --- Prep-VirtIODrivers.ps1 | 155 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 155 insertions(+) create mode 100644 Prep-VirtIODrivers.ps1 diff --git a/Prep-VirtIODrivers.ps1 b/Prep-VirtIODrivers.ps1 new file mode 100644 index 0000000..0fce130 --- /dev/null +++ b/Prep-VirtIODrivers.ps1 @@ -0,0 +1,155 @@ +<# +.SYNOPSIS +Pre-stage VirtIO drivers on a VMware Windows Server VM before migrating to Proxmox (KVM/QEMU). + +.DESCRIPTION +- Optionally downloads the latest virtio-win.iso, or uses a provided local ISO path. +- Mounts the ISO. +- Injects key drivers into the online Windows driver store using pnputil: + * Storage: vioscsi + viostor + * Network: NetKVM + * Memory Balloon: Balloon +- (Optional) Adds QEMU guest extras (commented). +- Verifies presence. +- Unmounts the ISO. + +.PARAMETER IsoPath +Path to an existing virtio-win.iso on disk. If omitted, use -Download to fetch it. + +.PARAMETER Download +Download the latest virtio-win.iso from Fedora mirrors. + +.EXAMPLE +.\Prep-VirtIODrivers.ps1 -Download + +.EXAMPLE +.\Prep-VirtIODrivers.ps1 -IsoPath "C:\Temp\virtio-win.iso" + +.NOTES +Run from an elevated PowerShell (Run as Administrator). +Tested on Windows Server 2025/2022/2019. Uses the 'w11\amd64' folder for 2025. +#> + +param( + [string]$IsoPath, + [switch]$Download +) + +# --- Require admin --- +$principal = New-Object Security.Principal.WindowsPrincipal([Security.Principal.WindowsIdentity]::GetCurrent()) +if (-not $principal.IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)) { + Write-Error "Please run this script as Administrator." + exit 1 +} + +$ErrorActionPreference = "Stop" + +# --- Determine working dir --- +$WorkDir = Join-Path $env:TEMP "virtio-prep" +New-Item -ItemType Directory -Force -Path $WorkDir | Out-Null + +# --- Ensure one of IsoPath or Download is set --- +if (-not $IsoPath -and -not $Download) { $Download = $true } + +# --- Download logic --- +if ($Download) { + try { + $IsoPath = Join-Path $WorkDir "virtio-win.iso" + Write-Host "Downloading latest virtio-win.iso..." -ForegroundColor Cyan + $primary = "https://fedorapeople.org/groups/virt/virtio-win/direct-downloads/latest-virtio/virtio-win.iso" + Invoke-WebRequest -Uri $primary -OutFile $IsoPath -UseBasicParsing -TimeoutSec 300 + } catch { + Write-Warning "Primary download failed, trying Fedora mirror..." + $fallback = "https://dl.fedoraproject.org/pub/alt/virtio-win/latest-virtio/virtio-win.iso" + Invoke-WebRequest -Uri $fallback -OutFile $IsoPath -UseBasicParsing -TimeoutSec 300 + } + Write-Host "Downloaded to $IsoPath" -ForegroundColor Green +} elseif (-not (Test-Path $IsoPath)) { + Write-Error "IsoPath not found: $IsoPath" + exit 1 +} + +# --- Mount ISO --- +Write-Host "Mounting ISO..." -ForegroundColor Cyan +$img = Mount-DiskImage -ImagePath $IsoPath -PassThru +$vol = $img | Get-Volume +$cd = ($vol | Select-Object -First 1).DriveLetter + ":" +Write-Host "Mounted at $cd" -ForegroundColor Green + +# --- Choose driver root folders +# Windows Server 2025 uses 'w11\amd64'. Provide a small fallback search if missing. +$CandidateSubDirs = @( + "w11\amd64", # Server 2025 + "2k22\amd64", # Server 2022 + "w10\amd64" # Broad fallback +) + +function Resolve-DriverPath { + param( + [string]$Base, + [string[]]$Candidates + ) + foreach ($c in $Candidates) { + $p = Join-Path $Base $c + if (Test-Path $p) { return $p } + } + return $null +} + +$Drivers = @() +$map = @{ + "vioscsi" = Join-Path $cd "vioscsi" + "viostor" = Join-Path $cd "viostor" + "NetKVM" = Join-Path $cd "NetKVM" + "Balloon" = Join-Path $cd "Balloon" +} + +foreach ($k in $map.Keys) { + $root = $map[$k] + $path = Resolve-DriverPath -Base $root -Candidates $CandidateSubDirs + if ($null -eq $path) { + Write-Warning "Could not find a suitable subfolder for $k under $root" + } else { + $Drivers += @{ Name=$k; Path=$path } + } +} + +# --- Install drivers using pnputil (online install into current OS) --- +Write-Host "`nInstalling VirtIO drivers..." -ForegroundColor Cyan +foreach ($d in $Drivers) { + $infGlob = Join-Path $d.Path "*.inf" + if (Test-Path $d.Path) { + Write-Host (" -> {0} from {1}" -f $d.Name, $d.Path) -ForegroundColor DarkCyan + pnputil /add-driver $infGlob /install | Out-Null + } else { + Write-Warning "Driver path missing: $($d.Path)" + } +} + +# --- Optional extras (uncomment to include) --- +# pnputil /add-driver "$cd\qxldod\w11\amd64\*.inf" /install | Out-Null # QXL Display +# pnputil /add-driver "$cd\vioserial\w11\amd64\*.inf" /install | Out-Null # VirtIO Serial +# pnputil /add-driver "$cd\pvpanic\w11\amd64\*.inf" /install | Out-Null # pvpanic + +# --- Verify presence in driver store --- +Write-Host "`nVerifying driver presence..." -ForegroundColor Cyan +$enum = (pnputil /enum-drivers) -join "`n" +foreach ($n in @("vioscsi","viostor","NetKVM","Balloon")) { + if ($enum -match [Regex]::Escape($n)) { + Write-Host (" [+] {0} present" -f $n) -ForegroundColor Green + } else { + Write-Warning (" [!] {0} NOT found in driver store" -f $n) + } +} + +# --- Unmount ISO --- +Write-Host "`nUnmounting ISO..." -ForegroundColor Cyan +Dismount-DiskImage -ImagePath $IsoPath + +Write-Host "`nAll done." -ForegroundColor Green +Write-Host @" +Next steps: +1) Shut down this VM cleanly and take your Veeam backup/export OR run your migration. +2) In Proxmox, attach the disks as VirtIO-SCSI and NIC as VirtIO (paravirtualized). +3) First boot should succeed; if needed, keep virtio-win.iso mounted to install guest tools. +"@