diff --git a/README.md b/README.md
index d16a3c15..b3ef0aa9 100644
--- a/README.md
+++ b/README.md
@@ -52,7 +52,7 @@ If you have Issues, refer to [Known Issues](https://christitustech.github.io/win
These are the sponsors that help keep this project alive with monthly contributions.
-
+
## 🏅 Thanks to all Contributors
Thanks a lot for spending your time helping Winutil grow. Thanks a lot! Keep rocking 🍻.
diff --git a/config/feature.json b/config/feature.json
index 137cd9ee..7ea9e48c 100644
--- a/config/feature.json
+++ b/config/feature.json
@@ -321,5 +321,5 @@
"Order": "a084_",
"Type": "Button",
"ButtonWidth": "300"
- },
+ }
}
diff --git a/config/tweaks.json b/config/tweaks.json
index 56729164..93ed630c 100644
--- a/config/tweaks.json
+++ b/config/tweaks.json
@@ -2584,6 +2584,36 @@
],
"link": "https://christitustech.github.io/winutil/dev/tweaks/z--Advanced-Tweaks---CAUTION/RemoveCopilot"
},
+ "WPFTweaksRecallOff": {
+ "Content": "Disable Recall",
+ "Description": "Turn Recall off",
+ "category": "Essential Tweaks",
+ "panel": "1",
+ "Order": "a011_",
+ "registry": [
+ {
+
+ "Path": "HKLM:\\SOFTWARE\\Policies\\Microsoft\\Windows\\WindowsAI",
+ "Name": "DisableAIDataAnalysis",
+ "Type": "DWord",
+ "Value": "1",
+ "OriginalValue": "0"
+ }
+ ],
+ "InvokeScript": [
+ "
+ Write-Host \"Disable Recall\"
+ DISM /Online /Disable-Feature /FeatureName:Recall
+ "
+ ],
+ "UndoScript": [
+ "
+ Write-Host \"Enable Recall\"
+ DISM /Online /Enable-Feature /FeatureName:Recall
+ "
+ ],
+ "link": "https://christitustech.github.io/winutil/dev/tweaks/Essential-Tweaks/DisableRecall"
+ },
"WPFTweaksDisableLMS1": {
"Content": "Disable Intel MM (vPro LMS)",
"Description": "Intel LMS service is always listening on all ports and could be a huge security risk. There is no need to run LMS on home machines and even in the Enterprise there are better solutions.",
@@ -3434,14 +3464,5 @@
"Type": "Button",
"ButtonWidth": "300",
"link": "https://christitustech.github.io/winutil/dev/tweaks/Performance-Plans/RemoveUltPerf"
- },
- "WPFWinUtilShortcut": {
- "Content": "Create WinUtil Shortcut",
- "category": "Shortcuts",
- "panel": "2",
- "Order": "a082_",
- "Type": "Button",
- "ButtonWidth": "300",
- "link": "https://christitustech.github.io/winutil/dev/tweaks/Shortcuts/Shortcut"
}
}
diff --git a/docs/dev/tweaks/Essential-Tweaks/DisableRecall.md b/docs/dev/tweaks/Essential-Tweaks/DisableRecall.md
new file mode 100644
index 00000000..a6ceaa73
--- /dev/null
+++ b/docs/dev/tweaks/Essential-Tweaks/DisableRecall.md
@@ -0,0 +1,91 @@
+# Disable Microsoft Recall
+
+Last Updated: 2024-10-24
+
+
+!!! info
+ The Development Documentation is auto generated for every compilation of WinUtil, meaning a part of it will always stay up-to-date. **Developers do have the ability to add custom content, which won't be updated automatically.**
+## Description
+
+Disables MS Recall built into Windows since 24H2.
+
+
+
+
+
+
+Preview Code
+
+```json
+"WPFTweaksRecallOff": {
+ "Content": "Disable Recall",
+ "Description": "Turn Recall off",
+ "category": "Essential Tweaks",
+ "panel": "1",
+ "Order": "a011_",
+ "registry": [
+ {
+
+ "Path": "HKLM:\\SOFTWARE\\Policies\\Microsoft\\Windows\\WindowsAI",
+ "Name": "DisableAIDataAnalysis",
+ "Type": "DWord",
+ "Value": "1",
+ "OriginalValue": "0"
+ }
+ ],
+ "InvokeScript": [
+ "
+ Write-Host \"Disable Recall\"
+ DISM /Online /Disable-Feature /FeatureName:Recall
+ "
+ ],
+ "UndoScript": [
+ "
+ Write-Host \"Enable Recall\"
+ DISM /Online /Enable-Feature /FeatureName:Recall
+ "
+ ],
+ "link": "https://christitustech.github.io/winutil/dev/tweaks/Essential-Tweaks/DisableRecall"
+ },
+```
+
+
+
+## Invoke Script
+
+```powershell
+
+ Write-Host "Disable Recall"
+ DISM /Online /Disable-Feature /FeatureName:Recall
+
+
+```
+## Undo Script
+
+```powershell
+
+ Write-Host "Enable Recall"
+ DISM /Online /Enable-Feature /FeatureName:Recall
+
+
+```
+## Registry Changes
+Applications and System Components store and retrieve configuration data to modify windows settings, so we can use the registry to change many settings in one place.
+
+
+You can find information about the registry on [Wikipedia](https://www.wikiwand.com/en/Windows_Registry) and [Microsoft's Website](https://learn.microsoft.com/en-us/windows/win32/sysinfo/registry).
+
+### Registry Key: DisableAIDataAnalysis
+
+**Type:** DWord
+
+**Original Value:** 0
+
+**New Value:** 1
+
+
+
+
+
+
+[View the JSON file](https://github.com/ChrisTitusTech/winutil/tree/main/config/tweaks.json)
diff --git a/docs/dev/tweaks/Shortcuts/Shortcut.md b/docs/dev/tweaks/Shortcuts/Shortcut.md
deleted file mode 100644
index c980269e..00000000
--- a/docs/dev/tweaks/Shortcuts/Shortcut.md
+++ /dev/null
@@ -1,113 +0,0 @@
-# Create WinUtil Shortcut
-
-Last Updated: 2024-08-07
-
-
-!!! info
- The Development Documentation is auto generated for every compilation of WinUtil, meaning a part of it will always stay up-to-date. **Developers do have the ability to add custom content, which won't be updated automatically.**
-
-
-
-
-
-
-
-Preview Code
-
-```json
-{
- "Content": "Create WinUtil Shortcut",
- "category": "Shortcuts",
- "panel": "2",
- "Order": "a082_",
- "Type": "Button",
- "ButtonWidth": "300",
- "link": "https://christitustech.github.io/winutil/dev/tweaks/Shortcuts/Shortcut"
-}
-```
-
-
-
-## Function: Invoke-WPFShortcut
-
-```powershell
-function Invoke-WPFShortcut {
- <#
-
- .SYNOPSIS
- Creates a shortcut and prompts for a save location
-
- .PARAMETER ShortcutToAdd
- The name of the shortcut to add
-
- .PARAMETER RunAsAdmin
- A boolean value to make 'Run as administrator' property on (true) or off (false), defaults to off
-
- #>
- param(
- $ShortcutToAdd,
- [bool]$RunAsAdmin = $false
- )
-
- # Preper the Shortcut Fields and add an a Custom Icon if it's available, else don't add a Custom Icon.
-
- Switch ($ShortcutToAdd) {
- "WinUtil" {
- # Use Powershell 7 if installed and fallback to PS5 if not
- if (Get-Command "pwsh" -ErrorAction SilentlyContinue) {
- $shell = "pwsh.exe"
- } else {
- $shell = "powershell.exe"
- }
-
- $shellArgs = "-ExecutionPolicy Bypass -Command `"Start-Process $shell -verb runas -ArgumentList `'-Command `"irm https://github.com/ChrisTitusTech/winutil/releases/latest/download/winutil.ps1 | iex`"`'"
-
- $DestinationName = "WinUtil.lnk"
- }
- }
-
- # Show a File Dialog Browser, to let the User choose the Name and Location of where to save the Shortcut
- $FileBrowser = New-Object System.Windows.Forms.SaveFileDialog
- $FileBrowser.InitialDirectory = [Environment]::GetFolderPath('Desktop')
- $FileBrowser.Filter = "Shortcut Files (*.lnk)|*.lnk"
- $FileBrowser.FileName = $DestinationName
-
- # Do an Early Return if the Save Operation was canceled by User's Input.
- $FileBrowserResult = $FileBrowser.ShowDialog()
- $DialogResultEnum = New-Object System.Windows.Forms.DialogResult
- if (-not ($FileBrowserResult -eq $DialogResultEnum::OK)) {
- return
- }
-
- # Prepare the Shortcut paramter
- $WshShell = New-Object -comObject WScript.Shell
- $Shortcut = $WshShell.CreateShortcut($FileBrowser.FileName)
- $Shortcut.TargetPath = $shell
- $Shortcut.Arguments = $shellArgs
- if (Test-Path -Path $winutildir["logo.ico"]) {
- $shortcut.IconLocation = $winutildir["logo.ico"]
- }
-
- # Save the Shortcut to disk
- $Shortcut.Save()
-
- if ($RunAsAdmin -eq $true) {
- $bytes = [System.IO.File]::ReadAllBytes($FileBrowser.FileName)
- # Set byte value at position 0x15 in hex, or 21 in decimal, from the value 0x00 to 0x20 in hex
- $bytes[0x15] = $bytes[0x15] -bor 0x20
- [System.IO.File]::WriteAllBytes($FileBrowser.FileName, $bytes)
- }
-
- Write-Host "Shortcut for $ShortcutToAdd has been saved to $($FileBrowser.FileName) with 'Run as administrator' set to $RunAsAdmin"
-}
-
-```
-
-
-
-
-
-
-
-[View the JSON file](https://github.com/ChrisTitusTech/winutil/tree/main/config/tweaks.json)
-
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..361f21b2 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,7 @@ function Remove-Features() {
$_.FeatureName -NotLike "*Media*" -AND
$_.FeatureName -NotLike "*NFS*" -AND
$_.FeatureName -NotLike "*SearchEngine*" -AND
+ $_.FeatureName -NotLike "*RemoteDesktop*" -AND
$_.State -ne "Disabled"
}
@@ -157,27 +169,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 +240,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
@@ -242,6 +276,31 @@ function Remove-ProvisionedPackages() {
}
}
+function Get-LocalizedUsers
+{
+ <#
+ .SYNOPSIS
+ Gets a localized user group representation for ICACLS commands (Port from DISMTools PE Helper)
+ .PARAMETER admins
+ Determines whether to get a localized user group representation for the Administrators user group
+ .OUTPUTS
+ A string containing the localized user group
+ .EXAMPLE
+ Get-LocalizedUsers -admins $true
+ #>
+ param (
+ [Parameter(Mandatory = $true, Position = 0)] [bool]$admins
+ )
+ if ($admins)
+ {
+ return (Get-LocalGroup | Where-Object { $_.SID.Value -like "S-1-5-32-544" }).Name
+ }
+ else
+ {
+ return (Get-LocalGroup | Where-Object { $_.SID.Value -like "S-1-5-32-545" }).Name
+ }
+}
+
function Copy-ToUSB([string]$fileToCopy) {
foreach ($volume in Get-Volume) {
if ($volume -and $volume.FileSystemLabel -ieq "ventoy") {
@@ -625,70 +684,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 +785,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,45 +805,19 @@ 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
- #
- $desktopPath = "$($env:USERPROFILE)\Desktop"
- # Specify the target PowerShell command
- $command = "powershell.exe -NoProfile -ExecutionPolicy Bypass -Command 'irm https://christitus.com/win | iex'"
- # Specify the path for the shortcut
- $shortcutPath = Join-Path $desktopPath 'winutil.lnk'
- # Create a shell object
- $shell = New-Object -ComObject WScript.Shell
-
- # Create a shortcut object
- $shortcut = $shell.CreateShortcut($shortcutPath)
-
- if (Test-Path -Path "c:\Windows\cttlogo.png") {
- $shortcut.IconLocation = "c:\Windows\cttlogo.png"
+ try
+ {
+ if ((Get-WindowsOptionalFeature -Online | Where-Object { $_.FeatureName -like "Recall" }).Count -gt 0)
+ {
+ Disable-WindowsOptionalFeature -Online -FeatureName "Recall" -Remove
+ }
}
+ catch
+ {
- # Set properties of the shortcut
- $shortcut.TargetPath = "powershell.exe"
- $shortcut.Arguments = "-NoProfile -ExecutionPolicy Bypass -Command `"$command`""
- # Save the shortcut
- $shortcut.Save()
-
- # Make the shortcut have 'Run as administrator' property on
- $bytes = [System.IO.File]::ReadAllBytes($shortcutPath)
- # Set byte value at position 0x15 in hex, or 21 in decimal, from the value 0x00 to 0x20 in hex
- $bytes[0x15] = $bytes[0x15] -bor 0x20
- [System.IO.File]::WriteAllBytes($shortcutPath, $bytes)
-
- Write-Host "Shortcut created at: $shortcutPath"
- #
- # Done create WinUtil shortcut on the desktop
- # ************************************************
-
- Start-Process explorer
-
+ }
'@
$firstRun | Out-File -FilePath "$env:temp\FirstStartup.ps1" -Force
}
diff --git a/functions/public/Invoke-WPFButton.ps1 b/functions/public/Invoke-WPFButton.ps1
index ee4d0421..6473f693 100644
--- a/functions/public/Invoke-WPFButton.ps1
+++ b/functions/public/Invoke-WPFButton.ps1
@@ -50,7 +50,6 @@ function Invoke-WPFButton {
"WPFFixesNetwork" {Invoke-WPFFixesNetwork}
"WPFUpdatesdisable" {Invoke-WPFUpdatesdisable}
"WPFUpdatessecurity" {Invoke-WPFUpdatessecurity}
- "WPFWinUtilShortcut" {Invoke-WPFShortcut -ShortcutToAdd "WinUtil" -RunAsAdmin $true}
"WPFGetInstalled" {Invoke-WPFGetInstalled -CheckBox "winget"}
"WPFGetInstalledTweaks" {Invoke-WPFGetInstalled -CheckBox "tweaks"}
"WPFGetIso" {Invoke-WPFGetIso}
diff --git a/functions/public/Invoke-WPFMicrowin.ps1 b/functions/public/Invoke-WPFMicrowin.ps1
index 78cced29..966d6a07 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) {
@@ -158,6 +162,35 @@ public class PowerManagement {
Write-Host "Removing Appx Bloat"
Remove-ProvisionedPackages
+ # Detect Windows 11 24H2 and add dependency to FileExp to prevent Explorer look from going back - thanks @WitherOrNot and @thecatontheceiling
+ if ((Test-CompatibleImage $imgVersion $([System.Version]::new(10,0,26100,1))) -eq $true)
+ {
+ try
+ {
+ if (Test-Path "$scratchDir\Windows\SystemApps\MicrosoftWindows.Client.FileExp_cw5n1h2txyewy\appxmanifest.xml" -PathType Leaf)
+ {
+ # Found the culprit. Do the following:
+
+ # 1. Take ownership of the file, from TrustedInstaller to Administrators
+ takeown /F "$scratchDir\Windows\SystemApps\MicrosoftWindows.Client.FileExp_cw5n1h2txyewy\appxmanifest.xml" /A
+
+ # 2. Set ACLs so that we can write to it
+ icacls "$scratchDir\Windows\SystemApps\MicrosoftWindows.Client.FileExp_cw5n1h2txyewy\appxmanifest.xml" /grant "$(Get-LocalizedUsers -admins $true):(M)" | Out-Host
+
+ # 3. Open the file and do the modification
+ $appxManifest = Get-Content -Path "$scratchDir\Windows\SystemApps\MicrosoftWindows.Client.FileExp_cw5n1h2txyewy\appxmanifest.xml"
+ $originalLine = $appxManifest[13]
+ $dependency = "`n "
+ $appxManifest[13] = "$originalLine$dependency"
+ Set-Content -Path "$scratchDir\Windows\SystemApps\MicrosoftWindows.Client.FileExp_cw5n1h2txyewy\appxmanifest.xml" -Value $appxManifest -Force -Encoding utf8
+ }
+ }
+ catch
+ {
+
+ }
+ }
+
Remove-FileOrDirectory -pathToDelete "$($scratchDir)\Windows\System32\LogFiles\WMI\RtBackup" -Directory
Remove-FileOrDirectory -pathToDelete "$($scratchDir)\Windows\DiagTrack" -Directory
Remove-FileOrDirectory -pathToDelete "$($scratchDir)\Windows\InboxApps" -Directory
@@ -238,6 +271,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 +325,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/functions/public/Invoke-WPFShortcut.ps1 b/functions/public/Invoke-WPFShortcut.ps1
deleted file mode 100644
index e4e47871..00000000
--- a/functions/public/Invoke-WPFShortcut.ps1
+++ /dev/null
@@ -1,72 +0,0 @@
-function Invoke-WPFShortcut {
- <#
-
- .SYNOPSIS
- Creates a shortcut and prompts for a save location
-
- .PARAMETER ShortcutToAdd
- The name of the shortcut to add
-
- .PARAMETER RunAsAdmin
- A boolean value to make 'Run as administrator' property on (true) or off (false), defaults to off
-
- #>
- param(
- $ShortcutToAdd,
- [bool]$RunAsAdmin = $false
- )
-
- # Preper the Shortcut Fields and add an a Custom Icon if it's available, else don't add a Custom Icon.
-
- Switch ($ShortcutToAdd) {
- "WinUtil" {
- # Use Powershell 7 if installed and fallback to PS5 if not
- if (Get-Command "pwsh" -ErrorAction SilentlyContinue) {
- $shell = "pwsh.exe"
- } else {
- $shell = "powershell.exe"
- }
-
- $shellArgs = "-ExecutionPolicy Bypass -Command `"Start-Process $shell -verb runas -ArgumentList `'-Command `"irm https://github.com/ChrisTitusTech/winutil/releases/latest/download/winutil.ps1 | iex`"`'"
-
- $DestinationName = "WinUtil.lnk"
- }
- }
-
- # Show a File Dialog Browser, to let the User choose the Name and Location of where to save the Shortcut
- $FileBrowser = New-Object System.Windows.Forms.SaveFileDialog
- $FileBrowser.InitialDirectory = [Environment]::GetFolderPath('Desktop')
- $FileBrowser.Filter = "Shortcut Files (*.lnk)|*.lnk"
- $FileBrowser.FileName = $DestinationName
-
- # Do an Early Return if the Save Operation was canceled by User's Input.
- $FileBrowserResult = $FileBrowser.ShowDialog()
- $DialogResultEnum = New-Object System.Windows.Forms.DialogResult
- if (-not ($FileBrowserResult -eq $DialogResultEnum::OK)) {
- return
- }
-
- # Prepare the Shortcut paramter
- $WshShell = New-Object -comObject WScript.Shell
- $Shortcut = $WshShell.CreateShortcut($FileBrowser.FileName)
- $Shortcut.TargetPath = $shell
- $Shortcut.Arguments = $shellArgs
- if (-NOT (Test-Path -Path $winutildir["logo.ico"])) {
- Invoke-WebRequest -Uri "https://christitus.com/images/logo-full.ico" -OutFile $winutildir["logo.ico"]
- }
- if (Test-Path -Path $winutildir["logo.ico"]) {
- $shortcut.IconLocation = $winutildir["logo.ico"]
- }
-
- # Save the Shortcut to disk
- $Shortcut.Save()
-
- if ($RunAsAdmin -eq $true) {
- $bytes = [System.IO.File]::ReadAllBytes($FileBrowser.FileName)
- # Set byte value at position 0x15 in hex, or 21 in decimal, from the value 0x00 to 0x20 in hex
- $bytes[0x15] = $bytes[0x15] -bor 0x20
- [System.IO.File]::WriteAllBytes($FileBrowser.FileName, $bytes)
- }
-
- Write-Host "Shortcut for $ShortcutToAdd has been saved to $($FileBrowser.FileName) with 'Run as administrator' set to $RunAsAdmin"
-}
diff --git a/functions/public/Invoke-WPFUpdatesdefault.ps1 b/functions/public/Invoke-WPFUpdatesdefault.ps1
index 0b786f32..0b8403c6 100644
--- a/functions/public/Invoke-WPFUpdatesdefault.ps1
+++ b/functions/public/Invoke-WPFUpdatesdefault.ps1
@@ -42,4 +42,24 @@ function Invoke-WPFUpdatesdefault {
Write-Host "==================================================="
Write-Host "--- Windows Update Settings Reset to Default ---"
Write-Host "==================================================="
+
+ Start-Process -FilePath "secedit" -ArgumentList "/configure /cfg $env:windir\inf\defltbase.inf /db defltbase.sdb /verbose" -Wait
+ Start-Process -FilePath "cmd.exe" -ArgumentList "/c RD /S /Q $env:WinDir\System32\GroupPolicyUsers" -Wait
+ Start-Process -FilePath "cmd.exe" -ArgumentList "/c RD /S /Q $env:WinDir\System32\GroupPolicy" -Wait
+ Start-Process -FilePath "gpupdate" -ArgumentList "/force" -Wait
+ Remove-Item -Path "HKCU:\Software\Microsoft\Windows\CurrentVersion\Policies" -Recurse -Force -ErrorAction SilentlyContinue
+ Remove-Item -Path "HKCU:\Software\Microsoft\WindowsSelfHost" -Recurse -Force -ErrorAction SilentlyContinue
+ Remove-Item -Path "HKCU:\Software\Policies" -Recurse -Force -ErrorAction SilentlyContinue
+ Remove-Item -Path "HKLM:\Software\Microsoft\Policies" -Recurse -Force -ErrorAction SilentlyContinue
+ Remove-Item -Path "HKLM:\Software\Microsoft\Windows\CurrentVersion\Policies" -Recurse -Force -ErrorAction SilentlyContinue
+ Remove-Item -Path "HKLM:\Software\Microsoft\Windows\CurrentVersion\WindowsStore\WindowsUpdate" -Recurse -Force -ErrorAction SilentlyContinue
+ Remove-Item -Path "HKLM:\Software\Microsoft\WindowsSelfHost" -Recurse -Force -ErrorAction SilentlyContinue
+ Remove-Item -Path "HKLM:\Software\Policies" -Recurse -Force -ErrorAction SilentlyContinue
+ Remove-Item -Path "HKLM:\Software\WOW6432Node\Microsoft\Policies" -Recurse -Force -ErrorAction SilentlyContinue
+ Remove-Item -Path "HKLM:\Software\WOW6432Node\Microsoft\Windows\CurrentVersion\Policies" -Recurse -Force -ErrorAction SilentlyContinue
+ Remove-Item -Path "HKLM:\Software\WOW6432Node\Microsoft\Windows\CurrentVersion\WindowsStore\WindowsUpdate" -Recurse -Force -ErrorAction SilentlyContinue
+
+ Write-Host "==================================================="
+ Write-Host "--- Windows Local Policies Reset to Default ---"
+ Write-Host "==================================================="
}
diff --git a/overrides/main.html b/overrides/main.html
index bf27a2c6..c8d5a413 100644
--- a/overrides/main.html
+++ b/overrides/main.html
@@ -4,6 +4,7 @@
{{ super() }}
Announcement: We are currently not adding any applications to WinUtil and any apps that will be added through a PR will be declined by the maintainer.
+ Announcement: We are currently reworking the docs to use Hugo rather then mkdocs.
{% endblock %}
diff --git a/scripts/main.ps1 b/scripts/main.ps1
index b865d5e4..690584de 100644
--- a/scripts/main.ps1
+++ b/scripts/main.ps1
@@ -397,10 +397,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 d10d12f9..9cc80c0e 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