Compare commits

...

23 Commits

Author SHA1 Message Date
CodingWonders
edcf13d02d
Merge c977182771 into 28bea518f0 2024-12-29 07:47:31 +00:00
CodingWonders
c977182771 Fixed some more indentation 2024-12-29 08:47:26 +01:00
CodingWonders
d2db3bec53 Exclude OpenSSH from package removal
Some people need this to avoid installing third-party programs like PuTTY
2024-12-28 22:23:20 +01:00
CodingWonders
9dd508d069 Add DISM command fallback
This fallback is triggered if an exception occurs while getting information with the cmdlets (I couldn't test this on my host as everything magically works now - sometimes it threw the Class not registered error)
2024-12-27 09:48:55 +01:00
CodingWonders
bee4d04a17 Add VirtIO instructions to MicroWin page 2024-12-19 20:28:20 +01:00
CodingWonders
3de92566e2 Update message 2024-12-19 19:17:41 +01:00
CodingWonders
3f2d42fa3f Add detections for expedited app removal
They only affect 24H2 and newer. Earlier releases don't have these expedited apps
2024-12-19 19:17:31 +01:00
CodingWonders
31fc41588b Access specific property of ISO image object
Only show the ISO path. No one is interested in the storage type
2024-12-19 18:55:28 +01:00
CodingWonders
d23e6f92fd Fix typo (#3104) 2024-12-14 07:44:45 +01:00
CodingWonders
2466b903f6
Merge branch 'main' into microwin-2025-preparation 2024-12-14 07:44:07 +01:00
CodingWonders
2f8eaf4f18 Add VirtIO functionality and more enhancements
- Added the ability to grab VirtIO Guest Tools
- Modified the description of the Copy ISO files function because it basically had nonsense
2024-12-06 08:55:02 +01:00
CodingWonders
aa717838b2
Merge branch 'main' into microwin-2025-preparation 2024-12-06 06:58:24 +01:00
CodingWonders
40c7a1b8d5
Merge branch 'main' into microwin-2025-preparation 2024-12-02 21:47:49 +01:00
CodingWonders
3cfc7c92b4 Improve copy operation to Ventoy drives
This change may fix the issues where there's a conflict between both Ventoy's and MicroWin's unattended answer files, causing target images to stop working as expected during OOBE
2024-12-02 21:46:38 +01:00
CodingWonders
9979a02a30
Merge branch 'main' into microwin-2025-preparation 2024-12-01 19:15:49 +01:00
CodingWonders
759d8f6878 Exclude Windows Photo Viewer from dir removal 2024-12-01 18:03:32 +01:00
CodingWonders
2c4cf504fc Package exclusion improvements
- Removed AppX packages from OS package exclusion list
- Added exclusion of PowerShell ISE (source: Discord server - yes, some people still use the PowerShell ISE)
2024-12-01 18:02:52 +01:00
CodingWonders
cc7b3d7836 Remove jargon of scratch directory options 2024-12-01 18:01:38 +01:00
CodingWonders
8e647e8c49 Update comment
It reflects my feelings towards Microsoft when it comes to security a lot better
2024-11-24 18:16:55 +01:00
CodingWonders
c5968243eb Fix name of excluded package 2024-11-24 13:37:06 +01:00
CodingWonders
706f65f631 Obscure passwords with Base64 and fix indentation
Fixes #3064
2024-11-24 12:52:59 +01:00
CodingWonders
9dcf8dd50e Exclude Windows Hello stuff from package removal 2024-11-24 12:51:53 +01:00
CodingWonders
a45402e9d8 Set Boot Manager entry timeout to 0
Fixes #2562
2024-11-22 18:24:00 +01:00
11 changed files with 423 additions and 151 deletions

View File

@ -55,6 +55,8 @@ public class PowerManagement {
$injectDrivers = $sync.MicrowinInjectDrivers.IsChecked $injectDrivers = $sync.MicrowinInjectDrivers.IsChecked
$importDrivers = $sync.MicrowinImportDrivers.IsChecked $importDrivers = $sync.MicrowinImportDrivers.IsChecked
$importVirtIO = $sync.MicrowinCopyVirtIO.IsChecked
$mountDir = $sync.MicrowinMountDir.Text $mountDir = $sync.MicrowinMountDir.Text
$scratchDir = $sync.MicrowinScratchDir.Text $scratchDir = $sync.MicrowinScratchDir.Text
@ -109,7 +111,7 @@ public class PowerManagement {
Write-Host "Mounting Windows image. This may take a while." Write-Host "Mounting Windows image. This may take a while."
Mount-WindowsImage -ImagePath "$mountDir\sources\install.wim" -Index $index -Path "$scratchDir" Mount-WindowsImage -ImagePath "$mountDir\sources\install.wim" -Index $index -Path "$scratchDir"
if ($?) { if ($?) {
Write-Host "Mounting complete! Performing removal of applications..." Write-Host "The Windows image has been mounted successfully. Continuing processing..."
} else { } else {
Write-Host "Could not mount image. Exiting..." Write-Host "Could not mount image. Exiting..."
Set-WinUtilTaskbaritem -state "Error" -value 1 -overlay "warning" Set-WinUtilTaskbaritem -state "Error" -value 1 -overlay "warning"
@ -155,13 +157,18 @@ public class PowerManagement {
} }
} }
if ($importVirtIO) {
Write-Host "Copying VirtIO drivers..."
Microwin-CopyVirtIO
}
Write-Host "Remove Features from the image" Write-Host "Remove Features from the image"
Microwin-RemoveFeatures Microwin-RemoveFeatures -UseCmdlets $true
Write-Host "Removing features complete!" Write-Host "Removing features complete!"
Write-Host "Removing OS packages" Write-Host "Removing OS packages"
Microwin-RemovePackages Microwin-RemovePackages -UseCmdlets $true
Write-Host "Removing Appx Bloat" Write-Host "Removing Appx Bloat"
Microwin-RemoveProvisionedPackages Microwin-RemoveProvisionedPackages -UseCmdlets $true
# Detect Windows 11 24H2 and add dependency to FileExp to prevent Explorer look from going back - thanks @WitherOrNot and @thecatontheceiling # Detect Windows 11 24H2 and add dependency to FileExp to prevent Explorer look from going back - thanks @WitherOrNot and @thecatontheceiling
if ((Microwin-TestCompatibleImage $imgVersion $([System.Version]::new(10,0,26100,1))) -eq $true) { if ((Microwin-TestCompatibleImage $imgVersion $([System.Version]::new(10,0,26100,1))) -eq $true) {
@ -189,8 +196,6 @@ public class PowerManagement {
Microwin-RemoveFileOrDirectory -pathToDelete "$($scratchDir)\Windows\DiagTrack" -Directory Microwin-RemoveFileOrDirectory -pathToDelete "$($scratchDir)\Windows\DiagTrack" -Directory
Microwin-RemoveFileOrDirectory -pathToDelete "$($scratchDir)\Windows\InboxApps" -Directory Microwin-RemoveFileOrDirectory -pathToDelete "$($scratchDir)\Windows\InboxApps" -Directory
Microwin-RemoveFileOrDirectory -pathToDelete "$($scratchDir)\Windows\System32\LocationNotificationWindows.exe" Microwin-RemoveFileOrDirectory -pathToDelete "$($scratchDir)\Windows\System32\LocationNotificationWindows.exe"
Microwin-RemoveFileOrDirectory -pathToDelete "$($scratchDir)\Program Files (x86)\Windows Photo Viewer" -Directory
Microwin-RemoveFileOrDirectory -pathToDelete "$($scratchDir)\Program Files\Windows Photo Viewer" -Directory
Microwin-RemoveFileOrDirectory -pathToDelete "$($scratchDir)\Program Files (x86)\Windows Media Player" -Directory Microwin-RemoveFileOrDirectory -pathToDelete "$($scratchDir)\Program Files (x86)\Windows Media Player" -Directory
Microwin-RemoveFileOrDirectory -pathToDelete "$($scratchDir)\Program Files\Windows Media Player" -Directory Microwin-RemoveFileOrDirectory -pathToDelete "$($scratchDir)\Program Files\Windows Media Player" -Directory
Microwin-RemoveFileOrDirectory -pathToDelete "$($scratchDir)\Program Files (x86)\Windows Mail" -Directory Microwin-RemoveFileOrDirectory -pathToDelete "$($scratchDir)\Program Files (x86)\Windows Mail" -Directory
@ -280,20 +285,22 @@ public class PowerManagement {
reg add "HKLM\zSYSTEM\Setup\LabConfig" /v "BypassTPMCheck" /t REG_DWORD /d 1 /f reg add "HKLM\zSYSTEM\Setup\LabConfig" /v "BypassTPMCheck" /t REG_DWORD /d 1 /f
reg add "HKLM\zSYSTEM\Setup\MoSetup" /v "AllowUpgradesWithUnsupportedTPMOrCPU" /t REG_DWORD /d 1 /f reg add "HKLM\zSYSTEM\Setup\MoSetup" /v "AllowUpgradesWithUnsupportedTPMOrCPU" /t REG_DWORD /d 1 /f
# Prevent Windows Update Installing so called Expedited Apps # Prevent Windows Update Installing so called Expedited Apps - 24H2 and newer
@( if ((Microwin-TestCompatibleImage $imgVersion $([System.Version]::new(10,0,26100,1))) -eq $true) {
'EdgeUpdate', @(
'DevHomeUpdate', 'EdgeUpdate',
'OutlookUpdate', 'DevHomeUpdate',
'CrossDeviceUpdate' 'OutlookUpdate',
) | ForEach-Object { 'CrossDeviceUpdate'
Write-Host "Removing Windows Expedited App: $_" ) | ForEach-Object {
Write-Host "Removing Windows Expedited App: $_"
# Copied here After Installation (Online) # Copied here After Installation (Online)
# reg delete "HKLM\zSOFTWARE\Microsoft\Windows\CurrentVersion\WindowsUpdate\Orchestrator\UScheduler\$_" /f | Out-Null # reg delete "HKLM\zSOFTWARE\Microsoft\Windows\CurrentVersion\WindowsUpdate\Orchestrator\UScheduler\$_" /f | Out-Null
# When in Offline Image # When in Offline Image
reg delete "HKLM\zSOFTWARE\Microsoft\WindowsUpdate\Orchestrator\UScheduler_Oobe\$_" /f | Out-Null reg delete "HKLM\zSOFTWARE\Microsoft\WindowsUpdate\Orchestrator\UScheduler_Oobe\$_" /f | Out-Null
}
} }
reg add "HKLM\zSOFTWARE\Microsoft\Windows\CurrentVersion\Search" /v "SearchboxTaskbarMode" /t REG_DWORD /d 0 /f reg add "HKLM\zSOFTWARE\Microsoft\Windows\CurrentVersion\Search" /v "SearchboxTaskbarMode" /t REG_DWORD /d 0 /f

View File

@ -169,7 +169,7 @@ function Invoke-MicrowinGetIso {
try { try {
Write-Host "Mounting Iso. Please wait." Write-Host "Mounting Iso. Please wait."
$mountedISO = Mount-DiskImage -PassThru "$filePath" $mountedISO = Mount-DiskImage -PassThru "$filePath"
Write-Host "Done mounting Iso $mountedISO" Write-Host "Done mounting Iso `"$($mountedISO.ImagePath)`""
$driveLetter = (Get-Volume -DiskImage $mountedISO).DriveLetter $driveLetter = (Get-Volume -DiskImage $mountedISO).DriveLetter
Write-Host "Iso mounted to '$driveLetter'" Write-Host "Iso mounted to '$driveLetter'"
} catch { } catch {
@ -189,7 +189,7 @@ function Invoke-MicrowinGetIso {
$sync.MicrowinScratchDirBox.Text ="" $sync.MicrowinScratchDirBox.Text =""
} }
$UseISOScratchDir = $sync.WPFMicrowinISOScratchDir.IsChecked $UseISOScratchDir = $sync.WPFMicrowinISOScratchDir.IsChecked
if ($UseISOScratchDir) { if ($UseISOScratchDir) {
$sync.MicrowinScratchDirBox.Text=$mountedISOPath $sync.MicrowinScratchDirBox.Text=$mountedISOPath
@ -220,10 +220,10 @@ function Invoke-MicrowinGetIso {
$sync.BusyText.Text=" - Mounting" $sync.BusyText.Text=" - Mounting"
Write-Host "Mounting Iso. Please wait." Write-Host "Mounting Iso. Please wait."
if ($sync.MicrowinScratchDirBox.Text -eq "") { if ($sync.MicrowinScratchDirBox.Text -eq "") {
$mountDir = Join-Path $env:TEMP $randomMicrowin $mountDir = Join-Path $env:TEMP $randomMicrowin
$scratchDir = Join-Path $env:TEMP $randomMicrowinScratch $scratchDir = Join-Path $env:TEMP $randomMicrowinScratch
} else { } else {
$scratchDir = $sync.MicrowinScratchDirBox.Text+"Scrach" $scratchDir = $sync.MicrowinScratchDirBox.Text+"Scratch"
$mountDir = $sync.MicrowinScratchDirBox.Text+"micro" $mountDir = $sync.MicrowinScratchDirBox.Text+"micro"
} }
@ -242,8 +242,8 @@ function Invoke-MicrowinGetIso {
# xcopy we can verify files and also not copy files that already exist, but hard to measure # xcopy we can verify files and also not copy files that already exist, but hard to measure
# xcopy.exe /E /I /H /R /Y /J $DriveLetter":" $mountDir >$null # xcopy.exe /E /I /H /R /Y /J $DriveLetter":" $mountDir >$null
$totalTime = Measure-Command { Copy-Files "$($driveLetter):" $mountDir -Recurse -Force } $totalTime = Measure-Command { Copy-Files "$($driveLetter):" "$mountDir" -Recurse -Force }
Write-Host "Copy complete! Total Time: $($totalTime.Minutes)m$($totalTime.Seconds)s" Write-Host "Copy complete! Total Time: $($totalTime.Minutes) minutes, $($totalTime.Seconds) seconds"
$wimFile = "$mountDir\sources\install.wim" $wimFile = "$mountDir\sources\install.wim"
Write-Host "Getting image information $wimFile" Write-Host "Getting image information $wimFile"

View File

@ -16,6 +16,54 @@ function Microwin-CopyToUSB([string]$fileToCopy) {
} }
Write-Host "File copied to Ventoy drive $($volume.DriveLetter)" Write-Host "File copied to Ventoy drive $($volume.DriveLetter)"
# Detect if config files are present, move them if they are, and configure the Ventoy drive to not bypass the requirements
$customVentoyConfig = @'
{
"control":[
{ "VTOY_WIN11_BYPASS_CHECK": "0" },
{ "VTOY_WIN11_BYPASS_NRO": "0" }
],
"control_legacy":[
{ "VTOY_WIN11_BYPASS_CHECK": "0" },
{ "VTOY_WIN11_BYPASS_NRO": "0" }
],
"control_uefi":[
{ "VTOY_WIN11_BYPASS_CHECK": "0" },
{ "VTOY_WIN11_BYPASS_NRO": "0" }
],
"control_ia32":[
{ "VTOY_WIN11_BYPASS_CHECK": "0" },
{ "VTOY_WIN11_BYPASS_NRO": "0" }
],
"control_aa64":[
{ "VTOY_WIN11_BYPASS_CHECK": "0" },
{ "VTOY_WIN11_BYPASS_NRO": "0" }
],
"control_mips":[
{ "VTOY_WIN11_BYPASS_CHECK": "0" },
{ "VTOY_WIN11_BYPASS_NRO": "0" }
]
}
'@
try {
Write-Host "Writing custom Ventoy configuration. Please wait..."
if (Test-Path -Path "$($volume.DriveLetter):\ventoy\ventoy.json" -PathType Leaf) {
Write-Host "A Ventoy configuration file exists. Moving it..."
Move-Item -Path "$($volume.DriveLetter):\ventoy\ventoy.json" -Destination "$($volume.DriveLetter):\ventoy\ventoy.json.old" -Force
Write-Host "Existing Ventoy configuration has been moved to `"ventoy.json.old`". Feel free to put your config back into the `"ventoy.json`" file."
}
if (-not (Test-Path -Path "$($volume.DriveLetter):\ventoy")) {
New-Item -Path "$($volume.DriveLetter):\ventoy" -ItemType Directory -Force | Out-Null
}
$customVentoyConfig | Out-File -FilePath "$($volume.DriveLetter):\ventoy\ventoy.json" -Encoding utf8 -Force
Write-Host "The Ventoy drive has been successfully configured."
} catch {
Write-Host "Could not configure Ventoy drive. Error: $($_.Exception.Message)`n"
Write-Host "Be sure to add the following configuration to the Ventoy drive by either creating a `"ventoy.json`" file in the `"ventoy`" directory (create it if it doesn't exist) or by editing an existing one: `n`n$customVentoyConfig`n"
Write-Host "Failure to do this will cause conflicts with your target ISO file."
}
return return
} }
} }

View File

@ -0,0 +1,40 @@
function Microwin-CopyVirtIO {
<#
.SYNOPSIS
Downloads and copies the VirtIO Guest Tools drivers to the target MicroWin ISO
.NOTES
A network connection must be available and the servers of Fedora People must be up. Automatic driver installation will not be added yet - I want this implementation to be reliable.
#>
try {
Write-Host "Checking existing files..."
if (Test-Path -Path "$($env:TEMP)\virtio.iso" -PathType Leaf) {
Write-Host "VirtIO ISO has been detected. Deleting..."
Remove-Item -Path "$($env:TEMP)\virtio.iso" -Force
}
Write-Host "Getting latest VirtIO drivers. Please wait. This can take some time, depending on your network connection speed and the speed of the servers..."
Start-BitsTransfer -Source "https://fedorapeople.org/groups/virt/virtio-win/direct-downloads/stable-virtio/virtio-win.iso" -Destination "$($env:TEMP)\virtio.iso" -DisplayName "Downloading VirtIO drivers..."
# Do everything else if the VirtIO ISO exists
if (Test-Path -Path "$($env:TEMP)\virtio.iso" -PathType Leaf) {
Write-Host "Mounting ISO. Please wait."
$virtIO_ISO = Mount-DiskImage -PassThru "$($env:TEMP)\virtio.iso"
$driveLetter = (Get-Volume -DiskImage $virtIO_ISO).DriveLetter
# Create new directory for VirtIO on ISO
New-Item -Path "$mountDir\VirtIO" -ItemType Directory | Out-Null
$totalTime = Measure-Command { Copy-Files "$($driveLetter):" "$mountDir\VirtIO" -Recurse -Force }
Write-Host "VirtIO contents have been successfully copied. Time taken: $($totalTime.Minutes) minutes, $($totalTime.Seconds) seconds`n"
Get-Volume $driveLetter | Get-DiskImage | Dismount-DiskImage
Remove-Item -Path "$($env:TEMP)\virtio.iso" -Force -ErrorAction SilentlyContinue
Write-Host "To proceed with installation of the MicroWin image in QEMU/Proxmox VE:"
Write-Host "1. Proceed with Setup until you reach the disk selection screen, in which you won't see any drives"
Write-Host "2. Click `"Load Driver`" and click Browse"
Write-Host "3. In the folder selection dialog, point to this path:`n`n `"D:\VirtIO\vioscsi\w11\amd64`" (replace amd64 with ARM64 if you are using Windows on ARM, and `"D:`" with the drive letter of the ISO)`n"
Write-Host "4. Select all drivers that will appear in the list box and click OK"
} else {
throw "Could not download VirtIO drivers"
}
} catch {
Write-Host "We could not download and/or prepare the VirtIO drivers. Error information: $_`n"
Write-Host "You will need to download these drivers manually. Location: https://fedorapeople.org/groups/virt/virtio-win/direct-downloads/stable-virtio/virtio-win.iso"
}
}

View File

@ -63,6 +63,22 @@ function Microwin-NewFirstRun {
{ {
} }
# Get BCD entries and set bootmgr timeout accordingly
try
{
# Check if the number of occurrences of "path" is 2 - this fixes the Boot Manager screen issue (#2562)
if ((bcdedit | Select-String "path").Count -eq 2)
{
# Set bootmgr timeout to 0
bcdedit /set `{bootmgr`} timeout 0
}
}
catch
{
}
'@ '@
$firstRun | Out-File -FilePath "$env:temp\FirstStartup.ps1" -Force $firstRun | Out-File -FilePath "$env:temp\FirstStartup.ps1" -Force
} }

View File

@ -31,7 +31,7 @@ function Microwin-NewUnattend {
<Group>Administrators</Group> <Group>Administrators</Group>
<Password> <Password>
<Value>PW-REPLACEME</Value> <Value>PW-REPLACEME</Value>
<PlainText>true</PlainText> <PlainText>PT-STATUS</PlainText>
</Password> </Password>
</LocalAccount> </LocalAccount>
</LocalAccounts> </LocalAccounts>
@ -42,7 +42,7 @@ function Microwin-NewUnattend {
<LogonCount>1</LogonCount> <LogonCount>1</LogonCount>
<Password> <Password>
<Value>PW-REPLACEME</Value> <Value>PW-REPLACEME</Value>
<PlainText>true</PlainText> <PlainText>PT-STATUS</PlainText>
</Password> </Password>
</AutoLogon> </AutoLogon>
<OOBE> <OOBE>
@ -295,15 +295,40 @@ function Microwin-NewUnattend {
</settings> </settings>
'@ '@
if ((Microwin-TestCompatibleImage $imgVersion $([System.Version]::new(10,0,22000,1))) -eq $false) { if ((Microwin-TestCompatibleImage $imgVersion $([System.Version]::new(10,0,22000,1))) -eq $false) {
# Replace the placeholder text with an empty string to make it valid for Windows 10 Setup # Replace the placeholder text with an empty string to make it valid for Windows 10 Setup
$unattend = $unattend.Replace("<#REPLACEME#>", "").Trim() $unattend = $unattend.Replace("<#REPLACEME#>", "").Trim()
} else { } else {
# Replace the placeholder text with the Specialize pass # Replace the placeholder text with the Specialize pass
$unattend = $unattend.Replace("<#REPLACEME#>", $specPass).Trim() $unattend = $unattend.Replace("<#REPLACEME#>", $specPass).Trim()
} }
# User password in Base64. According to Microsoft, this is the way you can hide this sensitive information.
# More information can be found here: https://learn.microsoft.com/en-us/windows-hardware/customize/desktop/wsim/hide-sensitive-data-in-an-answer-file
# Yeah, I know this is not the best way to protect this kind of data, but we all know how Microsoft is - "the Apple of security" (in a sense, it takes them
# an eternity to implement basic security features right. Just look at the NTLM and Kerberos situation!)
$b64pass = ""
# Replace default User and Password values with the provided parameters # Replace default User and Password values with the provided parameters
$unattend = $unattend.Replace("USER-REPLACEME", $userName).Trim() $unattend = $unattend.Replace("USER-REPLACEME", $userName).Trim()
$unattend = $unattend.Replace("PW-REPLACEME", $userPassword).Trim() try {
# I want to play it safe here - I don't want encoding mismatch problems like last time
# NOTE: "Password" needs to be appended to the password specified by the user. Otherwise, a parse error will occur when processing oobeSystem.
# This will not be added to the actual password stored in the target system's SAM file - only the provided password
$b64pass = [Convert]::ToBase64String([System.Text.Encoding]::Unicode.GetBytes("$($userPassword)Password"))
} catch {
$b64pass = ""
}
if ($b64pass -ne "") {
# If we could encode the password with Base64, put it in the answer file and indicate that it's NOT in plain text
$unattend = $unattend.Replace("PW-REPLACEME", $b64pass).Trim()
$unattend = $unattend.Replace("PT-STATUS", "false").Trim()
$b64pass = ""
} else {
$unattend = $unattend.Replace("PW-REPLACEME", $userPassword).Trim()
$unattend = $unattend.Replace("PT-STATUS", "true").Trim()
}
# Save unattended answer file with UTF-8 encoding # Save unattended answer file with UTF-8 encoding
$unattend | Out-File -FilePath "$env:temp\unattend.xml" -Force -Encoding utf8 $unattend | Out-File -FilePath "$env:temp\unattend.xml" -Force -Encoding utf8

View File

@ -3,38 +3,80 @@ function Microwin-RemoveFeatures() {
.SYNOPSIS .SYNOPSIS
Removes certain features from ISO image Removes certain features from ISO image
.PARAMETER Name .PARAMETER UseCmdlets
No Params Determines whether or not to use the DISM cmdlets for processing.
- If true, DISM cmdlets will be used
- If false, calls to the DISM executable will be made whilst selecting bits and pieces from the output as a string (that was how MicroWin worked before
the DISM conversion to cmdlets)
.EXAMPLE .EXAMPLE
Microwin-RemoveFeatures Microwin-RemoveFeatures -UseCmdlets $true
#> #>
param (
[Parameter(Mandatory = $true, Position = 0)] [bool]$UseCmdlets
)
try { try {
$featlist = (Get-WindowsOptionalFeature -Path $scratchDir) if ($UseCmdlets) {
$featlist = (Get-WindowsOptionalFeature -Path "$scratchDir")
$featlist = $featlist | Where-Object { $featlist = $featlist | Where-Object {
$_.FeatureName -NotLike "*Defender*" -AND $_.FeatureName -NotLike "*Defender*" -AND
$_.FeatureName -NotLike "*Printing*" -AND $_.FeatureName -NotLike "*Printing*" -AND
$_.FeatureName -NotLike "*TelnetClient*" -AND $_.FeatureName -NotLike "*TelnetClient*" -AND
$_.FeatureName -NotLike "*PowerShell*" -AND $_.FeatureName -NotLike "*PowerShell*" -AND
$_.FeatureName -NotLike "*NetFx*" -AND $_.FeatureName -NotLike "*NetFx*" -AND
$_.FeatureName -NotLike "*Media*" -AND $_.FeatureName -NotLike "*Media*" -AND
$_.FeatureName -NotLike "*NFS*" -AND $_.FeatureName -NotLike "*NFS*" -AND
$_.FeatureName -NotLike "*SearchEngine*" -AND $_.FeatureName -NotLike "*SearchEngine*" -AND
$_.FeatureName -NotLike "*RemoteDesktop*" -AND $_.FeatureName -NotLike "*RemoteDesktop*" -AND
$_.State -ne "Disabled" $_.State -ne "Disabled"
}
} else {
$featList = dism /english /image="$scratchDir" /get-features | Select-String -Pattern "Feature Name : " -CaseSensitive -SimpleMatch
if ($?) {
$featList = $featList -split "Feature Name : " | Where-Object {$_}
# Exclude the same items. Note: for now, this doesn't exclude those features that are disabled.
# This will appear in the future
$featList = $featList | Where-Object {
$_ -NotLike "*Defender*" -AND
$_ -NotLike "*Printing*" -AND
$_ -NotLike "*TelnetClient*" -AND
$_ -NotLike "*PowerShell*" -AND
$_ -NotLike "*NetFx*" -AND
$_ -NotLike "*Media*" -AND
$_ -NotLike "*NFS*" -AND
$_ -NotLike "*SearchEngine*" -AND
$_ -NotLike "*RemoteDesktop*"
}
} else {
Write-Host "Features could not be obtained with DISM. MicroWin processing will continue, but features will be skipped."
return
}
} }
foreach($feature in $featlist) { if ($UseCmdlets) {
$status = "Removing feature $($feature.FeatureName)" foreach ($feature in $featList) {
Write-Progress -Activity "Removing features" -Status $status -PercentComplete ($counter++/$featlist.Count*100) $status = "Removing feature $($feature.FeatureName)"
Write-Debug "Removing feature $($feature.FeatureName)" Write-Progress -Activity "Removing features" -Status $status -PercentComplete ($counter++/$featlist.Count*100)
Disable-WindowsOptionalFeature -Path "$scratchDir" -FeatureName $($feature.FeatureName) -Remove -ErrorAction SilentlyContinue -NoRestart Write-Debug "Removing feature $($feature.FeatureName)"
Disable-WindowsOptionalFeature -Path "$scratchDir" -FeatureName $($feature.FeatureName) -Remove -ErrorAction SilentlyContinue -NoRestart
}
} else {
foreach ($feature in $featList) {
$status = "Removing feature $feature"
Write-Progress -Activity "Removing features" -Status $status -PercentComplete ($counter++/$featlist.Count*100)
Write-Debug "Removing feature $feature"
dism /english /image="$scratchDir" /disable-feature /featurename=$feature /remove /quiet /norestart | Out-Null
if ($? -eq $false) {
Write-Host "Feature $feature could not be disabled."
}
}
} }
Write-Progress -Activity "Removing features" -Status "Ready" -Completed Write-Progress -Activity "Removing features" -Status "Ready" -Completed
Write-Host "You can re-enable the disabled features at any time, using either Windows Update or the SxS folder in <installation media>\Sources." Write-Host "You can re-enable the disabled features at any time, using either Windows Update or the SxS folder in <installation media>\Sources."
} catch { } catch {
Write-Host "Unable to get information about the features. MicroWin processing will continue, but features will not be processed" Write-Host "Unable to get information about the features. A fallback will be used..."
Write-Host "Error information: $($_.Exception.Message)" -ForegroundColor Yellow Write-Host "Error information: $($_.Exception.Message)" -ForegroundColor Yellow
Microwin-RemoveFeatures -UseCmdlets $false
} }
} }

View File

@ -1,71 +1,103 @@
function Microwin-RemovePackages { function Microwin-RemovePackages {
<#
.SYNOPSIS
Removes certain packages from ISO image
.PARAMETER UseCmdlets
Determines whether or not to use the DISM cmdlets for processing.
- If true, DISM cmdlets will be used
- If false, calls to the DISM executable will be made whilst selecting bits and pieces from the output as a string (that was how MicroWin worked before
the DISM conversion to cmdlets)
.EXAMPLE
Microwin-RemovePackages -UseCmdlets $true
#>
param (
[Parameter(Mandatory = $true, Position = 0)] [bool]$UseCmdlets
)
try { try {
$pkglist = (Get-WindowsPackage -Path "$scratchDir").PackageName if ($useCmdlets) {
$pkglist = (Get-WindowsPackage -Path "$scratchDir").PackageName
$pkglist = $pkglist | Where-Object { $pkglist = $pkglist | Where-Object {
$_ -NotLike "*ApplicationModel*" -AND $_ -NotLike "*ApplicationModel*" -AND
$_ -NotLike "*indows-Client-LanguagePack*" -AND $_ -NotLike "*indows-Client-LanguagePack*" -AND
$_ -NotLike "*LanguageFeatures-Basic*" -AND $_ -NotLike "*LanguageFeatures-Basic*" -AND
$_ -NotLike "*Package_for_ServicingStack*" -AND $_ -NotLike "*Package_for_ServicingStack*" -AND
$_ -NotLike "*.NET*" -AND $_ -NotLike "*DotNet*" -AND
$_ -NotLike "*Store*" -AND $_ -NotLike "*Notepad*" -AND
$_ -NotLike "*VCLibs*" -AND $_ -NotLike "*WMIC*" -AND
$_ -NotLike "*AAD.BrokerPlugin", $_ -NotLike "*Ethernet*" -AND
$_ -NotLike "*LockApp*" -AND $_ -NotLike "*Wifi*" -AND
$_ -NotLike "*Notepad*" -AND $_ -NotLike "*FodMetadata*" -AND
$_ -NotLike "*immersivecontrolpanel*" -AND $_ -NotLike "*Foundation*" -AND
$_ -NotLike "*ContentDeliveryManager*" -AND $_ -NotLike "*LanguageFeatures*" -AND
$_ -NotLike "*PinningConfirMationDialog*" -AND $_ -NotLike "*VBSCRIPT*" -AND
$_ -NotLike "*SecHealthUI*" -AND $_ -NotLike "*License*" -AND
$_ -NotLike "*SecureAssessmentBrowser*" -AND $_ -NotLike "*Hello-Face*" -AND
$_ -NotLike "*PrintDialog*" -AND $_ -NotLike "*ISE*" -AND
$_ -NotLike "*AssignedAccessLockApp*" -AND $_ -NotLike "*OpenSSH*"
$_ -NotLike "*OOBENetworkConnectionFlow*" -AND }
$_ -NotLike "*Apprep.ChxApp*" -AND } else {
$_ -NotLike "*CBS*" -AND $pkgList = dism /english /image="$scratchDir" /get-packages | Select-String -Pattern "Package Identity : " -CaseSensitive -SimpleMatch
$_ -NotLike "*OOBENetworkCaptivePortal*" -AND if ($?) {
$_ -NotLike "*PeopleExperienceHost*" -AND $pkgList = $pkgList -split "Package Identity : " | Where-Object {$_}
$_ -NotLike "*ParentalControls*" -AND # Exclude the same items.
$_ -NotLike "*Win32WebViewHost*" -AND $pkgList = $pkgList | Where-Object {
$_ -NotLike "*InputApp*" -AND $_ -NotLike "*ApplicationModel*" -AND
$_ -NotLike "*DirectPlay*" -AND $_ -NotLike "*indows-Client-LanguagePack*" -AND
$_ -NotLike "*AccountsControl*" -AND $_ -NotLike "*LanguageFeatures-Basic*" -AND
$_ -NotLike "*AsyncTextService*" -AND $_ -NotLike "*Package_for_ServicingStack*" -AND
$_ -NotLike "*CapturePicker*" -AND $_ -NotLike "*DotNet*" -AND
$_ -NotLike "*CredDialogHost*" -AND $_ -NotLike "*Notepad*" -AND
$_ -NotLike "*BioEnrollMent*" -AND $_ -NotLike "*WMIC*" -AND
$_ -NotLike "*ShellExperienceHost*" -AND $_ -NotLike "*Ethernet*" -AND
$_ -NotLike "*DesktopAppInstaller*" -AND $_ -NotLike "*Wifi*" -AND
$_ -NotLike "*WebMediaExtensions*" -AND $_ -NotLike "*FodMetadata*" -AND
$_ -NotLike "*WMIC*" -AND $_ -NotLike "*Foundation*" -AND
$_ -NotLike "*UI.XaML*" -AND $_ -NotLike "*LanguageFeatures*" -AND
$_ -NotLike "*Ethernet*" -AND $_ -NotLike "*VBSCRIPT*" -AND
$_ -NotLike "*Wifi*" -AND $_ -NotLike "*License*" -AND
$_ -NotLike "*FodMetadata*" -AND $_ -NotLike "*Hello-Face*" -AND
$_ -NotLike "*Foundation*" -AND $_ -NotLike "*ISE*" -AND
$_ -NotLike "*LanguageFeatures*" -AND $_ -NotLike "*OpenSSH*"
$_ -NotLike "*VBSCRIPT*" -AND }
$_ -NotLike "*License*" } else {
Write-Host "Packages could not be obtained with DISM. MicroWin processing will continue, but packages will be skipped."
return
} }
}
$failedCount = 0 if ($UseCmdlets) {
$failedCount = 0
$erroredPackages = [System.Collections.Generic.List[ErroredPackage]]::new() $erroredPackages = [System.Collections.Generic.List[ErroredPackage]]::new()
foreach ($pkg in $pkglist) { foreach ($pkg in $pkglist) {
try { try {
$status = "Removing $pkg" $status = "Removing $pkg"
Write-Progress -Activity "Removing Packages" -Status $status -PercentComplete ($counter++/$pkglist.Count*100) Write-Progress -Activity "Removing Packages" -Status $status -PercentComplete ($counter++/$pkglist.Count*100)
Remove-WindowsPackage -Path "$scratchDir" -PackageName $pkg -NoRestart -ErrorAction SilentlyContinue Remove-WindowsPackage -Path "$scratchDir" -PackageName $pkg -NoRestart -ErrorAction SilentlyContinue
} catch { } catch {
# This can happen if the package that is being removed is a permanent one # This can happen if the package that is being removed is a permanent one
$erroredPackages.Add([ErroredPackage]::new($pkg, $_.Exception.Message)) $erroredPackages.Add([ErroredPackage]::new($pkg, $_.Exception.Message))
$failedCount += 1 $failedCount += 1
continue continue
}
}
} else {
foreach ($package in $pkgList) {
$status = "Removing package $package"
Write-Progress -Activity "Removing features" -Status $status -PercentComplete ($counter++/$featlist.Count*100)
Write-Debug "Removing package $package"
dism /english /image="$scratchDir" /remove-package /packagename=$package /remove /quiet /norestart | Out-Null
if ($? -eq $false) {
Write-Host "Package $package could not be removed."
}
} }
} }
Write-Progress -Activity "Removing Packages" -Status "Ready" -Completed Write-Progress -Activity "Removing Packages" -Status "Ready" -Completed
if ($failedCount -gt 0) if ($UseCmdlets -and $failedCount -gt 0)
{ {
Write-Host "$failedCount package(s) could not be removed. Your image will still work fine, however. Below is information on what packages failed to be removed and why." Write-Host "$failedCount package(s) could not be removed. Your image will still work fine, however. Below is information on what packages failed to be removed and why."
if ($erroredPackages.Count -gt 0) if ($erroredPackages.Count -gt 0)
@ -90,7 +122,8 @@ function Microwin-RemovePackages {
} }
} }
} catch { } catch {
Write-Host "Unable to get information about the packages. MicroWin processing will continue, but packages will not be processed" Write-Host "Unable to get information about the packages. A fallback will be used..."
Write-Host "Error information: $($_.Exception.Message)" -ForegroundColor Yellow Write-Host "Error information: $($_.Exception.Message)" -ForegroundColor Yellow
Microwin-RemovePackages -UseCmdlets $false
} }
} }

View File

@ -3,49 +3,94 @@ function Microwin-RemoveProvisionedPackages() {
.SYNOPSIS .SYNOPSIS
Removes AppX packages from a Windows image during MicroWin processing Removes AppX packages from a Windows image during MicroWin processing
.PARAMETER Name .PARAMETER UseCmdlets
No Params Determines whether or not to use the DISM cmdlets for processing.
- If true, DISM cmdlets will be used
- If false, calls to the DISM executable will be made whilst selecting bits and pieces from the output as a string (that was how MicroWin worked before
the DISM conversion to cmdlets)
.EXAMPLE .EXAMPLE
Microwin-RemoveProvisionedPackages Microwin-RemoveProvisionedPackages
#> #>
param (
[Parameter(Mandatory = $true, Position = 0)] [bool]$UseCmdlets
)
try try
{ {
$appxProvisionedPackages = Get-AppxProvisionedPackage -Path "$($scratchDir)" | Where-Object { if ($UseCmdlets) {
$_.PackageName -NotLike "*AppInstaller*" -AND $appxProvisionedPackages = Get-AppxProvisionedPackage -Path "$($scratchDir)" | Where-Object {
$_.PackageName -NotLike "*Store*" -and $_.PackageName -NotLike "*AppInstaller*" -AND
$_.PackageName -NotLike "*Notepad*" -and $_.PackageName -NotLike "*Store*" -and
$_.PackageName -NotLike "*Printing*" -and $_.PackageName -NotLike "*Notepad*" -and
$_.PackageName -NotLike "*YourPhone*" -and $_.PackageName -NotLike "*Printing*" -and
$_.PackageName -NotLike "*Xbox*" -and $_.PackageName -NotLike "*YourPhone*" -and
$_.PackageName -NotLike "*WindowsTerminal*" -and $_.PackageName -NotLike "*Xbox*" -and
$_.PackageName -NotLike "*Calculator*" -and $_.PackageName -NotLike "*WindowsTerminal*" -and
$_.PackageName -NotLike "*Photos*" -and $_.PackageName -NotLike "*Calculator*" -and
$_.PackageName -NotLike "*VCLibs*" -and $_.PackageName -NotLike "*Photos*" -and
$_.PackageName -NotLike "*Paint*" -and $_.PackageName -NotLike "*VCLibs*" -and
$_.PackageName -NotLike "*Gaming*" -and $_.PackageName -NotLike "*Paint*" -and
$_.PackageName -NotLike "*Extension*" -and $_.PackageName -NotLike "*Gaming*" -and
$_.PackageName -NotLike "*SecHealthUI*" -and $_.PackageName -NotLike "*Extension*" -and
$_.PackageName -NotLike "*ScreenSketch*" $_.PackageName -NotLike "*SecHealthUI*" -and
$_.PackageName -NotLike "*ScreenSketch*"
}
} else {
$appxProvisionedPackages = dism /english /image="$scratchDir" /get-provisionedappxpackages | Select-String -Pattern "PackageName : " -CaseSensitive -SimpleMatch
if ($?) {
$appxProvisionedPackages = $appxProvisionedPackages -split "PackageName : " | Where-Object {$_}
# Exclude the same items.
$appxProvisionedPackages = $appxProvisionedPackages | Where-Object {
$_ -NotLike "*AppInstaller*" -AND
$_ -NotLike "*Store*" -and
$_ -NotLike "*Notepad*" -and
$_ -NotLike "*Printing*" -and
$_ -NotLike "*YourPhone*" -and
$_ -NotLike "*Xbox*" -and
$_ -NotLike "*WindowsTerminal*" -and
$_ -NotLike "*Calculator*" -and
$_ -NotLike "*Photos*" -and
$_ -NotLike "*VCLibs*" -and
$_ -NotLike "*Paint*" -and
$_ -NotLike "*Gaming*" -and
$_ -NotLike "*Extension*" -and
$_ -NotLike "*SecHealthUI*" -and
$_ -NotLike "*ScreenSketch*"
}
} else {
Write-Host "AppX packages could not be obtained with DISM. MicroWin processing will continue, but AppX packages will be skipped."
return
}
} }
$counter = 0 $counter = 0
foreach ($appx in $appxProvisionedPackages) { if ($UseCmdlets) {
$status = "Removing Provisioned $($appx.PackageName)" foreach ($appx in $appxProvisionedPackages) {
Write-Progress -Activity "Removing Provisioned Apps" -Status $status -PercentComplete ($counter++/$appxProvisionedPackages.Count*100) $status = "Removing Provisioned $($appx.PackageName)"
try { Write-Progress -Activity "Removing Provisioned Apps" -Status $status -PercentComplete ($counter++/$appxProvisionedPackages.Count*100)
Remove-AppxProvisionedPackage -Path "$scratchDir" -PackageName $appx.PackageName -ErrorAction SilentlyContinue try {
} catch { Remove-AppxProvisionedPackage -Path "$scratchDir" -PackageName $appx.PackageName -ErrorAction SilentlyContinue
Write-Host "Application $($appx.PackageName) could not be removed" } catch {
continue Write-Host "Application $($appx.PackageName) could not be removed"
continue
}
}
} else {
foreach ($appx in $appxProvisionedPackages) {
$status = "Removing Provisioned $appx"
Write-Progress -Activity "Removing Provisioned Apps" -Status $status -PercentComplete ($counter++/$appxProvisionedPackages.Count*100)
dism /english /image="$scratchDir" /remove-provisionedappxpackage /packagename=$appx /quiet /norestart | Out-Null
if ($? -eq $false) {
Write-Host "AppX package $appx could not be removed."
}
} }
} }
Write-Progress -Activity "Removing Provisioned Apps" -Status "Ready" -Completed Write-Progress -Activity "Removing Provisioned Apps" -Status "Ready" -Completed
} }
catch catch
{ {
# This can happen if getting AppX packages fails Write-Host "Unable to get information about the AppX packages. A fallback will be used..."
Write-Host "Unable to get information about the AppX packages. MicroWin processing will continue, but AppX packages will not be processed"
Write-Host "Error information: $($_.Exception.Message)" -ForegroundColor Yellow Write-Host "Error information: $($_.Exception.Message)" -ForegroundColor Yellow
Microwin-RemoveProvisionedPackages -UseCmdlets $false
} }
} }

View File

@ -2,11 +2,17 @@ function Copy-Files {
<# <#
.DESCRIPTION .DESCRIPTION
This function will make all modifications to the registry Copies the contents of a given ISO file to a given destination
.PARAMETER Path
The source of the files to copy
.PARAMETER Destination
The destination to copy the files to
.PARAMETER Recurse
Determines whether or not to copy all files of the ISO file, including those in subdirectories
.PARAMETER Force
Determines whether or not to overwrite existing files
.EXAMPLE .EXAMPLE
Copy-Files "D:" "C:\ISOFile" -Recurse -Force
Set-WinUtilRegistry -Name "PublishUserActivities" -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\System" -Type "DWord" -Value "0"
#> #>
param ( param (
@ -23,7 +29,7 @@ function Copy-Files {
foreach ($file in $files) { foreach ($file in $files) {
$status = "Copying file {0} of {1}: {2}" -f $counter, $files.Count, $file.Name $status = "Copying file {0} of {1}: {2}" -f $counter, $files.Count, $file.Name
Write-Progress -Activity "Copy Windows files" -Status $status -PercentComplete ($counter++/$files.count*100) Write-Progress -Activity "Copy disc image files" -Status $status -PercentComplete ($counter++/$files.count*100)
$restpath = $file.FullName -Replace $path, '' $restpath = $file.FullName -Replace $path, ''
if ($file.PSIsContainer -eq $true) { if ($file.PSIsContainer -eq $true) {
@ -35,7 +41,7 @@ function Copy-Files {
Set-ItemProperty -Path ($destination+$restpath) -Name IsReadOnly -Value $false Set-ItemProperty -Path ($destination+$restpath) -Name IsReadOnly -Value $false
} }
} }
Write-Progress -Activity "Copy Windows files" -Status "Ready" -Completed Write-Progress -Activity "Copy disc image files" -Status "Ready" -Completed
} catch { } catch {
Write-Host "Unable to Copy all the files due to an unhandled exception" -ForegroundColor Yellow Write-Host "Unable to Copy all the files due to an unhandled exception" -ForegroundColor Yellow
Write-Host "Error information: $($_.Exception.Message)`n" -ForegroundColor Yellow Write-Host "Error information: $($_.Exception.Message)`n" -ForegroundColor Yellow

View File

@ -1111,8 +1111,10 @@
Choose a Windows ISO file that you've downloaded <LineBreak/> Choose a Windows ISO file that you've downloaded <LineBreak/>
Check the status in the console Check the status in the console
</TextBlock> </TextBlock>
<Rectangle Fill="{DynamicResource MainForegroundColor}" Height="2" HorizontalAlignment="Stretch" Margin="0,10,0,10"/>
<TextBlock Margin="5" Padding="1" TextWrapping="Wrap" Foreground="{DynamicResource ComboBoxForegroundColor}" ToolTip="Scratch directories act as a custom destination for image files"><Bold>Scratch directory settings (optional)</Bold></TextBlock>
<CheckBox x:Name="WPFMicrowinISOScratchDir" Content="Use ISO directory for ScratchDir " IsChecked="False" Margin="{DynamicResource MicrowinCheckBoxMargin}" <CheckBox x:Name="WPFMicrowinISOScratchDir" Content="Use ISO directory for ScratchDir " IsChecked="False" Margin="{DynamicResource MicrowinCheckBoxMargin}"
ToolTip="Use ISO directory for ScratchDir " /> ToolTip="Check this to use the path of the ISO file you specify as a scratch directory" />
<Grid> <Grid>
<Grid.ColumnDefinitions> <Grid.ColumnDefinitions>
<ColumnDefinition Width="*" /> <!-- Takes the remaining space --> <ColumnDefinition Width="*" /> <!-- Takes the remaining space -->
@ -1122,7 +1124,7 @@
Text="Scratch" Text="Scratch"
Margin="2" Margin="2"
IsReadOnly="False" IsReadOnly="False"
ToolTip="Alt Path For Scratch Directory" ToolTip="Specify an alternate path for the scratch directory"
Grid.Column="0" Grid.Column="0"
VerticalAlignment="Center" VerticalAlignment="Center"
Foreground="{DynamicResource LabelboxForegroundColor}"> Foreground="{DynamicResource LabelboxForegroundColor}">
@ -1138,6 +1140,7 @@
</Button.Content> </Button.Content>
</Button> </Button>
</Grid> </Grid>
<Rectangle Fill="{DynamicResource MainForegroundColor}" Height="2" HorizontalAlignment="Stretch" Margin="0,10,0,10"/>
<TextBox Name="MicrowinFinalIsoLocation" Background="Transparent" BorderBrush="{DynamicResource MainForegroundColor}" <TextBox Name="MicrowinFinalIsoLocation" Background="Transparent" BorderBrush="{DynamicResource MainForegroundColor}"
Text="ISO location will be printed here" Text="ISO location will be printed here"
Margin="2" Margin="2"
@ -1172,6 +1175,7 @@
ToolTip="Path to unpacked drivers all sys and inf files for devices that need drivers" ToolTip="Path to unpacked drivers all sys and inf files for devices that need drivers"
/> />
<CheckBox Name="MicrowinImportDrivers" Content="Import drivers from current system" Margin="{DynamicResource MicrowinCheckBoxMargin}" IsChecked="False" ToolTip="Export all third-party drivers from your system and inject them to the MicroWin image"/> <CheckBox Name="MicrowinImportDrivers" Content="Import drivers from current system" Margin="{DynamicResource MicrowinCheckBoxMargin}" IsChecked="False" ToolTip="Export all third-party drivers from your system and inject them to the MicroWin image"/>
<CheckBox Name="MicrowinCopyVirtIO" Content="Include VirtIO drivers" Margin="{DynamicResource MicrowinCheckBoxMargin}" IsChecked="False" ToolTip="Copy VirtIO Guest Tools drivers to your ISO file. Check this only if you want to use it on QEMU/Proxmox VE"/>
<Rectangle Fill="{DynamicResource MainForegroundColor}" Height="2" HorizontalAlignment="Stretch" Margin="0,10,0,10"/> <Rectangle Fill="{DynamicResource MainForegroundColor}" Height="2" HorizontalAlignment="Stretch" Margin="0,10,0,10"/>
<CheckBox Name="WPFMicrowinCopyToUsb" Content="Copy to Ventoy" Margin="{DynamicResource MicrowinCheckBoxMargin}" IsChecked="False" ToolTip="Copy to USB disk with a label Ventoy"/> <CheckBox Name="WPFMicrowinCopyToUsb" Content="Copy to Ventoy" Margin="{DynamicResource MicrowinCheckBoxMargin}" IsChecked="False" ToolTip="Copy to USB disk with a label Ventoy"/>
<Rectangle Fill="{DynamicResource MainForegroundColor}" Height="2" HorizontalAlignment="Stretch" Margin="0,10,0,10"/> <Rectangle Fill="{DynamicResource MainForegroundColor}" Height="2" HorizontalAlignment="Stretch" Margin="0,10,0,10"/>
@ -1262,7 +1266,13 @@
- Once complete, the target ISO file will be in the directory you have specified <LineBreak/> - Once complete, the target ISO file will be in the directory you have specified <LineBreak/>
- Copy this image to your Ventoy USB Stick, boot to this image, gg - Copy this image to your Ventoy USB Stick, boot to this image, gg
<LineBreak/> <LineBreak/>
If you are injecting drivers ensure you put all your inf, sys, and dll files for each driver into a separate directory If you are injecting drivers ensure you put all your inf, sys, and dll files for each driver into a separate directory <LineBreak/><LineBreak/>
<Bold>Installing VirtIO drivers</Bold><LineBreak/>
If you plan on using your ISO on QEMU/Proxmox VE, you can bundle VirtIO drivers with your ISO to automatically install drivers. Simply tick the "Include VirtIO drivers" checkbox before starting the process. Then, follow these instructions:<LineBreak/><LineBreak/>
<TextBlock TextWrapping="WrapWithOverflow" Margin="15,0,0,0" Text="1. Proceed with Setup until you reach the disk selection screen, in which you won't see any drives" Foreground="{DynamicResource ComboBoxForegroundColor}"/><LineBreak/>
<TextBlock TextWrapping="WrapWithOverflow" Margin="15,0,0,0" Text="2. Click &quot;Load Driver&quot; and click Browse" Foreground="{DynamicResource ComboBoxForegroundColor}"/><LineBreak/>
<TextBlock TextWrapping="WrapWithOverflow" Margin="15,0,0,0" Text="3. In the folder selection dialog, point to this path: &quot;D:\VirtIO\vioscsi\w11\amd64&quot; (replace amd64 with ARM64 if you are using Windows on ARM, and &quot;D:&quot; with the drive letter of the ISO)" Foreground="{DynamicResource ComboBoxForegroundColor}"/><LineBreak/>
<TextBlock TextWrapping="WrapWithOverflow" Margin="15,0,0,0" Text="4. Select all drivers that will appear in the list box and click OK" Foreground="{DynamicResource ComboBoxForegroundColor}"/><LineBreak/>
</TextBlock> </TextBlock>
<TextBlock Margin="15,0,15,15" <TextBlock Margin="15,0,15,15"
Padding = "1" Padding = "1"
@ -1273,7 +1283,7 @@
Foreground = "{DynamicResource ComboBoxForegroundColor}" Foreground = "{DynamicResource ComboBoxForegroundColor}"
xml:space = "preserve" xml:space = "preserve"
> >
<Bold>Example:</Bold> <Bold>Driver structure example:</Bold>
C:\drivers\ C:\drivers\
|-- Driver1\ |-- Driver1\
| |-- Driver1.inf | |-- Driver1.inf
@ -1282,7 +1292,7 @@
| |-- Driver2.inf | |-- Driver2.inf
| |-- Driver2.sys | |-- Driver2.sys
|-- OtherFiles... |-- OtherFiles...
</TextBlock> </TextBlock>
</StackPanel> </StackPanel>
</Border> </Border>
</Grid> </Grid>