diff --git a/functions/private/Copy-Files.ps1 b/functions/private/Copy-Files.ps1 index 33342916..fafb4b51 100644 --- a/functions/private/Copy-Files.ps1 +++ b/functions/private/Copy-Files.ps1 @@ -19,10 +19,10 @@ function Copy-Files { try { $files = Get-ChildItem -Path $path -Recurse:$recurse - Write-Host "Copy $($files.Count)(s) from $path to $destination" + Write-Host "Copy $($files.Count) file(s) from $path to $destination" foreach ($file in $files) { - $status = "Copy files {0} on {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) $restpath = $file.FullName -Replace $path, '' @@ -37,7 +37,11 @@ function Copy-Files { } Write-Progress -Activity "Copy Windows files" -Status "Ready" -Completed } catch { - Write-Warning "Unable to Copy all the files due to unhandled exception" - Write-Warning $psitem.Exception.StackTrace + 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 "Additional information:" -ForegroundColor Yellow + Write-Host $PSItem.Exception.StackTrace + # Write possible suggestions + Write-Host "`nIf you are using an antivirus, try configuring exclusions" } } diff --git a/functions/private/Invoke-WinUtilMicroWin-Helper.ps1 b/functions/private/Invoke-WinUtilMicroWin-Helper.ps1 index 1f80269b..b38dc2a2 100644 --- a/functions/private/Invoke-WinUtilMicroWin-Helper.ps1 +++ b/functions/private/Invoke-WinUtilMicroWin-Helper.ps1 @@ -25,6 +25,17 @@ function Test-CompatibleImage() { } } +class ErroredPackage { + [string]$PackageName + [string]$ErrorMessage + ErroredPackage() { $this.Init(@{} )} + # Constructor for packages that have errored out + ErroredPackage([string]$pkgName, [string]$reason) { + $this.PackageName = $pkgName + $this.ErrorMessage = $reason + } +} + function Get-FidoLangFromCulture { param ( @@ -98,6 +109,8 @@ function Remove-Features() { $_.FeatureName -NotLike "*Media*" -AND $_.FeatureName -NotLike "*NFS*" -AND $_.FeatureName -NotLike "*SearchEngine*" -AND + $_.FeatureName -NotLike "*RemoteDesktop*" -AND + $_.FeatureName -NotLike "*Recall*" -AND $_.State -ne "Disabled" } @@ -157,27 +170,54 @@ function Remove-Packages { $_ -NotLike "*WMIC*" -AND $_ -NotLike "*UI.XaML*" -AND $_ -NotLike "*Ethernet*" -AND - $_ -NotLike "*Wifi*" + $_ -NotLike "*Wifi*" -AND + $_ -NotLike "*FodMetadata*" -AND + $_ -NotLike "*Foundation*" -AND + $_ -NotLike "*LanguageFeatures*" -AND + $_ -NotLike "*VBSCRIPT*" -AND + $_ -NotLike "*License*" } $failedCount = 0 + $erroredPackages = [System.Collections.Generic.List[ErroredPackage]]::new() + foreach ($pkg in $pkglist) { try { $status = "Removing $pkg" - Write-Progress -Activity "Removing Apps" -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 } catch { - # This can happen if the package that is being removed is a permanent one, like FodMetadata - Write-Host "Could not remove OS package $($pkg)" + # This can happen if the package that is being removed is a permanent one + $erroredPackages.Add([ErroredPackage]::new($pkg, $_.Exception.Message)) $failedCount += 1 continue } } - Write-Progress -Activity "Removing Apps" -Status "Ready" -Completed + Write-Progress -Activity "Removing Packages" -Status "Ready" -Completed if ($failedCount -gt 0) { - Write-Host "Some packages could not be removed. Do not worry: your image will still work fine. This can happen if the package is permanent or has been superseded by a newer one." + 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) + { + $erroredPackages = $erroredPackages | Sort-Object -Property ErrorMessage + + $previousErroredPackage = $erroredPackages[0] + $counter = 0 + Write-Host "" + Write-Host "- $($previousErroredPackage.ErrorMessage)" + foreach ($erroredPackage in $erroredPackages) { + if ($erroredPackage.ErrorMessage -ne $previousErroredPackage.ErrorMessage) { + Write-Host "" + $counter = 0 + Write-Host "- $($erroredPackage.ErrorMessage)" + } + $counter += 1 + Write-Host " $counter) $($erroredPackage.PackageName)" + $previousErroredPackage = $erroredPackage + } + Write-Host "" + } } } catch { Write-Host "Unable to get information about the packages. MicroWin processing will continue, but packages will not be processed" @@ -201,13 +241,8 @@ function Remove-ProvisionedPackages() { $appxProvisionedPackages = Get-AppxProvisionedPackage -Path "$($scratchDir)" | Where-Object { $_.PackageName -NotLike "*AppInstaller*" -AND $_.PackageName -NotLike "*Store*" -and - $_.PackageName -NotLike "*dism*" -and - $_.PackageName -NotLike "*Foundation*" -and - $_.PackageName -NotLike "*FodMetadata*" -and - $_.PackageName -NotLike "*LanguageFeatures*" -and $_.PackageName -NotLike "*Notepad*" -and $_.PackageName -NotLike "*Printing*" -and - $_.PackageName -NotLike "*Foundation*" -and $_.PackageName -NotLike "*YourPhone*" -and $_.PackageName -NotLike "*Xbox*" -and $_.PackageName -NotLike "*WindowsTerminal*" -and @@ -625,70 +660,70 @@ function New-CheckInstall { # using here string to embedd firstrun $checkInstall = @' @echo off - if exist "C:\windows\cpu.txt" ( - echo C:\windows\cpu.txt exists + if exist "%HOMEDRIVE%\windows\cpu.txt" ( + echo %HOMEDRIVE%\windows\cpu.txt exists ) else ( - echo C:\windows\cpu.txt does not exist + echo %HOMEDRIVE%\windows\cpu.txt does not exist ) - if exist "C:\windows\SerialNumber.txt" ( - echo C:\windows\SerialNumber.txt exists + if exist "%HOMEDRIVE%\windows\SerialNumber.txt" ( + echo %HOMEDRIVE%\windows\SerialNumber.txt exists ) else ( - echo C:\windows\SerialNumber.txt does not exist + echo %HOMEDRIVE%\windows\SerialNumber.txt does not exist ) - if exist "C:\unattend.xml" ( - echo C:\unattend.xml exists + if exist "%HOMEDRIVE%\unattend.xml" ( + echo %HOMEDRIVE%\unattend.xml exists ) else ( - echo C:\unattend.xml does not exist + echo %HOMEDRIVE%\unattend.xml does not exist ) - if exist "C:\Windows\Setup\Scripts\SetupComplete.cmd" ( - echo C:\Windows\Setup\Scripts\SetupComplete.cmd exists + if exist "%HOMEDRIVE%\Windows\Setup\Scripts\SetupComplete.cmd" ( + echo %HOMEDRIVE%\Windows\Setup\Scripts\SetupComplete.cmd exists ) else ( - echo C:\Windows\Setup\Scripts\SetupComplete.cmd does not exist + echo %HOMEDRIVE%\Windows\Setup\Scripts\SetupComplete.cmd does not exist ) - if exist "C:\Windows\Panther\unattend.xml" ( - echo C:\Windows\Panther\unattend.xml exists + if exist "%HOMEDRIVE%\Windows\Panther\unattend.xml" ( + echo %HOMEDRIVE%\Windows\Panther\unattend.xml exists ) else ( - echo C:\Windows\Panther\unattend.xml does not exist + echo %HOMEDRIVE%\Windows\Panther\unattend.xml does not exist ) - if exist "C:\Windows\System32\Sysprep\unattend.xml" ( - echo C:\Windows\System32\Sysprep\unattend.xml exists + if exist "%HOMEDRIVE%\Windows\System32\Sysprep\unattend.xml" ( + echo %HOMEDRIVE%\Windows\System32\Sysprep\unattend.xml exists ) else ( - echo C:\Windows\System32\Sysprep\unattend.xml does not exist + echo %HOMEDRIVE%\Windows\System32\Sysprep\unattend.xml does not exist ) - if exist "C:\Windows\FirstStartup.ps1" ( - echo C:\Windows\FirstStartup.ps1 exists + if exist "%HOMEDRIVE%\Windows\FirstStartup.ps1" ( + echo %HOMEDRIVE%\Windows\FirstStartup.ps1 exists ) else ( - echo C:\Windows\FirstStartup.ps1 does not exist + echo %HOMEDRIVE%\Windows\FirstStartup.ps1 does not exist ) - if exist "C:\Windows\winutil.ps1" ( - echo C:\Windows\winutil.ps1 exists + if exist "%HOMEDRIVE%\Windows\winutil.ps1" ( + echo %HOMEDRIVE%\Windows\winutil.ps1 exists ) else ( - echo C:\Windows\winutil.ps1 does not exist + echo %HOMEDRIVE%\Windows\winutil.ps1 does not exist ) - if exist "C:\Windows\LogSpecialize.txt" ( - echo C:\Windows\LogSpecialize.txt exists + if exist "%HOMEDRIVE%\Windows\LogSpecialize.txt" ( + echo %HOMEDRIVE%\Windows\LogSpecialize.txt exists ) else ( - echo C:\Windows\LogSpecialize.txt does not exist + echo %HOMEDRIVE%\Windows\LogSpecialize.txt does not exist ) - if exist "C:\Windows\LogAuditUser.txt" ( - echo C:\Windows\LogAuditUser.txt exists + if exist "%HOMEDRIVE%\Windows\LogAuditUser.txt" ( + echo %HOMEDRIVE%\Windows\LogAuditUser.txt exists ) else ( - echo C:\Windows\LogAuditUser.txt does not exist + echo %HOMEDRIVE%\Windows\LogAuditUser.txt does not exist ) - if exist "C:\Windows\LogOobeSystem.txt" ( - echo C:\Windows\LogOobeSystem.txt exists + if exist "%HOMEDRIVE%\Windows\LogOobeSystem.txt" ( + echo %HOMEDRIVE%\Windows\LogOobeSystem.txt exists ) else ( - echo C:\Windows\LogOobeSystem.txt does not exist + echo %HOMEDRIVE%\Windows\LogOobeSystem.txt does not exist ) - if exist "c:\windows\csup.txt" ( - echo c:\windows\csup.txt exists + if exist "%HOMEDRIVE%\windows\csup.txt" ( + echo %HOMEDRIVE%\windows\csup.txt exists ) else ( - echo c:\windows\csup.txt does not exist + echo %HOMEDRIVE%\windows\csup.txt does not exist ) - if exist "c:\windows\LogFirstRun.txt" ( - echo c:\windows\LogFirstRun.txt exists + if exist "%HOMEDRIVE%\windows\LogFirstRun.txt" ( + echo %HOMEDRIVE%\windows\LogFirstRun.txt exists ) else ( - echo c:\windows\LogFirstRun.txt does not exist + echo %HOMEDRIVE%\windows\LogFirstRun.txt does not exist ) '@ $checkInstall | Out-File -FilePath "$env:temp\checkinstall.cmd" -Force -Encoding Ascii @@ -726,7 +761,7 @@ function New-FirstRun { } } - "FirstStartup has worked" | Out-File -FilePath c:\windows\LogFirstRun.txt -Append -NoClobber + "FirstStartup has worked" | Out-File -FilePath "$env:HOMEDRIVE\windows\LogFirstRun.txt" -Append -NoClobber $taskbarPath = "$env:AppData\Microsoft\Internet Explorer\Quick Launch\User Pinned\TaskBar" # Delete all files on the Taskbar @@ -746,7 +781,7 @@ function New-FirstRun { } } Remove-Item -Path "$env:USERPROFILE\Desktop\*.lnk" - Remove-Item -Path "C:\Users\Default\Desktop\*.lnk" + Remove-Item -Path "$env:HOMEDRIVE\Users\Default\Desktop\*.lnk" # ************************************************ # Create WinUtil shortcut on the desktop @@ -762,8 +797,8 @@ function New-FirstRun { # Create a shortcut object $shortcut = $shell.CreateShortcut($shortcutPath) - if (Test-Path -Path "c:\Windows\cttlogo.png") { - $shortcut.IconLocation = "c:\Windows\cttlogo.png" + if (Test-Path -Path "$env:HOMEDRIVE\Windows\cttlogo.png") { + $shortcut.IconLocation = "$env:HOMEDRIVE\Windows\cttlogo.png" } # Set properties of the shortcut @@ -783,8 +818,17 @@ function New-FirstRun { # Done create WinUtil shortcut on the desktop # ************************************************ - Start-Process explorer + try + { + if ((Get-WindowsOptionalFeature -Online | Where-Object { $_.FeatureName -like "Recall" }).Count -gt 0) + { + Disable-WindowsOptionalFeature -Online -FeatureName "Recall" -Remove + } + } + catch + { + } '@ $firstRun | Out-File -FilePath "$env:temp\FirstStartup.ps1" -Force } diff --git a/functions/private/Set-WinUtilRegistry.ps1 b/functions/private/Set-WinUtilRegistry.ps1 index 397ce84c..d2141800 100644 --- a/functions/private/Set-WinUtilRegistry.ps1 +++ b/functions/private/Set-WinUtilRegistry.ps1 @@ -36,7 +36,7 @@ function Set-WinUtilRegistry { } Write-Host "Set $Path\$Name to $Value" - if ($Value -ne ""){ + if ($Value -ne "") { Set-ItemProperty -Path $Path -Name $Name -Type $Type -Value $Value -Force -ErrorAction Stop | Out-Null } else{ diff --git a/functions/public/Invoke-WPFMicrowin.ps1 b/functions/public/Invoke-WPFMicrowin.ps1 index 78cced29..4b90a5bc 100644 --- a/functions/public/Invoke-WPFMicrowin.ps1 +++ b/functions/public/Invoke-WPFMicrowin.ps1 @@ -51,10 +51,6 @@ public class PowerManagement { $index = $sync.MicrowinWindowsFlavors.SelectedValue.Split(":")[0].Trim() Write-Host "Index chosen: '$index' from $($sync.MicrowinWindowsFlavors.SelectedValue)" - $keepPackages = $sync.WPFMicrowinKeepProvisionedPackages.IsChecked - $keepProvisionedPackages = $sync.WPFMicrowinKeepAppxPackages.IsChecked - $keepDefender = $sync.WPFMicrowinKeepDefender.IsChecked - $keepEdge = $sync.WPFMicrowinKeepEdge.IsChecked $copyToUSB = $sync.WPFMicrowinCopyToUsb.IsChecked $injectDrivers = $sync.MicrowinInjectDrivers.IsChecked $importDrivers = $sync.MicrowinImportDrivers.IsChecked @@ -91,6 +87,14 @@ public class PowerManagement { return } + # Detect whether the image to process contains Windows 10 and show warning + if ((Test-CompatibleImage $imgVersion $([System.Version]::new(10,0,21996,1))) -eq $false) { + $msg = "Windows 10 has been detected in the image you want to process. While you can continue, Windows 10 is not a recommended target for MicroWin, and you may not get the full experience." + $dlg_msg = $msg + Write-Host $msg + [System.Windows.MessageBox]::Show($dlg_msg, "Winutil", [System.Windows.MessageBoxButton]::OK, [System.Windows.MessageBoxImage]::Exclamation) + } + $mountDirExists = Test-Path $mountDir $scratchDirExists = Test-Path $scratchDir if (-not $mountDirExists -or -not $scratchDirExists) { @@ -238,6 +242,9 @@ public class PowerManagement { # Write-Host Error code $LASTEXITCODE Write-Host "Done disabling Teams" + Write-Host "Fix Windows Volume Mixer Issue" + reg add "HKLM\zNTUSER\Software\Microsoft\Internet Explorer\LowRegistry\Audio\PolicyConfig\PropertyStore" /f + Write-Host "Bypassing system requirements (system image)" reg add "HKLM\zDEFAULT\Control Panel\UnsupportedHardwareNotificationCache" /v "SV1" /t REG_DWORD /d 0 /f reg add "HKLM\zDEFAULT\Control Panel\UnsupportedHardwareNotificationCache" /v "SV2" /t REG_DWORD /d 0 /f @@ -289,6 +296,19 @@ public class PowerManagement { reg add "HKLM\zSOFTWARE\Microsoft\Windows\CurrentVersion\Themes\Personalize" /v "AppsUseLightTheme" /t REG_DWORD /d 0 /f reg add "HKLM\zSOFTWARE\Microsoft\Windows\CurrentVersion\Themes\Personalize" /v "SystemUsesLightTheme" /t REG_DWORD /d 0 /f + if ((Test-CompatibleImage $imgVersion $([System.Version]::new(10,0,21996,1))) -eq $false) { + # We're dealing with Windows 10. Configure sane desktop settings. NOTE: even though stuff to disable News and Interests is there, + # it doesn't seem to work, and I don't want to waste more time dealing with an operating system that will lose support in a year (2025) + + # I invite anyone to work on improving stuff for News and Interests, but that won't be me! + + Write-Host "Disabling Search Highlights..." + reg add "HKLM\zNTUSER\SOFTWARE\Microsoft\Windows\CurrentVersion\Feeds\DSB" /v "ShowDynamicContent" /t REG_DWORD /d 0 /f + reg add "HKLM\zNTUSER\SOFTWARE\Microsoft\Windows\CurrentVersion\SearchSettings" /v "IsDynamicSearchBoxEnabled" /t REG_DWORD /d 0 /f + reg add "HKLM\zSOFTWARE\Policies\Microsoft\Dsh" /v "AllowNewsAndInterests" /t REG_DWORD /d 0 /f + reg add "HKLM\zNTUSER\SOFTWARE\Microsoft\Windows\CurrentVersion\Search" /v "TraySearchBoxVisible" /t REG_DWORD /d 1 /f + } + } catch { Write-Error "An unexpected error occurred: $_" } finally { diff --git a/scripts/main.ps1 b/scripts/main.ps1 index 873aab4d..9186fb9c 100644 --- a/scripts/main.ps1 +++ b/scripts/main.ps1 @@ -410,10 +410,8 @@ $sync["ISOmanual"].add_Checked({ $sync["ISOLanguage"].Visibility = [System.Windows.Visibility]::Collapsed }) -$sync["ISORelease"].Items.Add("23H2") | Out-Null -$sync["ISORelease"].Items.Add("22H2") | Out-Null -$sync["ISORelease"].Items.Add("21H2") | Out-Null -$sync["ISORelease"].SelectedItem = "23H2" +$sync["ISORelease"].Items.Add("24H2") | Out-Null +$sync["ISORelease"].SelectedItem = "24H2" $sync["ISOLanguage"].Items.Add("System Language ($(Get-FidoLangFromCulture -langName $((Get-Culture).Name)))") | Out-Null if ($currentCulture -ne "English International") { diff --git a/xaml/inputXML.xaml b/xaml/inputXML.xaml index d2baa016..db6894f4 100644 --- a/xaml/inputXML.xaml +++ b/xaml/inputXML.xaml @@ -1040,7 +1040,7 @@ HorizontalAlignment="Stretch"> - + Choose a Windows ISO file that you've downloaded Check the status in the console