diff --git a/.gitattributes b/.gitattributes
new file mode 100644
index 0000000..dfe0770
--- /dev/null
+++ b/.gitattributes
@@ -0,0 +1,2 @@
+# Auto detect text files and perform LF normalization
+* text=auto
diff --git a/.gitignore b/.gitignore
index 8250ba0..6b2d97e 100644
--- a/.gitignore
+++ b/.gitignore
@@ -27,4 +27,8 @@ $RECYCLE.BIN/
*.Package.ps1
CustomMenu.inf
*.zip
-ChangeLog_Full.md
\ No newline at end of file
+ChangeLog_Full.md
+/Optimize-Offline_*
+/OfflineTemp*
+/Src/GUI/image_info.json
+/ConsoleOut.txt
diff --git a/ChangeLog.md b/ChangeLog.md
index e81961b..fd4a21b 100644
--- a/ChangeLog.md
+++ b/ChangeLog.md
@@ -1,5 +1,32 @@
# ChangeLog #
+## Build 4.0.1.10 (02-16-2023) ##
+
+- Corrected the improper formatting of the output WimFileInfo.xml file when running Optimize-Offline with PowerShell 7+
+- Windows 10 22H2 will now display properly in the output WimFileInfo.xml file.
+- Added additional telemetry disabling registry entries.
+- Disabled Interests and News and Meet Now taskbar registry entries.
+- Updated the Win32Calc integration WIM file.
+- Updated the integrated Microsoft Edge Administrative Policy Templates WIM file to the latest versions.
+- Updated the integrated CustomAppsAssociations.xml
+- Updated the 'Additional Tweaks' registry template.
+- Updated the Set-Additional.ps1 post-setup script.
+- Added a Remove-DefaultUser0.ps1 post-setup script.
+- The Get-DeploymentTool function has been replaced with the Get-DISMPath function.
+- Removed redundancies in the Invoke-Cleanup function.
+- Additional framework code changes and other core module updates.
+
+**NOTE: Windows 11 compatibility will be coming with build 4.0.2. Furthermore, the reason for the fairly long hiatus with updates has been due to the passing of my father and the subsequent birth of a little bundle of joy. Though my personal life is not anyone's business on the internet, I also do not think it's fair to let those who use this framework to sit in the dark about its current state. Conclusively, I will try to get to the Troubleshooting/Bug reports as soon as I'm available to do so. Thank you for your understanding and patience.**
+
+## Build 4.0.1.9 (09-12-2021) ##
+
+- Optimize-Offline's native ISO creation function has been re-written and now supports PowerShell 6+.
+- The names of the Biometric FOD packages that are automatically removed when the BioEnrollment System Application has been removed are now displayed and logged.
+- Added the disabling of Windows Taskbar Interests and News.
+- Additional framework code changes and other core module updates.
+
+**NOTE: A very small update was added on 09-16-2021 that adds 21H2 to the Get-ImageData function as well as the module manifest.**
+
## Build 4.0.1.8 (06-22-2021) ##
**NOTE: Updates should resume with the same frequency as before.**
@@ -37,19 +64,3 @@
- Updated the Windows Store bundle packages.
- The MAML XML external help file and manifest data have been updated.
- Multiple code improvements across the framework.
-
-## Build 4.0.1.5 (09-17-2020) ##
-
-- Fixed an error where the metadata for the image would not be returned if both the -DaRT and -Additional parameters were omitted.
-- Updated the Win32Calc integration image package to correct a bug where selecting 'Unit Conversion' from its drop-down list would cause the Win32Calc.exe to close immediately.
-- Updated the Resource Function that returns the metadata for any images being optimized.
-- Additional Optimize-Offline code improvements.
-
-## Build 4.0.1.4 (08-23-2020) ##
-
-- Added support for Windows 10 build 19042 (20H2).
-- Added the new 20H2 Start Menu Experience to the applied registry settings.
-- Corrected an issue for Windows 10 builds 19041+ where it occasionally would be returned as an unsupported image build.
-- Updated the Windows Store bundle packages.
-- Updated the optional Set-Additional runtime script.
-- Multiple code improvements across the framework.
diff --git a/Configuration.json b/Configuration.json
index d5ca3aa..d21d528 100644
--- a/Configuration.json
+++ b/Configuration.json
@@ -1,36 +1,61 @@
{
- "_Info": [
- "This is a JSON based Configuration file for Optimize-Offline.",
- "Ensure proper formatting is used when editing the JSON parameter values.",
- "Boolean parameter values use true and false. String parameter values must be enclosed in double-quotes."
- ],
- "SourcePath": "Path:\\To\\SourceImage",
- "WindowsApps": "Select",
- "SystemApps": true,
- "Capabilities": true,
- "Packages": false,
- "Features": true,
- "DeveloperMode": false,
- "WindowsStore": false,
- "MicrosoftEdge": false,
- "Win32Calc": true,
- "Dedup": true,
- "DaRT": [
- "Setup",
- "Recovery"
- ],
- "Registry": true,
- "Additional": {
- "Setup": false,
- "Wallpaper": false,
- "SystemLogo": false,
- "LockScreen": false,
- "RegistryTemplates": false,
- "LayoutModification": false,
- "Unattend": false,
- "Drivers": false,
- "NetFx3": false
- },
- "ComponentCleanup": false,
- "ISO": "No-Prompt"
+ "_Info": [
+ "This is a JSON based Configuration file for Optimize-Offline.",
+ "Ensure proper formatting is used when editing the JSON parameter values.",
+ "Boolean parameter values use true and false. String parameter values must be enclosed in double-quotes.",
+ "WindowsApps, SystemApps, Capabilities, Packages : All | None | Select | Whitelist | Blacklist",
+ "FeaturesToEnable, FeaturesToDisable : All | None | Select | List",
+ "Services : None | Select | List | Advanced",
+ "CompressionType: Select | None | Fast | Maximum | Solid",
+ "OutputPath : default | path[{filename}?] | select",
+ "FlashToUSB: Off | UEFI | Legacy"
+ ],
+ "SourcePath": "PathTo:\\sources\\install.wim",
+ "WindowsApps": "Select",
+ "SystemApps": "Select",
+ "Capabilities": "None",
+ "Packages": "None",
+ "FeaturesToEnable": "List",
+ "FeaturesToDisable": "List",
+ "Services": "Select",
+ "DeveloperMode": false,
+ "WindowsStore": false,
+ "MicrosoftEdge": false,
+ "Win32Calc": false,
+ "DormantDefender": false,
+ "Dedup": false,
+ "DaRT": [],
+ "Registry": false,
+ "OutputPath": "default",
+ "Additional": {
+ "Setup": false,
+ "Wallpaper": false,
+ "SystemLogo": false,
+ "LockScreen": false,
+ "RegistryTemplates": false,
+ "LayoutModification": false,
+ "Unattend": false,
+ "Drivers": false,
+ "NetFx3": false
+ },
+ "ComponentCleanup": false,
+ "ISO": "No-Prompt",
+ "CompressionType": "Maximum",
+ "SelectiveRegistry": {
+ "DisableWindowsUpgrade": false,
+ "DisableWindowsUpdateMicrosoft": false,
+ "DisableDriverUpdate": false,
+ "DormantOneDrive": false,
+ "Disable3rdPartyApps": false,
+ "W11ClassicContextMenu": false,
+ "ExplorerUIRibbon": false,
+ "ClassicSearchExplorer": false,
+ "RemoveTaskbarPinnedIcons": false,
+ "DisableTeamsApp": false,
+ "DisableVirtualizationSecurity": false,
+ "RunAsTiContextMenu": false,
+ "AmoledBlackTheme": false
+ },
+ "ShutDownOnComplete": false,
+ "FlashToUSB": "Off"
}
\ No newline at end of file
diff --git a/Content/Additional/LayoutModification/README.md b/Content/Additional/LayoutModification/README.md
index 2d57b72..c58c859 100644
--- a/Content/Additional/LayoutModification/README.md
+++ b/Content/Additional/LayoutModification/README.md
@@ -1 +1 @@
-If adding additional user content, place any custom Start Menu layout XML (LayoutModification.xml) file to be added to the image here.
+If adding additional user content, place any custom Start Menu layout XML/JSON (LayoutModification.xml/LayoutModification.json) file to be added to the image here.
diff --git a/Content/Additional/RegistryTemplates/Additional Tweaks.reg b/Content/Additional/RegistryTemplates/Additional Tweaks.reg
index 6d5f09a..fb1761f 100644
Binary files a/Content/Additional/RegistryTemplates/Additional Tweaks.reg and b/Content/Additional/RegistryTemplates/Additional Tweaks.reg differ
diff --git a/Content/Additional/SelectiveRegistry/AMOLED_black_theme.reg b/Content/Additional/SelectiveRegistry/AMOLED_black_theme.reg
new file mode 100644
index 0000000..9891bd1
--- /dev/null
+++ b/Content/Additional/SelectiveRegistry/AMOLED_black_theme.reg
@@ -0,0 +1,87 @@
+Windows Registry Editor Version 5.00
+
+; Pitch Black Theme preset by AveYo, AccentPalette idea by /u/Egg-Tricky
+; for Ctrl+Alt+Del, Logon, Taskbar, Start Menu, Action Center, Title Bar (10 & 11)
+
+[-HKEY_CURRENT_USER\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\Accent]
+[HKEY_CURRENT_USER\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\Accent]
+"AccentColorMenu"=dword:1f000000 ; Window borders and titlebar
+"StartColorMenu"=dword:1f202020 ; Modals in UWP ex. Apply new refresh rate in 10
+"AccentPalette"=hex:\
+ 00,9d,ff,1f,\ ; Links in action center and apps
+ 00,9d,ff,1f,\ ; Taskbar icons underline
+ 00,9d,ff,1f,\ ; Start button hover
+ 00,9d,ff,1f,\ ; Settings icons and links [Blue]
+ 00,00,00,00,\ ; Startmenu background / Active taskbar button - IF "EnableTransparency"=dword:00000000
+ 00,00,00,00,\ ; Taskbar front and Folders on start list background [None]
+ 00,00,00,00,\ ; Taskbar background - IF "EnableTransparency"=dword:00000001
+ 00,00,00,00 ; Unused
+
+[-HKEY_USERS\.DEFAULT\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\Accent]
+[HKEY_USERS\.DEFAULT\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\Accent]
+"AccentColorMenu"=dword:1f000000 ; Window borders and titlebar
+"StartColorMenu"=dword:1f202020 ; Modals in UWP ex. Apply new refresh rate in 10
+"AccentPalette"=hex:\
+ 00,9d,ff,1f,\ ; Links in action center and apps
+ 00,9d,ff,1f,\ ; Taskbar icons underline
+ 00,9d,ff,1f,\ ; Start button hover
+ 00,9d,ff,1f,\ ; Settings icons and links [Blue]
+ 00,00,00,00,\ ; Startmenu background / Active taskbar button - IF "EnableTransparency"=dword:00000000
+ 00,00,00,00,\ ; Taskbar front and Folders on start list background [None]
+ 00,00,00,00,\ ; Taskbar background - IF "EnableTransparency"=dword:00000001
+ 00,00,00,00 ; Unused
+
+[-HKEY_CURRENT_USER\SOFTWARE\Microsoft\Windows\DWM]
+[HKEY_CURRENT_USER\SOFTWARE\Microsoft\Windows\DWM]
+"ColorPrevalence"=dword:00000001 ; Show accent color on Title bars and window borders [x]
+"AccentColor"=dword:1f000000 ; Active title bars - black unsupported in the UI but works with AccentPalette
+"AccentColorInactive"=dword:1f202020 ; Inactive title bars
+
+[-HKEY_USERS\.DEFAULT\SOFTWARE\Microsoft\Windows\DWM]
+[HKEY_USERS\.DEFAULT\SOFTWARE\Microsoft\Windows\DWM]
+"ColorPrevalence"=dword:00000001 ; Show accent color on Title bars and window borders [x]
+"AccentColor"=dword:1f000000 ; Active title bars - black unsupported in the UI but works with AccentPalette
+"AccentColorInactive"=dword:1f202020 ; Inactive title bars
+
+[-HKEY_CURRENT_USER\SOFTWARE\Microsoft\Windows\CurrentVersion\Themes\Personalize]
+[HKEY_CURRENT_USER\SOFTWARE\Microsoft\Windows\CurrentVersion\Themes\Personalize]
+"ColorPrevalence"=dword:00000001 ; Show accent color on Start, taskbar and action center [x]
+"AppsUseLightTheme"=dword:00000000 ; Apps mode [Dark]
+"SystemUsesLightTheme"=dword:00000000 ; Windows mode [Dark]
+"EnabledBlurBehind"=dword:00000001 ; Blur [x]
+"EnableTransparency"=dword:00000000 ; Transparency []
+
+[-HKEY_USERS\.DEFAULT\SOFTWARE\Microsoft\Windows\CurrentVersion\Themes\Personalize]
+[HKEY_USERS\.DEFAULT\SOFTWARE\Microsoft\Windows\CurrentVersion\Themes\Personalize]
+"ColorPrevalence"=dword:00000001 ; Show accent color on Start, taskbar and action center [x]
+"AppsUseLightTheme"=dword:00000000 ; Apps mode [Dark]
+"SystemUsesLightTheme"=dword:00000000 ; Windows mode [Dark]
+"EnabledBlurBehind"=dword:00000001 ; Blur [x]
+"EnableTransparency"=dword:00000000 ; Transparency []
+
+[-HKEY_CURRENT_USER\Control Panel\Colors]
+[HKEY_CURRENT_USER\Control Panel\Colors]
+"Hilight"="0 157 255" ; [Blue]
+"HotTrackingColor"="0 157 255"
+"MenuHilight"="0 157 255"
+
+[-HKEY_USERS\.DEFAULT\Control Panel\Colors]
+[HKEY_USERS\.DEFAULT\Control Panel\Colors]
+"Hilight"="0 157 255" ; [Blue]
+"HotTrackingColor"="0 157 255"
+"MenuHilight"="0 157 255"
+
+[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon]
+"Background"="0 0 0"
+
+[HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\System]
+"DisableAcrylicBackgroundOnLogon"=dword:00000001 ; AveYo: enable pure black logon on 11
+"DisableLogonBackgroundImage"=dword:00000001 ; enable solid color logon - separate undo.reg provided
+
+[HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\Personalization]
+"PersonalColors_Background"="#000000" ; AveYo: this is what was missing to make Ctrl+Alt+Del background black as well
+"PersonalColors_Accent"=-
+"NoLockScreen"=dword:00000001 ; no lock screen entirely - separate undo.reg provided
+
+[-HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\DWM]
+; done - log off and back on to see all changes
\ No newline at end of file
diff --git a/Content/Additional/SelectiveRegistry/RunAsTi.reg b/Content/Additional/SelectiveRegistry/RunAsTi.reg
new file mode 100644
index 0000000..6eb192d
--- /dev/null
+++ b/Content/Additional/SelectiveRegistry/RunAsTi.reg
@@ -0,0 +1,121 @@
+Windows Registry Editor Version 5.00
+
+; Context Menu entries to use RunAsTI - lean and mean snippet by AveYo, 2018-2022
+; [FEATURES]
+; - innovative HKCU load, no need for reg load / unload ping-pong; programs get the user profile
+; - sets ownership privileges, high priority, and explorer support; get System if TI unavailable
+; - accepts special characters in paths for which default run as administrator fails
+; - show on the new 11 contextmenu via whitelisted id; plenty other available, f**k needing an app!
+; 2022.01.28: workaround for 11 release (22000) hindering explorer as TI; fix 7 args
+
+[-HKEY_CLASSES_ROOT\RunAsTI]
+[-HKEY_CLASSES_ROOT\batfile\shell\setdesktopwallpaper]
+[-HKEY_CLASSES_ROOT\cmdfile\shell\setdesktopwallpaper]
+[-HKEY_CLASSES_ROOT\exefile\shell\setdesktopwallpaper]
+[-HKEY_CLASSES_ROOT\mscfile\shell\setdesktopwallpaper]
+[-HKEY_CLASSES_ROOT\Microsoft.PowerShellScript.1\shell\setdesktopwallpaper]
+[-HKEY_CLASSES_ROOT\regfile\shell\setdesktopwallpaper]
+[-HKEY_CLASSES_ROOT\Folder\shell\setdesktopwallpaper]
+[-HKEY_CLASSES_ROOT\Directory\background\shell\extract]
+; To remove entries, copy paste above into undo_RunAsTI.reg file, then import it
+
+; RunAsTI on .bat
+[HKEY_CLASSES_ROOT\batfile\shell\setdesktopwallpaper]
+"MUIVerb"="Run as trustedinstaller"
+"HasLUAShield"=""
+"Icon"="powershell.exe,0"
+[HKEY_CLASSES_ROOT\batfile\shell\setdesktopwallpaper\command]
+@="C:\\Windows\\System32\\WindowsPowerShell\\v1.0\\powershell.exe -win 1 -nop -c iex((10..39|%%{(gp 'Registry::HKCR\\RunAsTI' $_ -ea 0).$_})-join[char]10); # --%% \"%L\""
+
+; RunAsTI on .cmd
+[HKEY_CLASSES_ROOT\cmdfile\shell\setdesktopwallpaper]
+"MUIVerb"="Run as trustedinstaller"
+"HasLUAShield"=""
+"Icon"="powershell.exe,0"
+[HKEY_CLASSES_ROOT\cmdfile\shell\setdesktopwallpaper\command]
+@="C:\\Windows\\System32\\WindowsPowerShell\\v1.0\\powershell.exe -win 1 -nop -c iex((10..39|%%{(gp 'Registry::HKCR\\RunAsTI' $_ -ea 0).$_})-join[char]10); # --%% \"%L\""
+
+; RunAsTI on .exe
+[HKEY_CLASSES_ROOT\exefile\shell\setdesktopwallpaper]
+"MUIVerb"="Run as trustedinstaller"
+"HasLUAShield"=""
+"Icon"="powershell.exe,0"
+[HKEY_CLASSES_ROOT\exefile\shell\setdesktopwallpaper\command]
+@="C:\\Windows\\System32\\WindowsPowerShell\\v1.0\\powershell.exe -win 1 -nop -c iex((10..39|%%{(gp 'Registry::HKCR\\RunAsTI' $_ -ea 0).$_})-join[char]10); # --%% \"%L\""
+
+; RunAsTI on .msc
+[HKEY_CLASSES_ROOT\mscfile\shell\setdesktopwallpaper]
+"MUIVerb"="Run as trustedinstaller"
+"HasLUAShield"=""
+"Icon"="powershell.exe,0"
+[HKEY_CLASSES_ROOT\mscfile\shell\setdesktopwallpaper\command]
+@="C:\\Windows\\System32\\WindowsPowerShell\\v1.0\\powershell.exe -win 1 -nop -c iex((10..39|%%{(gp 'Registry::HKCR\\RunAsTI' $_ -ea 0).$_})-join[char]10); # --%% \"%L\""
+
+; RunAsTI on .ps1
+[HKEY_CLASSES_ROOT\Microsoft.PowerShellScript.1\shell\setdesktopwallpaper]
+"MUIVerb"="Run as trustedinstaller"
+"HasLUAShield"=""
+"Icon"="powershell.exe,0"
+[HKEY_CLASSES_ROOT\Microsoft.PowerShellScript.1\shell\setdesktopwallpaper\command]
+@="C:\\Windows\\System32\\WindowsPowerShell\\v1.0\\powershell.exe -win 1 -nop -c iex((10..39|%%{(gp 'Registry::HKCR\\RunAsTI' $_ -ea 0).$_})-join[char]10); # --%% powershell -nop -c iex((gc -lit '%L')-join[char]10)"
+
+; RunAsTI on .reg
+[HKEY_CLASSES_ROOT\regfile\shell\setdesktopwallpaper]
+"MUIVerb"="Import as trustedinstaller"
+"HasLUAShield"=""
+"Icon"="powershell.exe,0"
+[HKEY_CLASSES_ROOT\regfile\shell\setdesktopwallpaper\command]
+@="C:\\Windows\\System32\\WindowsPowerShell\\v1.0\\powershell.exe -win 1 -nop -c iex((10..39|%%{(gp 'Registry::HKCR\\RunAsTI' $_ -ea 0).$_})-join[char]10); # --%% regedit /s \"%L\""
+
+; RunAsTI on Folder
+[HKEY_CLASSES_ROOT\Folder\shell\setdesktopwallpaper]
+"MuiVerb"="Open as trustedinstaller"
+"HasLUAShield"=""
+"Icon"="powershell.exe,0"
+"AppliesTo"="NOT System.ParsingName:=\"::{645FF040-5081-101B-9F08-00AA002F954E}\""
+[HKEY_CLASSES_ROOT\Folder\shell\setdesktopwallpaper\command]
+@="C:\\Windows\\System32\\WindowsPowerShell\\v1.0\\powershell.exe -win 1 -nop -c iex((10..39|%%{(gp 'Registry::HKCR\\RunAsTI' $_ -ea 0).$_})-join[char]10); # --%% \"%L\""
+
+; Open Powershell as trustedinstaller here
+[HKEY_CLASSES_ROOT\Directory\background\shell\extract]
+"MuiVerb"="Powershell as trustedinstaller"
+"HasLUAShield"=""
+"NoWorkingDirectory"=""
+"Position"="Middle"
+"Icon"="powershell.exe,0"
+[HKEY_CLASSES_ROOT\Directory\background\shell\extract\command]
+@="C:\\Windows\\System32\\WindowsPowerShell\\v1.0\\powershell.exe -win 1 -nop -c iex((10..39|%%{(gp 'Registry::HKCR\\RunAsTI' $_ -ea 0).$_})-join[char]10); # --%% cmd /c set \"1=%V\"& start powershell -nop -noe -c $host.ui.RawUI.WindowTitle=$(whoami); set-location -lit $env:1"
+
+; RunAsTI function
+[HKEY_CLASSES_ROOT\RunAsTI]
+"10"="function RunAsTI ($cmd,$arg) { $id='RunAsTI'; $key=\"Registry::HKU\\$(((whoami /user)-split' ')[-1])\\Volatile Environment\"; $code=@'"
+"11"=" $I=[int32]; $M=$I.module.gettype(\"System.Runtime.Interop`Services.Mar`shal\"); $P=$I.module.gettype(\"System.Int`Ptr\"); $S=[string]"
+"12"=" $D=@(); $T=@(); $DM=[AppDomain]::CurrentDomain.\"DefineDynami`cAssembly\"(1,1).\"DefineDynami`cModule\"(1); $Z=[uintptr]::size "
+"13"=" 0..5|% {$D += $DM.\"Defin`eType\"(\"AveYo_$_\",1179913,[ValueType])}; $D += [uintptr]; 4..6|% {$D += $D[$_].\"MakeByR`efType\"()}"
+"14"=" $F='kernel','advapi','advapi', ($S,$S,$I,$I,$I,$I,$I,$S,$D[7],$D[8]), ([uintptr],$S,$I,$I,$D[9]),([uintptr],$S,$I,$I,[byte[]],$I)"
+"15"=" 0..2|% {$9=$D[0].\"DefinePInvok`eMethod\"(('CreateProcess','RegOpenKeyEx','RegSetValueEx')[$_],$F[$_]+'32',8214,1,$S,$F[$_+3],1,4)}"
+"16"=" $DF=($P,$I,$P),($I,$I,$I,$I,$P,$D[1]),($I,$S,$S,$S,$I,$I,$I,$I,$I,$I,$I,$I,[int16],[int16],$P,$P,$P,$P),($D[3],$P),($P,$P,$I,$I)"
+"17"=" 1..5|% {$k=$_; $n=1; $DF[$_-1]|% {$9=$D[$k].\"Defin`eField\"('f' + $n++, $_, 6)}}; 0..5|% {$T += $D[$_].\"Creat`eType\"()}"
+"18"=" 0..5|% {nv \"A$_\" ([Activator]::CreateInstance($T[$_])) -fo}; function F ($1,$2) {$T[0].\"G`etMethod\"($1).invoke(0,$2)}"
+"19"=" $TI=(whoami /groups)-like'*1-16-16384*'; $As=0; if(!$cmd) {$cmd='control';$arg='admintools'}; if ($cmd-eq'This PC'){$cmd='file:'}"
+"20"=" if (!$TI) {'TrustedInstaller','lsass','winlogon'|% {if (!$As) {$9=sc.exe start $_; $As=@(get-process -name $_ -ea 0|% {$_})[0]}}"
+"21"=" function M ($1,$2,$3) {$M.\"G`etMethod\"($1,[type[]]$2).invoke(0,$3)}; $H=@(); $Z,(4*$Z+16)|% {$H += M \"AllocHG`lobal\" $I $_}"
+"22"=" M \"WriteInt`Ptr\" ($P,$P) ($H[0],$As.Handle); $A1.f1=131072; $A1.f2=$Z; $A1.f3=$H[0]; $A2.f1=1; $A2.f2=1; $A2.f3=1; $A2.f4=1"
+"23"=" $A2.f6=$A1; $A3.f1=10*$Z+32; $A4.f1=$A3; $A4.f2=$H[1]; M \"StructureTo`Ptr\" ($D[2],$P,[boolean]) (($A2 -as $D[2]),$A4.f2,$false)"
+"24"=" $Run=@($null, \"powershell -win 1 -nop -c iex `$env:R; # $id\", 0, 0, 0, 0x0E080600, 0, $null, ($A4 -as $T[4]), ($A5 -as $T[5]))"
+"25"=" F 'CreateProcess' $Run; return}; $env:R=''; rp $key $id -force; $priv=[diagnostics.process].\"GetM`ember\"('SetPrivilege',42)[0]"
+"26"=" 'SeSecurityPrivilege','SeTakeOwnershipPrivilege','SeBackupPrivilege','SeRestorePrivilege' |% {$priv.Invoke($null, @(\"$_\",2))}"
+"27"=" $HKU=[uintptr][uint32]2147483651; $NT='S-1-5-18'; $reg=($HKU,$NT,8,2,($HKU -as $D[9])); F 'RegOpenKeyEx' $reg; $LNK=$reg[4]"
+"28"=" function L ($1,$2,$3) {sp 'Registry::HKCR\\AppID\\{CDCBCFCA-3CDC-436f-A4E2-0E02075250C2}' 'RunAs' $3 -force -ea 0"
+"29"=" $b=[Text.Encoding]::Unicode.GetBytes(\"\\Registry\\User\\$1\"); F 'RegSetValueEx' @($2,'SymbolicLinkValue',0,6,[byte[]]$b,$b.Length)}"
+"30"=" function Q {[int](gwmi win32_process -filter 'name=\"explorer.exe\"'|?{$_.getownersid().sid-eq$NT}|select -last 1).ProcessId}"
+"31"=" $11bug=($((gwmi Win32_OperatingSystem).BuildNumber)-eq'22000')-AND(($cmd-eq'file:')-OR(test-path -lit $cmd -PathType Container))"
+"32"=" if ($11bug) {'System.Windows.Forms','Microsoft.VisualBasic' |% {$9=[Reflection.Assembly]::LoadWithPartialName(\"'$_\")}}"
+"33"=" if ($11bug) {$path='^(l)'+$($cmd -replace '([\\+\\^\\%\\~\\(\\)\\[\\]])','{$1}')+'{ENTER}'; $cmd='control.exe'; $arg='admintools'}"
+"34"=" L ($key-split'\\\\')[1] $LNK ''; $R=[diagnostics.process]::start($cmd,$arg); if ($R) {$R.PriorityClass='High'; $R.WaitForExit()}"
+"35"=" if ($11bug) {$w=0; do {if($w-gt40){break}; sleep -mi 250;$w++} until (Q); [Microsoft.VisualBasic.Interaction]::AppActivate($(Q))}"
+"36"=" if ($11bug) {[Windows.Forms.SendKeys]::SendWait($path)}; do {sleep 7} while(Q); L '.Default' $LNK 'Interactive User'"
+"37"="'@; $V='';'cmd','arg','id','key'|%{$V+=\"`n`$$_='$($(gv $_ -val)-replace\"'\",\"''\")';\"}; sp $key $id $($V,$code) -type 7 -force -ea 0"
+"38"=" start powershell -args \"-win 1 -nop -c `n$V `$env:R=(gi `$key -ea 0).getvalue(`$id)-join''; iex `$env:R\" -verb runas"
+"39"="}; $A=([environment]::commandline-split'-[-]%+ ?',2)[1]-split'\"([^\"]+)\"|([^ ]+)',2|%{$_.Trim(' \"')}; RunAsTI $A[1] $A[2]; # AveYo, 2022.01.28"
+;
diff --git a/Content/Additional/SelectiveRegistry/SelectiveRegistry.ps1 b/Content/Additional/SelectiveRegistry/SelectiveRegistry.ps1
new file mode 100644
index 0000000..0a3621c
--- /dev/null
+++ b/Content/Additional/SelectiveRegistry/SelectiveRegistry.ps1
@@ -0,0 +1,167 @@
+RegHives -Load
+If($SelectiveRegistry.DisableWindowsUpgrade) {
+
+ $TargetReleaseVersionInfo = $null
+
+ Switch ($Global:InstallInfo.Build) {
+ "17134" { $TargetReleaseVersionInfo = "1803" }
+ "17763" { $TargetReleaseVersionInfo = "1809" }
+ "18362" { $TargetReleaseVersionInfo = "1903" }
+ "18363" { $TargetReleaseVersionInfo = "1909" }
+ "19041" { $TargetReleaseVersionInfo = "2004" }
+ "19042" { $TargetReleaseVersionInfo = "2009" }
+ "19043" { $TargetReleaseVersionInfo = "21H1" }
+ }
+
+ If ($Global:InstallInfo.Build -ge "19044") {
+ $TargetReleaseVersionInfo = "21H2"
+ }
+
+ If ($Global:InstallInfo.Build -ge "22500") {
+ $TargetReleaseVersionInfo = "22H2"
+ }
+
+ If ($TargetReleaseVersionInfo){
+
+ Log $OptimizeData.SelectiveRegistryWindowsUpgrade
+
+ RegKey -Path "HKLM:\WIM_HKLM_SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate\AU" -Name "AUOptions" -Type DWord -Value "2"
+ RegKey -Path "HKLM:\WIM_HKLM_SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate\AU" -Name "NoAutoUpdate" -Type DWord -Value "1"
+ RegKey -Path "HKLM:\WIM_HKLM_SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate" -Name "DeferUpdatePeriod" -Type DWord -Value "1"
+ RegKey -Path "HKLM:\WIM_HKLM_SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate" -Name "DeferUpgrade" -Type DWord -Value "1"
+ RegKey -Path "HKLM:\WIM_HKLM_SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate" -Name "DeferUpgradePeriod" -Type DWord -Value "1"
+ RegKey -Path "HKLM:\WIM_HKLM_SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate" -Name "TargetReleaseVersion" -Type DWord -Value "1"
+ RegKey -Path "HKLM:\WIM_HKLM_SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate" -Name "TargetReleaseVersionInfo" -Type String -Value $TargetReleaseVersionInfo
+
+ If ($Global:InstallInfo.Build -ge "17134" -and $Global:InstallInfo.Build -le "20348") { RegKey -Path "HKLM:\WIM_HKLM_SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate" -Name "ProductVersion" -Type String -Value "Windows 10" }
+
+ If ($Global:InstallInfo.Build -ge "22000") { RegKey -Path "HKLM:\WIM_HKLM_SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate" -Name "ProductVersion" -Type String -Value "Windows 11" }
+
+ }
+ Start-Sleep 1
+}
+If($SelectiveRegistry.DisableWindowsUpdateMicrosoft) {
+ Log $OptimizeData.SelectiveRegistryWindowsUpdateMS
+ RegKey -Path "HKLM:\WIM_HKLM_SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate" -Name "DoNotConnectToWindowsUpdateInternetLocations" -Type DWord -Value "1"
+ RegKey -Path "HKLM:\WIM_HKLM_SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate" -Name "DisableWindowsUpdateAccess" -Type DWord -Value "1"
+ RegKey -Path "HKLM:\WIM_HKLM_SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate" -Name "WUServer" -Type String -Value " "
+ RegKey -Path "HKLM:\WIM_HKLM_SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate" -Name "WUStatusServer" -Type String -Value " "
+ RegKey -Path "HKLM:\WIM_HKLM_SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate" -Name "UpdateServiceUrlAlternate" -Type String -Value " "
+ RegKey -Path "HKLM:\WIM_HKLM_SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate\AU" -Name "UseWUServer" -Type DWord -Value "1"
+ Start-Sleep 1
+}
+
+If($SelectiveRegistry.DisableDriverUpdate) {
+ Log $OptimizeData.SelectiveRegistryDriverUpdate
+ RegKey -Path "HKLM:\WIM_HKLM_SOFTWARE\Policies\Microsoft\Windows\Device Metadata" -Name "PreventDeviceMetadataFromNetwork" -Type DWord -Value "1"
+ RegKey -Path "HKLM:\WIM_HKLM_SOFTWARE\Policies\Microsoft\Windows\DriverSearching" -Name "DontPromptForWindowsUpdate" -Type DWord -Value "1"
+ RegKey -Path "HKLM:\WIM_HKLM_SOFTWARE\Policies\Microsoft\Windows\DriverSearching" -Name "DontSearchWindowsUpdate" -Type DWord -Value "1"
+ RegKey -Path "HKLM:\WIM_HKLM_SOFTWARE\Policies\Microsoft\Windows\DriverSearching" -Name "DriverUpdateWizardWuSearchEnabled" -Type DWord -Value "0"
+ RegKey -Path "HKLM:\WIM_HKLM_SOFTWARE\Policies\Microsoft\Windows\DriverSearching" -Name "SearchOrderConfig" -Type DWord -Value "1"
+ RegKey -Path "HKLM:\WIM_HKLM_SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate" -Name "ExcludeWUDriversInQualityUpdate" -Type DWord -Value "1"
+ Start-Sleep 1
+}
+
+If($SelectiveRegistry.DormantOneDrive) {
+ Log $OptimizeData.SelectiveRegistryDormantOneDrive
+ RegKey -Path "HKLM:\WIM_HKCU\SOFTWARE\Microsoft\Windows\CurrentVersion\Run" -Name "OneDriveSetup" -Type DWord -Value "0"
+ Start-Sleep 1
+}
+
+# classic search in explorer
+If($SelectiveRegistry.ClassicSearchExplorer -and $Global:InstallInfo.Build -ge '18363') {
+
+ Log $OptimizeData.SelectiveRegistryClassicSearchExplorer
+
+ RegKey -Path "HKLM:\WIM_HKLM_SOFTWARE\Classes\CLSID\{1d64637d-31e9-4b06-9124-e83fb178ac6e}\TreatAs" -Name "(default)" -Value "{64bc32b5-4eec-4de7-972d-bd8bd0324537}" -Type String -Force
+
+ Start-Sleep 1
+}
+
+If($SelectiveRegistry.RemoveTaskbarPinnedIcons){
+
+ Log $OptimizeData.SelectiveRegistryRemoveTaskbarPinnedIcons
+
+ ## Disable taskbar taskview button
+ RegKey -Path "HKLM:\WIM_HKCU\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\Advanced" -Name "ShowTaskViewButton" -Type Dword -Value "0" -Force
+
+ If($Global:InstallInfo.Build -ge '18362') {
+ #Hide MeetNow icon in taskbar
+ RegKey -Path "HKLM:\WIM_HKCU\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\Explorer" -Name "HideSCAMeetNow" -Type dword -Value "1"
+ RegKey -Path "HKLM:\WIM_HKLM_SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\Explorer" -Name "HideSCAMeetNow" -Type dword -Value "1"
+ }
+
+ if($Global:InstallInfo.Build -le '19044'){
+ RegKey -Path "HKLM:\WIM_HKCU\Software\Policies\Microsoft\Windows\Explorer" -Name "NoPinningStoreToTaskbar" -Value 1 -Type DWord
+ RegKey -Path "HKLM:\WIM_HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\Taskband\AuxilliaryPins" -Name "MailPin" -Value 2 -Type DWord
+ RegKey -Path "HKLM:\WIM_HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced\People" -Name "PeopleBand" -Value 0 -Type DWord
+ }
+
+ # Disable News & Interests icon
+ RegKey -Path "HKLM:\WIM_HKCU\SOFTWARE\Microsoft\Windows\CurrentVersion\Feeds" -Name "ShellFeedsTaskbarViewMode" -Type dword -Value "2"
+ RegKey -Path "HKLM:\WIM_HKLM_SOFTWARE\Policies\Microsoft\Windows\Windows Feeds" -Name "EnableFeeds" -Type dword -Value "0"
+
+ If($Global:InstallInfo.Build -ge '22000') {
+ #Remove Chat icon in taskbar
+ RegKey -Path "HKLM:\WIM_HKLM_SOFTWARE\Policies\Microsoft\Windows\Windows Chat" -Name "ChatIcon" -Type dword -Value "3"
+ RegKey -Path "HKLM:\WIM_HKCU\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\Advanced" -Name "TaskbarMn" -Type dword -Value "0"
+
+ ## Disable widgets button
+ RegKey -Path "HKLM:\WIM_HKCU\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\Advanced" -Name "TaskbarDa" -Type Dword -Value "0" -Force
+ }
+
+ Start-Sleep 1
+
+}
+
+If($SelectiveRegistry.W11ClassicContextMenu -and $Global:InstallInfo.Build -ge '22000') {
+ Log $OptimizeData.SelectiveRegistryW11ClassicContextMenu
+ # Classic context menus
+ RegKey -Path "HKLM:\WIM_HKLM_SOFTWARE\Classes\CLSID\{86ca1aa0-34aa-4e8b-a509-50c905bae2a2}\InprocServer32" -Name "(default)" -Value "" -Type String -Force
+ Start-Sleep 1
+}
+
+if($SelectiveRegistry.DisableTeamsApp -and $Global:InstallInfo.Build -ge '10240') {
+ Log $OptimizeData.SelectiveRegistryDisableTeamsApp
+ RegKey -Path "HKLM:\WIM_HKLM_SOFTWARE\Microsoft\Windows\CurrentVersion\Communications" -Name "ConfigureChatAutoInstall" -Value "0" -Type DWord -Force
+ Start-Sleep 1
+}
+
+if($SelectiveRegistry.DisableVirtualizationSecurity -and $Global:InstallInfo.Build -ge '22000') {
+ Log $OptimizeData.SelectiveRegistryDisableVirtualizationSecurity
+ RegKey -Path "HKLM:\WIM_HKLM_SYSTEM\ControlSet001\Control\DeviceGuard\Scenarios" -Name "HypervisorEnforcedCodeIntegrity" -Value "0" -Type DWord -Force
+ RegKey -Path "HKLM:\WIM_HKLM_SYSTEM\ControlSet001\Control\DeviceGuard" -Name "EnableVirtualizationBasedSecurity" -Value "0" -Type DWord -Force
+ Start-Sleep 1
+}
+
+
+
+if ($SelectiveRegistry.ExplorerUIRibbon) {
+ if ($Global:InstallInfo.Build -le "19044"){
+ Log $OptimizeData.SelectiveRegistryExplorerUIRibbon
+ RegKey -Path "HKLM:\WIM_HKLM_SOFTWARE\Microsoft\Windows\CurrentVersion\Shell Extensions\Blocked" -Name "{e2bf9676-5f8f-435c-97eb-11607a5bedf7}" -Value "" -Type String -Force
+ RegKey -Path "HKLM:\WIM_HKLM_SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Shell Extensions\Blocked" -Name "{e2bf9676-5f8f-435c-97eb-11607a5bedf7}" -Value "" -Type String -Force
+ Start-Sleep 1
+ } elseif ($Global:InstallInfo.Build -eq "22000") {
+ Log $OptimizeData.SelectiveRegistryExplorerUIRibbon
+ # RegKey -Path "HKLM:\WIM_HKCU\Software\Classes\CLSID\{d93ed569-3b3e-4bff-8355-3c44f6a52bb5}\InprocServer32" -Name "(default)" -Value "" -Type String -Force
+ RegKey -Path "HKLM:\WIM_HKLM_SOFTWARE\Classes\CLSID\{d93ed569-3b3e-4bff-8355-3c44f6a52bb5}\InprocServer32" -Name "(default)" -Value "" -Type String -Force
+ Start-Sleep 1
+ }
+}
+
+RegHives -Unload
+
+if($SelectiveRegistry.AmoledBlackTheme -and $Global:InstallInfo.Build -ge '10240') {
+ Log $OptimizeData.SelectiveRegistryAmoledBlackTheme
+ Import-Registry -Path (Get-ChildItem -Path $OptimizeOffline.SelectiveRegistry -Filter AMOLED_black_theme.reg).FullName
+ Start-Sleep 1
+}
+
+if($SelectiveRegistry.RunAsTiContextMenu){
+ Log $OptimizeData.SelectiveRegistryRunAsTiContextMenu
+ Import-Registry -Path (Get-ChildItem -Path $OptimizeOffline.SelectiveRegistry -Filter RunAsTi.reg).FullName
+ Start-Sleep 1
+}
+
+Clear-Host
diff --git a/Content/Additional/SelectiveRegistry/WindowsPhotoViewer.reg b/Content/Additional/SelectiveRegistry/WindowsPhotoViewer.reg
new file mode 100644
index 0000000..2fdecc8
--- /dev/null
+++ b/Content/Additional/SelectiveRegistry/WindowsPhotoViewer.reg
@@ -0,0 +1,197 @@
+Windows Registry Editor Version 5.00
+
+[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Photo Viewer\Capabilities\FileAssociations]
+".bmp"="PhotoViewer.FileAssoc.BITMAP"
+".dib"="PhotoViewer.FileAssoc.BITMAP"
+".jpg"="PhotoViewer.FileAssoc.JPEG"
+".jpe"="PhotoViewer.FileAssoc.JPEG"
+".jpeg"="PhotoViewer.FileAssoc.JPEG"
+".jxr"="PhotoViewer.FileAssoc.JPEG"
+".jfif"="PhotoViewer.FileAssoc.JFIF"
+".wdp"="PhotoViewer.FileAssoc.WDP"
+".png"="PhotoViewer.FileAssoc.PNG"
+".gif"="PhotoViewer.FileAssoc.TIFF"
+".tiff"="PhotoViewer.FileAssoc.TIFF"
+".tif"="PhotoViewer.FileAssoc.TIFF"
+
+; Bitmap
+
+[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\PhotoViewer.FileAssoc.BITMAP]
+"ImageOptionFlags"=dword:00000001
+"FriendlyTypeName"=hex(2):40,00,25,00,50,00,72,00,6f,00,67,00,72,00,61,00,6d,\
+ 00,46,00,69,00,6c,00,65,00,73,00,25,00,5c,00,57,00,69,00,6e,00,64,00,6f,00,\
+ 77,00,73,00,20,00,50,00,68,00,6f,00,74,00,6f,00,20,00,56,00,69,00,65,00,77,\
+ 00,65,00,72,00,5c,00,50,00,68,00,6f,00,74,00,6f,00,56,00,69,00,65,00,77,00,\
+ 65,00,72,00,2e,00,64,00,6c,00,6c,00,2c,00,2d,00,33,00,30,00,35,00,36,00,00,\
+ 00
+
+[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\PhotoViewer.FileAssoc.BITMAP\DefaultIcon]
+@="%SystemRoot%\\System32\\imageres.dll,-70"
+
+[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\PhotoViewer.FileAssoc.BITMAP\shell]
+
+[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\PhotoViewer.FileAssoc.BITMAP\shell\open]
+
+[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\PhotoViewer.FileAssoc.BITMAP\shell\open\command]
+@=hex(2):25,00,53,00,79,00,73,00,74,00,65,00,6d,00,52,00,6f,00,6f,00,74,00,25,\
+ 00,5c,00,53,00,79,00,73,00,74,00,65,00,6d,00,33,00,32,00,5c,00,72,00,75,00,\
+ 6e,00,64,00,6c,00,6c,00,33,00,32,00,2e,00,65,00,78,00,65,00,20,00,22,00,25,\
+ 00,50,00,72,00,6f,00,67,00,72,00,61,00,6d,00,46,00,69,00,6c,00,65,00,73,00,\
+ 25,00,5c,00,57,00,69,00,6e,00,64,00,6f,00,77,00,73,00,20,00,50,00,68,00,6f,\
+ 00,74,00,6f,00,20,00,56,00,69,00,65,00,77,00,65,00,72,00,5c,00,50,00,68,00,\
+ 6f,00,74,00,6f,00,56,00,69,00,65,00,77,00,65,00,72,00,2e,00,64,00,6c,00,6c,\
+ 00,22,00,2c,00,20,00,49,00,6d,00,61,00,67,00,65,00,56,00,69,00,65,00,77,00,\
+ 5f,00,46,00,75,00,6c,00,6c,00,73,00,63,00,72,00,65,00,65,00,6e,00,20,00,25,\
+ 00,31,00,00,00
+
+[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\PhotoViewer.FileAssoc.BITMAP\shell\open\DropTarget]
+"CLSID"="{FFE2A43C-56B9-4bf5-9A79-CC6D4285608A}"
+
+
+; JFIF
+
+
+[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\PhotoViewer.FileAssoc.JFIF]
+"EditFlags"=dword:00010000
+"ImageOptionFlags"=dword:00000001
+"FriendlyTypeName"=hex(2):40,00,25,00,50,00,72,00,6f,00,67,00,72,00,61,00,6d,\
+ 00,46,00,69,00,6c,00,65,00,73,00,25,00,5c,00,57,00,69,00,6e,00,64,00,6f,00,\
+ 77,00,73,00,20,00,50,00,68,00,6f,00,74,00,6f,00,20,00,56,00,69,00,65,00,77,\
+ 00,65,00,72,00,5c,00,50,00,68,00,6f,00,74,00,6f,00,56,00,69,00,65,00,77,00,\
+ 65,00,72,00,2e,00,64,00,6c,00,6c,00,2c,00,2d,00,33,00,30,00,35,00,35,00,00,\
+ 00
+
+[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\PhotoViewer.FileAssoc.JFIF\DefaultIcon]
+@="%SystemRoot%\\System32\\imageres.dll,-72"
+
+[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\PhotoViewer.FileAssoc.JFIF\shell]
+
+[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\PhotoViewer.FileAssoc.JFIF\shell\open]
+"MuiVerb"=hex(2):40,00,25,00,50,00,72,00,6f,00,67,00,72,00,61,00,6d,00,46,00,\
+ 69,00,6c,00,65,00,73,00,25,00,5c,00,57,00,69,00,6e,00,64,00,6f,00,77,00,73,\
+ 00,20,00,50,00,68,00,6f,00,74,00,6f,00,20,00,56,00,69,00,65,00,77,00,65,00,\
+ 72,00,5c,00,70,00,68,00,6f,00,74,00,6f,00,76,00,69,00,65,00,77,00,65,00,72,\
+ 00,2e,00,64,00,6c,00,6c,00,2c,00,2d,00,33,00,30,00,34,00,33,00,00,00
+
+[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\PhotoViewer.FileAssoc.JFIF\shell\open\command]
+@=hex(2):25,00,53,00,79,00,73,00,74,00,65,00,6d,00,52,00,6f,00,6f,00,74,00,25,\
+ 00,5c,00,53,00,79,00,73,00,74,00,65,00,6d,00,33,00,32,00,5c,00,72,00,75,00,\
+ 6e,00,64,00,6c,00,6c,00,33,00,32,00,2e,00,65,00,78,00,65,00,20,00,22,00,25,\
+ 00,50,00,72,00,6f,00,67,00,72,00,61,00,6d,00,46,00,69,00,6c,00,65,00,73,00,\
+ 25,00,5c,00,57,00,69,00,6e,00,64,00,6f,00,77,00,73,00,20,00,50,00,68,00,6f,\
+ 00,74,00,6f,00,20,00,56,00,69,00,65,00,77,00,65,00,72,00,5c,00,50,00,68,00,\
+ 6f,00,74,00,6f,00,56,00,69,00,65,00,77,00,65,00,72,00,2e,00,64,00,6c,00,6c,\
+ 00,22,00,2c,00,20,00,49,00,6d,00,61,00,67,00,65,00,56,00,69,00,65,00,77,00,\
+ 5f,00,46,00,75,00,6c,00,6c,00,73,00,63,00,72,00,65,00,65,00,6e,00,20,00,25,\
+ 00,31,00,00,00
+
+[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\PhotoViewer.FileAssoc.JFIF\shell\open\DropTarget]
+"CLSID"="{FFE2A43C-56B9-4bf5-9A79-CC6D4285608A}"
+
+
+; Jpeg
+
+
+[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\PhotoViewer.FileAssoc.JPEG]
+"EditFlags"=dword:00010000
+"ImageOptionFlags"=dword:00000001
+"FriendlyTypeName"=hex(2):40,00,25,00,50,00,72,00,6f,00,67,00,72,00,61,00,6d,\
+ 00,46,00,69,00,6c,00,65,00,73,00,25,00,5c,00,57,00,69,00,6e,00,64,00,6f,00,\
+ 77,00,73,00,20,00,50,00,68,00,6f,00,74,00,6f,00,20,00,56,00,69,00,65,00,77,\
+ 00,65,00,72,00,5c,00,50,00,68,00,6f,00,74,00,6f,00,56,00,69,00,65,00,77,00,\
+ 65,00,72,00,2e,00,64,00,6c,00,6c,00,2c,00,2d,00,33,00,30,00,35,00,35,00,00,\
+ 00
+
+[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\PhotoViewer.FileAssoc.JPEG\DefaultIcon]
+@="%SystemRoot%\\System32\\imageres.dll,-72"
+
+[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\PhotoViewer.FileAssoc.JPEG\shell]
+
+[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\PhotoViewer.FileAssoc.JPEG\shell\open]
+"MuiVerb"=hex(2):40,00,25,00,50,00,72,00,6f,00,67,00,72,00,61,00,6d,00,46,00,\
+ 69,00,6c,00,65,00,73,00,25,00,5c,00,57,00,69,00,6e,00,64,00,6f,00,77,00,73,\
+ 00,20,00,50,00,68,00,6f,00,74,00,6f,00,20,00,56,00,69,00,65,00,77,00,65,00,\
+ 72,00,5c,00,70,00,68,00,6f,00,74,00,6f,00,76,00,69,00,65,00,77,00,65,00,72,\
+ 00,2e,00,64,00,6c,00,6c,00,2c,00,2d,00,33,00,30,00,34,00,33,00,00,00
+
+[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\PhotoViewer.FileAssoc.JPEG\shell\open\command]
+@=hex(2):25,00,53,00,79,00,73,00,74,00,65,00,6d,00,52,00,6f,00,6f,00,74,00,25,\
+ 00,5c,00,53,00,79,00,73,00,74,00,65,00,6d,00,33,00,32,00,5c,00,72,00,75,00,\
+ 6e,00,64,00,6c,00,6c,00,33,00,32,00,2e,00,65,00,78,00,65,00,20,00,22,00,25,\
+ 00,50,00,72,00,6f,00,67,00,72,00,61,00,6d,00,46,00,69,00,6c,00,65,00,73,00,\
+ 25,00,5c,00,57,00,69,00,6e,00,64,00,6f,00,77,00,73,00,20,00,50,00,68,00,6f,\
+ 00,74,00,6f,00,20,00,56,00,69,00,65,00,77,00,65,00,72,00,5c,00,50,00,68,00,\
+ 6f,00,74,00,6f,00,56,00,69,00,65,00,77,00,65,00,72,00,2e,00,64,00,6c,00,6c,\
+ 00,22,00,2c,00,20,00,49,00,6d,00,61,00,67,00,65,00,56,00,69,00,65,00,77,00,\
+ 5f,00,46,00,75,00,6c,00,6c,00,73,00,63,00,72,00,65,00,65,00,6e,00,20,00,25,\
+ 00,31,00,00,00
+
+[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\PhotoViewer.FileAssoc.JPEG\shell\open\DropTarget]
+"CLSID"="{FFE2A43C-56B9-4bf5-9A79-CC6D4285608A}"
+
+; PNG
+
+[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\PhotoViewer.FileAssoc.PNG]
+"ImageOptionFlags"=dword:00000001
+"FriendlyTypeName"=hex(2):40,00,25,00,50,00,72,00,6f,00,67,00,72,00,61,00,6d,\
+ 00,46,00,69,00,6c,00,65,00,73,00,25,00,5c,00,57,00,69,00,6e,00,64,00,6f,00,\
+ 77,00,73,00,20,00,50,00,68,00,6f,00,74,00,6f,00,20,00,56,00,69,00,65,00,77,\
+ 00,65,00,72,00,5c,00,50,00,68,00,6f,00,74,00,6f,00,56,00,69,00,65,00,77,00,\
+ 65,00,72,00,2e,00,64,00,6c,00,6c,00,2c,00,2d,00,33,00,30,00,35,00,37,00,00,\
+ 00
+
+[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\PhotoViewer.FileAssoc.PNG\DefaultIcon]
+@="%SystemRoot%\\System32\\imageres.dll,-71"
+
+[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\PhotoViewer.FileAssoc.PNG\shell]
+
+[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\PhotoViewer.FileAssoc.PNG\shell\open]
+
+[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\PhotoViewer.FileAssoc.PNG\shell\open\command]
+@=hex(2):25,00,53,00,79,00,73,00,74,00,65,00,6d,00,52,00,6f,00,6f,00,74,00,25,\
+ 00,5c,00,53,00,79,00,73,00,74,00,65,00,6d,00,33,00,32,00,5c,00,72,00,75,00,\
+ 6e,00,64,00,6c,00,6c,00,33,00,32,00,2e,00,65,00,78,00,65,00,20,00,22,00,25,\
+ 00,50,00,72,00,6f,00,67,00,72,00,61,00,6d,00,46,00,69,00,6c,00,65,00,73,00,\
+ 25,00,5c,00,57,00,69,00,6e,00,64,00,6f,00,77,00,73,00,20,00,50,00,68,00,6f,\
+ 00,74,00,6f,00,20,00,56,00,69,00,65,00,77,00,65,00,72,00,5c,00,50,00,68,00,\
+ 6f,00,74,00,6f,00,56,00,69,00,65,00,77,00,65,00,72,00,2e,00,64,00,6c,00,6c,\
+ 00,22,00,2c,00,20,00,49,00,6d,00,61,00,67,00,65,00,56,00,69,00,65,00,77,00,\
+ 5f,00,46,00,75,00,6c,00,6c,00,73,00,63,00,72,00,65,00,65,00,6e,00,20,00,25,\
+ 00,31,00,00,00
+
+[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\PhotoViewer.FileAssoc.PNG\shell\open\DropTarget]
+"CLSID"="{FFE2A43C-56B9-4bf5-9A79-CC6D4285608A}"
+
+; WDP
+
+[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\PhotoViewer.FileAssoc.WDP]
+"EditFlags"=dword:00010000
+"ImageOptionFlags"=dword:00000001
+
+[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\PhotoViewer.FileAssoc.WDP\DefaultIcon]
+@="%SystemRoot%\\System32\\wmphoto.dll,-400"
+
+[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\PhotoViewer.FileAssoc.WDP\shell]
+
+[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\PhotoViewer.FileAssoc.WDP\shell\open]
+"MuiVerb"=hex(2):40,00,25,00,50,00,72,00,6f,00,67,00,72,00,61,00,6d,00,46,00,\
+ 69,00,6c,00,65,00,73,00,25,00,5c,00,57,00,69,00,6e,00,64,00,6f,00,77,00,73,\
+ 00,20,00,50,00,68,00,6f,00,74,00,6f,00,20,00,56,00,69,00,65,00,77,00,65,00,\
+ 72,00,5c,00,70,00,68,00,6f,00,74,00,6f,00,76,00,69,00,65,00,77,00,65,00,72,\
+ 00,2e,00,64,00,6c,00,6c,00,2c,00,2d,00,33,00,30,00,34,00,33,00,00,00
+
+[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\PhotoViewer.FileAssoc.WDP\shell\open\command]
+@=hex(2):25,00,53,00,79,00,73,00,74,00,65,00,6d,00,52,00,6f,00,6f,00,74,00,25,\
+ 00,5c,00,53,00,79,00,73,00,74,00,65,00,6d,00,33,00,32,00,5c,00,72,00,75,00,\
+ 6e,00,64,00,6c,00,6c,00,33,00,32,00,2e,00,65,00,78,00,65,00,20,00,22,00,25,\
+ 00,50,00,72,00,6f,00,67,00,72,00,61,00,6d,00,46,00,69,00,6c,00,65,00,73,00,\
+ 25,00,5c,00,57,00,69,00,6e,00,64,00,6f,00,77,00,73,00,20,00,50,00,68,00,6f,\
+ 00,74,00,6f,00,20,00,56,00,69,00,65,00,77,00,65,00,72,00,5c,00,50,00,68,00,\
+ 6f,00,74,00,6f,00,56,00,69,00,65,00,77,00,65,00,72,00,2e,00,64,00,6c,00,6c,\
+ 00,22,00,2c,00,20,00,49,00,6d,00,61,00,67,00,65,00,56,00,69,00,65,00,77,00,\
+ 5f,00,46,00,75,00,6c,00,6c,00,73,00,63,00,72,00,65,00,65,00,6e,00,20,00,25,\
+ 00,31,00,00,00
+
+[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\PhotoViewer.FileAssoc.WDP\shell\open\DropTarget]
+"CLSID"="{FFE2A43C-56B9-4bf5-9A79-CC6D4285608A}"
+
diff --git a/Content/Additional/Setup/Remove-DefaultUser0.cmd b/Content/Additional/Setup/Remove-DefaultUser0.cmd
new file mode 100644
index 0000000..198f461
--- /dev/null
+++ b/Content/Additional/Setup/Remove-DefaultUser0.cmd
@@ -0,0 +1,18 @@
+@ECHO OFF
+CD /D "%~dp0"
+
+NET SESSION >NUL 2>&1
+IF %ERRORLEVEL% NEQ 0 (
+ ECHO Permission denied. This script must be run as an Administrator.
+ ECHO:
+ PAUSE
+ EXIT
+) ELSE (
+ PowerShell.exe -NoProfile -ExecutionPolicy Bypass -File .\Remove-DefaultUser0.ps1 -Argument 2> .\Remove-DefaultUser0.error
+ DEL /F /Q "%~dp0Remove-DefaultUser0.error" >NUL 2>&1
+ DEL /F /Q "%~dp0Remove-DefaultUser0.ps1" >NUL 2>&1
+ DEL /F /Q "%~f0" >NUL 2>&1
+)
+PAUSE
+EXIT
+
diff --git a/Content/Additional/Setup/Remove-DefaultUser0.ps1 b/Content/Additional/Setup/Remove-DefaultUser0.ps1
new file mode 100644
index 0000000..2ce1c64
--- /dev/null
+++ b/Content/Additional/Setup/Remove-DefaultUser0.ps1
@@ -0,0 +1,18 @@
+If (([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator))
+{
+ [IO.DirectoryInfo]$ProfilePath = Get-ChildItem -Path "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList" | ForEach-Object -Process { $PSItem.GetValue('ProfileImagePath') } | Where-Object { $PSItem -like "*defaultuser0*" }
+ If ($ProfilePath.Exists)
+ {
+ Clear-Host
+ Write-Host "Removing the DefaultUser0 profile." -ForegroundColor Yellow
+ Get-CimInstance -Class Win32_UserProfile | Where-Object { ($PSItem.LocalPath | Split-Path -Leaf) -eq 'defaultuser0' } | Remove-CimInstance
+ $ProfilePath.Refresh()
+ If ($ProfilePath.Exists -and (Test-Path -Path $ProfilePath.FullName))
+ {
+ Invoke-Expression -Command ('TAKEOWN /F "{0}"' -f $ProfilePath.FullName) > $null
+ Invoke-Expression -Command ('ICACLS "{0}" /GRANT *S-1-1-0:F' -f $ProfilePath.FullName) > $null
+ Invoke-Expression -Command ('CMD RMDIR /S /Q "{0}"' -f $ProfilePath.FullName) > $null
+ }
+ }
+ Else { Exit }
+}
\ No newline at end of file
diff --git a/Content/Additional/Setup/Remove-OneDrive.cmd b/Content/Additional/Setup/Remove-OneDrive.cmd
index 7e6b59a..302c0e9 100644
--- a/Content/Additional/Setup/Remove-OneDrive.cmd
+++ b/Content/Additional/Setup/Remove-OneDrive.cmd
@@ -1,18 +1,2 @@
-@ECHO OFF
-CD /D "%~dp0"
-
-NET SESSION >NUL 2>&1
-IF %ERRORLEVEL% NEQ 0 (
- ECHO Permission denied. This script must be run as an Administrator.
- ECHO:
- PAUSE
- EXIT
-) ELSE (
- PowerShell.exe -NoProfile -ExecutionPolicy Bypass -File .\Remove-OneDrive.ps1 -Argument 2> .\Remove-OneDrive.error
- DEL /F /Q "%~dp0Remove-OneDrive.error" >NUL 2>&1
- DEL /F /Q "%~dp0Remove-OneDrive.ps1" >NUL 2>&1
- DEL /F /Q "%~f0" >NUL 2>&1
-)
-PAUSE
-EXIT
+PowerShell -NoProfile -ExecutionPolicy Bypass -File ".\Remove-OneDrive.ps1"
diff --git a/Content/Additional/Setup/Remove-OneDrive.ps1 b/Content/Additional/Setup/Remove-OneDrive.ps1
index e8db43a..946084f 100644
--- a/Content/Additional/Setup/Remove-OneDrive.ps1
+++ b/Content/Additional/Setup/Remove-OneDrive.ps1
@@ -154,6 +154,19 @@ Function Remove-OneDrive
}
}
+# Ensure we are running with administrative permissions.
+If (!([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)) {
+ $arguments = @(" Set-ExecutionPolicy Bypass -Scope Process -Force; & '" + $MyInvocation.MyCommand.Definition + "'")
+ foreach ($param in $PSBoundParameters.GetEnumerator()) {
+ $arguments += "-"+[string]$param.Key+$(If ($param.Value -notin @("True", "False")) {"="+$param.Value} Else {""})
+ }
+ If(!$noPause){
+ $arguments += " ; pause"
+ }
+ Start-Process powershell -Verb RunAs -ArgumentList $arguments
+ Stop-Process -Id $PID
+}
+
If (([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator))
{
Clear-Host
diff --git a/Content/Additional/Setup/Run_TI_SetupComplete_online.cmd b/Content/Additional/Setup/Run_TI_SetupComplete_online.cmd
new file mode 100644
index 0000000..ff46d09
--- /dev/null
+++ b/Content/Additional/Setup/Run_TI_SetupComplete_online.cmd
@@ -0,0 +1,41 @@
+@ECHO OFF
+TITLE Run SetupComplete.cmd online as TrustedInstaller
+
+:: RunAsTI (part 1 of 2) - lean and mean snippet by AveYo Source: https://github.com/AveYo/LeanAndMean
+whoami|findstr /i /c:"nt authority\system" >nul || ( call :RunAsTI "%~f0" %* & exit/b )
+
+pushd "%~dp0"
+
+CALL "%~dp0SetupComplete.cmd"
+
+EXIT
+
+:: RunAsTI (part 2 of 2) - lean and mean snippet by AveYo Source: https://github.com/AveYo/LeanAndMean
+#:RunAsTI: #1 snippet to run as TI/System, with /high priority, /priv ownership, explorer and HKCU load
+set ^ #=& set "0=%~f0"& set 1=%*& powershell -nop -c iex(([io.file]::ReadAllText($env:0)-split':RunAsTI\:.*')[1])& exit/b
+$_CAN_PASTE_DIRECTLY_IN_POWERSHELL='^,^'; function RunAsTI ($cmd) { $id='RunAsTI'; $sid=((whoami /user)-split' ')[-1]; $code=@'
+$ti=(whoami /groups)-like"*1-16-16384*"; $DM=[AppDomain]::CurrentDomain."DefineDynamicAss`embly"(1,1)."DefineDynamicMod`ule"(1)
+$D=@(); 0..5|% {$D+=$DM."DefineT`ype"("M$_",1179913,[ValueType])}; $I=[int32];$P=$I.module.gettype("System.Int`Ptr"); $U=[uintptr]
+$D+=$U; 4..6|% {$D+=$D[$_]."MakeB`yRefType"()};$M=$I.module.gettype("System.Runtime.Interop`Services.Mar`shal");$Z=[uintptr]::size
+$S=[string]; $F="kernel","advapi","advapi",($S,$S,$I,$I,$I,$I,$I,$S,$D[7],$D[8]),($U,$S,$I,$I,$D[9]),($U,$S,$I,$I,[byte[]],$I)
+0..2|% {$9=$D[0]."DefinePInvokeMeth`od"(("CreateProcess","RegOpenKeyEx","RegSetValueEx")[$_],$F[$_]+'32',8214,1,$S,$F[$_+3],1,4)}
+$DF=0,($P,$I,$P),($I,$I,$I,$I,$P,$D[1]),($I,$S,$S,$S,$I,$I,$I,$I,$I,$I,$I,$I,[int16],[int16],$P,$P,$P,$P),($D[3],$P),($P,$P,$I,$I)
+1..5|% {$k=$_;$n=1;$AveYo=1; $DF[$_]|% {$9=$D[$k]."DefineFie`ld"('f'+$n++,$_,6)}}; $T=@(); 0..5|% {$T+=$D[$_]."CreateT`ype"()}
+0..5|% {nv "A$_" ([Activator]::CreateInstance($T[$_])) -force}; function F ($1,$2) {$T[0]."GetMeth`od"($1).invoke(0,$2)};
+if (!$ti) { $g=0; "TrustedInstaller","lsass"|% {if (!$g) {net1 start $_ 2>&1 >$null; $g=@(get-process -name $_ -ea 0|% {$_})[0]}}
+ function M($1,$2,$3){$M."GetMeth`od"($1,[type[]]$2).invoke(0,$3)}; $H=@(); $Z,(4*$Z+16)|% {$H+=M "AllocHG`lobal" $I $_};
+ M "WriteInt`Ptr" ($P,$P) ($H[0],$g.Handle); $A1.f1=131072;$A1.f2=$Z;$A1.f3=$H[0];$A2.f1=1;$A2.f2=1;$A2.f3=1;$A2.f4=1;$A2.f6=$A1
+ $A3.f1=10*$Z+32;$A4.f1=$A3;$A4.f2=$H[1]; M "StructureTo`Ptr" ($D[2],$P,[boolean]) (($A2 -as $D[2]),$A4.f2,$false); $w=0x0E080600
+ $out=@($null,"powershell -win 1 -nop -c iex `$env:A",0,0,0,$w,0,$null,($A4 -as $T[4]),($A5 -as $T[5])); F "CreateProcess" $out
+} else { $env:A=''; $PRIV=[uri].module.gettype("System.Diagnostics.Process")."GetMeth`ods"(42) |? {$_.Name -eq "SetPrivilege"}
+ "SeSecurityPrivilege","SeTakeOwnershipPrivilege","SeBackupPrivilege","SeRestorePrivilege" |% {$PRIV.Invoke(0, @("$_",2))}
+ $HKU=[uintptr][uint32]2147483651; $LNK=$HKU; $reg=@($HKU,"S-1-5-18",8,2,($LNK -as $D[9])); F "RegOpenKeyEx" $reg; $LNK=$reg[4]
+ function SYM($1,$2){$b=[Text.Encoding]::Unicode.GetBytes("\Registry\User\$1");@($2,"SymbolicLinkValue",0,6,[byte[]]$b,$b.Length)}
+ F "RegSetValueEx" (SYM $(($key-split'\\')[1]) $LNK); $EXP="HKLM:\Software\Classes\AppID\{CDCBCFCA-3CDC-436f-A4E2-0E02075250C2}"
+ $r="explorer"; if (!$cmd) {$cmd='C:\'}; $dir=test-path -lit ((($cmd -split '^("[^"]+")|^([^\s]+)') -ne'')[0].trim('"')) -type 1
+ if (!$dir) {$r="start `"$id`" /high /w"}; sp $EXP RunAs '' -force; start cmd -args ("/q/x/d/r title $id && $r",$cmd) -wait -win 1
+ do {sleep 7} while ((gwmi win32_process -filter 'name="explorer.exe"'|? {$_.getownersid().sid -eq "S-1-5-18"}))
+ F "RegSetValueEx" (SYM ".Default" $LNK); sp $EXP RunAs "Interactive User" -force } # lean and mean snippet by AveYo, 2018-2021
+'@; $key="Registry::HKEY_USERS\$sid\Volatile Environment"; $a1="`$id='$id';`$key='$key';";$a2="`$cmd='$($cmd-replace"'","''")';`n"
+sp $key $id $($a1,$a2,$code) -type 7 -force; $arg="$a1 `$env:A=(gi `$key).getvalue(`$id)-join'';rp `$key `$id -force; iex `$env:A"
+$_PRESS_ENTER='^,^'; start powershell -args "-win 1 -nop -c $arg" -verb runas }; <#,#> RunAsTI $env:1; #:RunAsTI:
diff --git a/Content/Additional/Setup/Services.json b/Content/Additional/Setup/Services.json
index 248634d..b9b9854 100644
Binary files a/Content/Additional/Setup/Services.json and b/Content/Additional/Setup/Services.json differ
diff --git a/Content/Additional/Setup/Set-Additional.cmd b/Content/Additional/Setup/Set-Additional.cmd
index 99c7670..a8d9db9 100644
--- a/Content/Additional/Setup/Set-Additional.cmd
+++ b/Content/Additional/Setup/Set-Additional.cmd
@@ -1,18 +1 @@
-@ECHO OFF
-CD /D "%~dp0"
-
-NET SESSION >NUL 2>&1
-IF %ERRORLEVEL% NEQ 0 (
- ECHO Permission denied. This script must be run as an Administrator.
- ECHO:
- PAUSE
- EXIT
-) ELSE (
- PowerShell.exe -NoProfile -ExecutionPolicy Bypass -File .\Set-Additional.ps1 -Argument 2> .\Set-Additional.error
- DEL /F /Q "%~dp0Set-Additional.error" >NUL 2>&1
- DEL /F /Q "%~dp0Set-Additional.ps1" >NUL 2>&1
- DEL /F /Q "%~f0" >NUL 2>&1
-)
-PAUSE
-EXIT
-
+PowerShell -NoProfile -ExecutionPolicy Bypass -File ".\Set-Additional.ps1"
\ No newline at end of file
diff --git a/Content/Additional/Setup/Set-Additional.ps1 b/Content/Additional/Setup/Set-Additional.ps1
index 55576c7..44b60cf 100644
--- a/Content/Additional/Setup/Set-Additional.ps1
+++ b/Content/Additional/Setup/Set-Additional.ps1
@@ -17,7 +17,7 @@ Function Set-Additional
If ((Get-ExecutionPolicy -Scope CurrentUser) -ne 'RemoteSigned') { Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser -Confirm:$false }
If ((Get-ExecutionPolicy -Scope LocalMachine) -ne 'RemoteSigned') { Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope LocalMachine -Confirm:$false }
- # Get the current build number for the Windows 10 version.
+ # Get the current build number for the Windows version.
$Build = Get-CimInstance -ClassName Win32_OperatingSystem | Select-Object -ExpandProperty BuildNumber
If (Test-Path -Path .\ScheduledTasks.json)
@@ -118,7 +118,7 @@ Function Set-Additional
}
# Disable Clipboard history, its synchronization service and any Remote Desktop redirection.
- If ($Build -ge 17763)
+ If ($Build -lt 19041)
{
If (!(Test-Path -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\System")) { New-Item -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\System" -ItemType Directory -Force | Out-Null }
Set-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\System" -Name AllowCrossDeviceClipboard -Value 0 -Force
@@ -127,7 +127,10 @@ Function Set-Additional
Set-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Terminal Server Client" -Name DisableClipboardRedirection -Value 1 -Force
If (!(Test-Path -Path "HKCU:\Software\Microsoft\Clipboard")) { New-Item -Path "HKCU:\Software\Microsoft\Clipboard" -ItemType Directory -Force | Out-Null }
Set-ItemProperty -Path "HKCU:\Software\Microsoft\Clipboard" -Name EnableClipboardHistory -Value 0 -Force
- Set-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Services\cbdhsvc" -Name Start -Value 4 -Force
+ }
+
+ If ($Build -ge 18363) {
+ Set-ItemProperty -Path "HKCU:\SOFTWARE\Classes\CLSID\{1d64637d-31e9-4b06-9124-e83fb178ac6e}\TreatAs" -Name "(Default)" -Value "{64bc32b5-4eec-4de7-972d-bd8bd0324537}" -Force
}
# Uninstall Cortana.
@@ -140,15 +143,14 @@ Function Set-Additional
If ((Get-ItemPropertyValue -Path "HKLM:\SYSTEM\CurrentControlSet\Control\Session Manager\Environment" -Name DrvType) -eq 'SSD')
{
- # Enable TRIM support for NTFS and ReFS file systems for SSD drives.
+ # Enable TRIM support for NTFS and ReFS file systems.
Invoke-Expression -Command ('FSUTIL BEHAVIOR SET DISABLEDELETENOTIFY NTFS 0') | Out-Null
- $QueryReFS = Invoke-Expression -Command ('FSUTIL BEHAVIOR QUERY DISABLEDELETENOTIFY') | Select-String -Pattern ReFS
- If ($QueryReFS) { Invoke-Expression -Command ('FSUTIL BEHAVIOR SET DISABLEDELETENOTIFY REFS 0') | Out-Null }
+ If (Invoke-Expression -Command ('FSUTIL BEHAVIOR QUERY DISABLEDELETENOTIFY') | Select-String -Pattern ReFS) { Invoke-Expression -Command ('FSUTIL BEHAVIOR SET DISABLEDELETENOTIFY REFS 0') | Out-Null }
- # Disable Swapfile.sys which can improve SSD performance.
+ # Disable Swapfile.sys which can improve SSD performance
Set-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Control\Session Manager\Memory Management" -Name SwapfileControl -Value 0 -Force
- # Disable Prefetch and Superfetch (optimal for SSD drives).
+ # Disable Prefetch and Superfetch (optimal for SSD drives)
If (!(Test-Path -Path "HKLM:\SYSTEM\CurrentControlSet\Control\Session Manager\Memory Management\PrefetchParameters")) { New-Item -Path "HKLM:\SYSTEM\CurrentControlSet\Control\Session Manager\Memory Management\PrefetchParameters" -ItemType Directory -Force | Out-Null }
Set-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Control\Session Manager\Memory Management\PrefetchParameters" -Name EnablePrefetcher -Value 0 -Force
Set-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Control\Session Manager\Memory Management\PrefetchParameters" -Name EnableSuperfetch -Value 0 -Force
@@ -161,6 +163,10 @@ Function Set-Additional
}
Else
{
+ # If the Ultimate Performance power scheme is not available, duplicate the power scheme's GUID so it becomes available. Finally, set the active power scheme to Ultimate Performance
+ If (!(Get-CimInstance -ClassName Win32_PowerPlan -Namespace root\cimv2\power -Filter "ElementName = 'Ultimate Performance'")) { Invoke-Expression -Command ('POWERCFG -DUPLICATESCHEME e9a42b02-d5df-448d-aa00-03f14749eb61') }
+ Invoke-Expression -Command ('POWERCFG -S e9a42b02-d5df-448d-aa00-03f14749eb61') | Out-Null
+
# Disable hibernation.
Invoke-Expression -Command ('POWERCFG -H OFF') | Out-Null
@@ -169,11 +175,6 @@ Function Set-Additional
$PSItem.AllowComputerToTurnOffDevice = 'Disabled'
$PSItem | Set-NetAdapterPowerManagement
}
-
- # Set the active power scheme to Ultimate Performance if the runtime Windows version is Windows 10 Pro for Workstations or the Ultimate Performance power scheme GUID is detected, else set the active power scheme to High Performance.
- If ((Get-WindowsEdition -Online | Select-Object -ExpandProperty Edition) -eq 'ProfessionalWorkstation') { Invoke-Expression -Command ('POWERCFG -S e9a42b02-d5df-448d-aa00-03f14749eb61') | Out-Null }
- ElseIf (POWERCFG -L | Out-String | Select-String -Pattern 'e9a42b02-d5df-448d-aa00-03f14749eb61') { Invoke-Expression -Command ('POWERCFG -S e9a42b02-d5df-448d-aa00-03f14749eb61') | Out-Null }
- Else { Invoke-Expression -Command ('POWERCFG -S 8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c') | Out-Null }
}
# Use the total amount of memory installed on the device to modify the svchost.exe split threshold to reduce the amount of svchost.exe processes that run simultaneously.
@@ -197,10 +198,11 @@ Function Set-Additional
If ($RequestReboot -eq [Windows.MessageBoxResult]::Yes)
{
Clear-Host
+ Remove-Item -Path $PSScriptRoot\Set-Additional.error -Force -ErrorAction Ignore
$ProgressPreference = 'Continue'
- ForEach ($Count In (1 .. 15))
+ ForEach ($Count In (1 .. 5))
{
- Write-Progress -Id 1 -Activity "Restarting $Env:COMPUTERNAME" -Status "Restarting in 15 seconds, $(15 - $Count) seconds left" -PercentComplete (($Count / 15) * 100)
+ Write-Progress -Id 1 -Activity "Restarting $Env:COMPUTERNAME" -Status "Restarting in 5 seconds, $(5 - $Count) seconds left" -PercentComplete (($Count / 5) * 100)
Start-Sleep 1
}
Restart-Computer -Force
@@ -214,6 +216,19 @@ Function Set-Additional
}
}
+# Ensure we are running with administrative permissions.
+If (!([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)) {
+ $arguments = @(" Set-ExecutionPolicy Bypass -Scope Process -Force; & '" + $MyInvocation.MyCommand.Definition + "'")
+ foreach ($param in $PSBoundParameters.GetEnumerator()) {
+ $arguments += "-"+[string]$param.Key+$(If ($param.Value -notin @("True", "False")) {"="+$param.Value} Else {""})
+ }
+ If(!$noPause){
+ $arguments += " ; pause"
+ }
+ Start-Process powershell -Verb RunAs -ArgumentList $arguments
+ Stop-Process -Id $PID
+}
+
If (([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator))
{
Clear-Host
diff --git a/Content/Additional/Setup/SetupComplete.cmd b/Content/Additional/Setup/SetupComplete.cmd
index 6617bdb..ea57998 100644
--- a/Content/Additional/Setup/SetupComplete.cmd
+++ b/Content/Additional/Setup/SetupComplete.cmd
@@ -4,6 +4,7 @@ REM Answer files should ALWAYS be removed from the 'Windows\Panther' and 'Window
PowerShell.exe -NoProfile -ExecutionPolicy Bypass -File "%WINDIR%\Setup\Scripts\Refresh-Explorer.ps1"
DEL /F /Q "%WINDIR%\Setup\Scripts\Refresh-Explorer.ps1" >NUL 2>&1
+DEL /F /Q "%WINDIR%\Setup\Scripts\Run_TI_SetupComplete_online.cmd >NUL 2>&1
DEL /F /Q "%WINDIR%\Panther\unattend.xml" >NUL 2>&1
DEL /F /Q "%WINDIR%\System32\Sysprep\unattend.xml" >NUL 2>&1
-DEL "%~f0"
\ No newline at end of file
+DEL "%~f0"
diff --git a/Content/Additional/Unattend/unattend.xml b/Content/Additional/Unattend/unattend.xml
new file mode 100644
index 0000000..33c78c1
--- /dev/null
+++ b/Content/Additional/Unattend/unattend.xml
@@ -0,0 +1,16 @@
+
+
+
+
+
+ true
+ true
+ true
+ true
+ 3
+ false
+
+ false
+
+
+
\ No newline at end of file
diff --git a/Content/Additional/Unattend/unattend_basic.xml b/Content/Additional/Unattend/unattend_basic.xml
new file mode 100644
index 0000000..33c78c1
--- /dev/null
+++ b/Content/Additional/Unattend/unattend_basic.xml
@@ -0,0 +1,16 @@
+
+
+
+
+
+ true
+ true
+ true
+ true
+ 3
+ false
+
+ false
+
+
+
\ No newline at end of file
diff --git a/Content/AppxWhitelist.json b/Content/AppxWhitelist.json
deleted file mode 100644
index f9436bb..0000000
Binary files a/Content/AppxWhitelist.json and /dev/null differ
diff --git a/Content/Assets/PlaceAssets.txt b/Content/Assets/PlaceAssets.txt
new file mode 100644
index 0000000..6c0b9e0
--- /dev/null
+++ b/Content/Assets/PlaceAssets.txt
@@ -0,0 +1,3 @@
+Place different assets here
+You can place windows.ico - used as the windows local disk icon
+setup.ico - used as the USB/ISO icon
\ No newline at end of file
diff --git a/Content/Assets/setup.ico b/Content/Assets/setup.ico
new file mode 100644
index 0000000..fbd1184
Binary files /dev/null and b/Content/Assets/setup.ico differ
diff --git a/Content/CustomAppAssociations.xml b/Content/CustomAppAssociations.xml
index ad2b6a7..399c50a 100644
--- a/Content/CustomAppAssociations.xml
+++ b/Content/CustomAppAssociations.xml
@@ -3,22 +3,13 @@
-
+
-
+
-
-
-
-
-
-
-
-
-
-
-
+
+
@@ -31,24 +22,30 @@
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
\ No newline at end of file
diff --git a/Content/Lists/Capabilities/CapabilitiesList.json b/Content/Lists/Capabilities/CapabilitiesList.json
new file mode 100644
index 0000000..3c4f7ee
--- /dev/null
+++ b/Content/Lists/Capabilities/CapabilitiesList.json
@@ -0,0 +1,5 @@
+{
+ "Name": [
+
+ ]
+ }
\ No newline at end of file
diff --git a/Content/Lists/Capabilities/CapabilitiesTemplate.json b/Content/Lists/Capabilities/CapabilitiesTemplate.json
new file mode 100644
index 0000000..4471978
--- /dev/null
+++ b/Content/Lists/Capabilities/CapabilitiesTemplate.json
@@ -0,0 +1,5 @@
+{
+ "Name": [
+
+ ]
+}
diff --git a/Content/Lists/FeaturesToDisable/FeaturesToDisableList.json b/Content/Lists/FeaturesToDisable/FeaturesToDisableList.json
new file mode 100644
index 0000000..f498830
--- /dev/null
+++ b/Content/Lists/FeaturesToDisable/FeaturesToDisableList.json
@@ -0,0 +1,5 @@
+{
+ "FeatureName" : [
+
+ ]
+}
diff --git a/Content/Lists/FeaturesToDisable/FeaturesToDisableTemplate.json b/Content/Lists/FeaturesToDisable/FeaturesToDisableTemplate.json
new file mode 100644
index 0000000..298df67
--- /dev/null
+++ b/Content/Lists/FeaturesToDisable/FeaturesToDisableTemplate.json
@@ -0,0 +1,5 @@
+{
+ "FeatureName": [
+
+ ]
+}
diff --git a/Content/Lists/FeaturesToEnable/FeaturesToEnableList.json b/Content/Lists/FeaturesToEnable/FeaturesToEnableList.json
new file mode 100644
index 0000000..f498830
--- /dev/null
+++ b/Content/Lists/FeaturesToEnable/FeaturesToEnableList.json
@@ -0,0 +1,5 @@
+{
+ "FeatureName" : [
+
+ ]
+}
diff --git a/Content/Lists/FeaturesToEnable/FeaturesToEnableTemplate.json b/Content/Lists/FeaturesToEnable/FeaturesToEnableTemplate.json
new file mode 100644
index 0000000..298df67
--- /dev/null
+++ b/Content/Lists/FeaturesToEnable/FeaturesToEnableTemplate.json
@@ -0,0 +1,5 @@
+{
+ "FeatureName": [
+
+ ]
+}
diff --git a/Content/Lists/Packages/PackagesList.json b/Content/Lists/Packages/PackagesList.json
new file mode 100644
index 0000000..a3c3ebc
--- /dev/null
+++ b/Content/Lists/Packages/PackagesList.json
@@ -0,0 +1,5 @@
+{
+ "PackageName": [
+
+ ]
+}
diff --git a/Content/Lists/Packages/PackagesTemplate.json b/Content/Lists/Packages/PackagesTemplate.json
new file mode 100644
index 0000000..da05129
--- /dev/null
+++ b/Content/Lists/Packages/PackagesTemplate.json
@@ -0,0 +1,5 @@
+{
+ "PackageName": [
+
+ ]
+}
diff --git a/Content/Lists/Services/ServicesAdvanced.json b/Content/Lists/Services/ServicesAdvanced.json
new file mode 100644
index 0000000..24866c6
--- /dev/null
+++ b/Content/Lists/Services/ServicesAdvanced.json
@@ -0,0 +1,13 @@
+{
+ "__Info": [
+ "start key values",
+ "0 = Boot",
+ "1 = System",
+ "2 = Automatic",
+ "3 = Manual",
+ "4 = Disabled"
+ ],
+ "Services": [
+
+ ]
+}
\ No newline at end of file
diff --git a/Content/Lists/Services/ServicesList.json b/Content/Lists/Services/ServicesList.json
new file mode 100644
index 0000000..6290035
--- /dev/null
+++ b/Content/Lists/Services/ServicesList.json
@@ -0,0 +1,8 @@
+{
+ "__Info": [
+ "Insert the services display names as a list, the names are found in the ./ServicesTemplate.json in the 'name' key"
+ ],
+ "Services": [
+
+ ]
+}
diff --git a/Content/Lists/Services/ServicesTemplate.json b/Content/Lists/Services/ServicesTemplate.json
new file mode 100644
index 0000000..9ac65b5
--- /dev/null
+++ b/Content/Lists/Services/ServicesTemplate.json
@@ -0,0 +1,13 @@
+{
+ "__Info": [
+ "start key values",
+ "0 = Boot",
+ "1 = System",
+ "2 = Automatic",
+ "3 = Manual",
+ "4 = Disabled"
+ ],
+ "Services": [
+
+ ]
+}
diff --git a/Content/Lists/SystemApps/SystemAppsList.json b/Content/Lists/SystemApps/SystemAppsList.json
new file mode 100644
index 0000000..960e422
--- /dev/null
+++ b/Content/Lists/SystemApps/SystemAppsList.json
@@ -0,0 +1,5 @@
+{
+ "DisplayName": [
+
+ ]
+}
\ No newline at end of file
diff --git a/Content/Lists/SystemApps/SystemAppsTemplate.json b/Content/Lists/SystemApps/SystemAppsTemplate.json
new file mode 100644
index 0000000..d3a4575
--- /dev/null
+++ b/Content/Lists/SystemApps/SystemAppsTemplate.json
@@ -0,0 +1,5 @@
+{
+ "DisplayName": [
+
+ ]
+}
diff --git a/Content/Lists/WindowsApps/WindowsAppsList.json b/Content/Lists/WindowsApps/WindowsAppsList.json
new file mode 100644
index 0000000..3f3ebae
--- /dev/null
+++ b/Content/Lists/WindowsApps/WindowsAppsList.json
@@ -0,0 +1,5 @@
+{
+ "DisplayName": [
+
+ ]
+}
diff --git a/Content/Lists/WindowsApps/WindowsAppsTemplate.json b/Content/Lists/WindowsApps/WindowsAppsTemplate.json
new file mode 100644
index 0000000..d3a4575
--- /dev/null
+++ b/Content/Lists/WindowsApps/WindowsAppsTemplate.json
@@ -0,0 +1,5 @@
+{
+ "DisplayName": [
+
+ ]
+}
diff --git a/Optimize-Offline.psd1 b/Optimize-Offline.psd1
index a7744f6..999742a 100644
--- a/Optimize-Offline.psd1
+++ b/Optimize-Offline.psd1
@@ -1,6 +1,6 @@
<#
===========================================================================
- Created with: SAPIEN Technologies, Inc., PowerShell Studio 2019 v5.7.182
+ Created with: SAPIEN Technologies, Inc., PowerShell Studio 2021 v5.8.194
Created on: 11/20/2019 11:53 AM
Created by: BenTheGreat
Filename: Optimize-Offline.psd1
@@ -14,10 +14,11 @@
@{
GUID = '86c4db30-1a45-43c7-a96b-46d2a1d84671'
RootModule = 'Optimize-Offline.psm1'
- ModuleVersion = '4.0.1.7'
+ ModuleVersion = '4.0.1.9'
+ ModuleForkVersion = 'gdeliana-7.1'
Author = 'Ben White'
- Copyright = '(c) 2020. All rights reserved.'
- Description = 'The Optimize-Offline module enables the offline optimizing of Windows 10 image (WIM/ESD) files for optimal runtime environments.'
+ Copyright = '(c) 2021. All rights reserved.'
+ Description = 'The Optimize-Offline module enables the offline optimizing of Windows images (WIM/ESD) files for optimal runtime environments.'
HelpInfoUri = 'https://github.com/DrEmpiricism/Optimize-Offline/blob/master/en-US/Optimize-Offline-help.xml'
PowerShellVersion = '5.1'
DotNetFrameworkVersion = '4.0'
@@ -30,7 +31,7 @@
CmdletsToExport = @()
PrivateData = @{
PSData = @{
- Tags = @('Image Optimization', 'WIM Optimization', 'Offline Windows Image', 'Offline Servicing', 'Offline Imaging', 'WIM', 'SWM', 'ESD', 'Windows 10', 'LTSC', 'Enterprise', '19H1', '19H2', '20H1', '20H2', 'Deployment', 'Debloat', 'DISM', 'PSModule')
+ Tags = @('Image Optimization', 'WIM Optimization', 'Offline Windows Image', 'Offline Servicing', 'Offline Imaging', 'WIM', 'SWM', 'ESD', 'Windows 10', 'Windows 11', 'LTSC', 'Enterprise', '19H1', '19H2', '20H1', '20H2', '21H1', '21H2', 'Deployment', 'Debloat', 'DISM', 'PSModule')
LicenseUri = 'https://github.com/DrEmpiricism/Optimize-Offline/blob/master/LICENSE'
ProjectUri = 'https://github.com/DrEmpiricism/Optimize-Offline'
ReleaseNotes = 'https://github.com/DrEmpiricism/Optimize-Offline/blob/master/ChangeLog.md'
diff --git a/Optimize-Offline.psm1 b/Optimize-Offline.psm1
index fc991f3..772967b 100644
--- a/Optimize-Offline.psm1
+++ b/Optimize-Offline.psm1
@@ -4,12 +4,12 @@
#Requires -Module Dism
<#
===========================================================================
- Created with: SAPIEN Technologies, Inc., PowerShell Studio 2021 v5.8.191
+ Created with: SAPIEN Technologies, Inc., PowerShell Studio 2023 v5.8.218
Created on: 11/20/2019 11:53 AM
Created by: BenTheGreat
Filename: Optimize-Offline.psm1
- Version: 4.0.1.8
- Last updated: 06/22/2021
+ Version: 4.0.1.10
+ Last updated: 02/16/2023
-------------------------------------------------------------------------
Module Name: Optimize-Offline
===========================================================================
@@ -25,23 +25,26 @@ Function Optimize-Offline
(
[Parameter(Mandatory = $true,
ValueFromPipeline = $true,
- HelpMessage = 'The full path to a Windows 10 Installation Media ISO, or a Windows 10 WIM, SWM or ESD file.')]
- [ValidateScript( {
- If ($PSItem.Exists -and $PSItem.Extension -eq '.ISO' -or $PSItem.Extension -eq '.WIM' -or $PSItem.Extension -eq '.SWM' -or $PSItem.Extension -eq '.ESD') { $true }
- Else { Throw ('Invalid source path: "{0}"' -f $PSItem.FullName) }
- })]
- [IO.FileInfo]$SourcePath,
+ HelpMessage = 'The full path to a Windows Installation Media ISO, or a Windows WIM, SWM or ESD file.')]
+ [Object]$SourcePath,
[Parameter(HelpMessage = 'Selectively or automatically deprovisions Windows Apps and removes their associated provisioning packages (.appx or .appxbundle).')]
- [ValidateSet('Select', 'Whitelist', 'All')]
+ [ValidateSet('None', 'Select', 'Whitelist', 'Blacklist', 'All', IgnoreCase = $true)]
[String]$WindowsApps,
[Parameter(HelpMessage = 'Populates and outputs a Gridview list of System Apps for selective removal.')]
- [Switch]$SystemApps,
+ [ValidateSet('None', 'Select', 'Whitelist', 'Blacklist', 'All', IgnoreCase = $true)]
+ [String]$SystemApps,
[Parameter(HelpMessage = 'Populates and outputs a Gridview list of Capability Packages for selective removal.')]
- [Switch]$Capabilities,
+ [ValidateSet('None', 'Select', 'Whitelist', 'Blacklist', 'All', IgnoreCase = $true)]
+ [String]$Capabilities,
[Parameter(HelpMessage = 'Populates and outputs a Gridview list of Windows Cabinet File Packages for selective removal.')]
- [Switch]$Packages,
+ [ValidateSet('None', 'Select', 'Whitelist', 'Blacklist', 'All', IgnoreCase = $true)]
+ [String]$Packages,
+ [ValidateSet('None', 'Select', 'List', 'All', IgnoreCase = $true)]
[Parameter(HelpMessage = 'Populates and outputs a Gridview list of Windows Optional Features for selective disabling and enabling.')]
- [Switch]$Features,
+ [String]$FeaturesToEnable,
+ [ValidateSet('None', 'Select', 'List', 'All', IgnoreCase = $true)]
+ [Parameter(HelpMessage = 'Populates and outputs a Gridview list of Windows Optional Features for selective disabling and enabling.')]
+ [String]$FeaturesToDisable,
[Parameter(HelpMessage = 'Integrates the Developer Mode Feature into the image.')]
[Switch]$DeveloperMode,
[Parameter(HelpMessage = 'Integrates the Microsoft Windows Store and its required dependencies into the image.')]
@@ -50,20 +53,55 @@ Function Optimize-Offline
[Switch]$MicrosoftEdge,
[Parameter(HelpMessage = 'Integrates the traditional Win32 Calculator into the image.')]
[Switch]$Win32Calc,
+ [Parameter(HelpMessage = 'Disable Windows defender while retaining the option to reactivate it.')]
+ [Switch]$DormantDefender,
[Parameter(HelpMessage = 'Integrates the Windows Server Data Deduplication Feature into the image.')]
[Switch]$Dedup,
[Parameter(HelpMessage = 'Integrates the Microsoft Diagnostic and Recovery Toolset (DaRT 10) and Windows 10 Debugging Tools into Windows Setup and Windows Recovery.')]
- [ValidateSet('Setup', 'Recovery')]
+ [ValidateSet('Setup', 'Recovery', IgnoreCase = $true)]
[String[]]$DaRT,
[Parameter(HelpMessage = 'Applies optimized settings to the image registry hives.')]
[Switch]$Registry,
+ [Parameter(HelpMessage = 'Sets the output path')]
+ [String]$OutputPath,
[Parameter(HelpMessage = 'Integrates user-specific content added to the "Content/Additional" directory into the image when enabled within the hashtable.')]
[Hashtable]$Additional = @{ Setup = $false; Wallpaper = $false; SystemLogo = $false; LockScreen = $false; RegistryTemplates = $false; LayoutModification = $false; Unattend = $false; Drivers = $false; NetFx3 = $false },
[Parameter(HelpMessage = 'Performs a clean-up of the Component Store by compressing all superseded components.')]
[Switch]$ComponentCleanup,
[Parameter(HelpMessage = 'Creates a new bootable Windows Installation Media ISO.')]
- [ValidateSet('Prompt', 'No-Prompt')]
- [String]$ISO
+ [ValidateSet('Prompt', 'No-Prompt', IgnoreCase = $true)]
+ [String]$ISO,
+ [Parameter(Mandatory=$false)] [Switch]$populateLists,
+ [Parameter(Mandatory=$false)] [Switch]$populateTemplates,
+ [Parameter(Mandatory=$false)]
+ [ValidateSet('Select', 'None', 'Fast', 'Maximum', 'Solid', IgnoreCase = $true)]
+ [String]$CompressionType,
+ [Parameter(Mandatory=$false)]
+ [Hashtable]$SelectiveRegistry = @{
+ DisableWindowsUpgrade = $false
+ DisableWindowsUpdateMicrosoft = $false
+ DisableDriverUpdate = $false
+ DormantOneDrive = $false
+ Disable3rdPartyApps = $false
+ W11ClassicContextMenu = $false
+ ExplorerUIRibbon = $false
+ ClassicSearchExplorer = $false
+ RemoveTaskbarPinnedIcons = $false
+ DisableTeamsApp = $false
+ DisableVirtualizationSecurity = $false
+ RunAsTiContextMenu = $false
+ AmoledBlackTheme = $false
+ },
+ [Parameter(HelpMessage = 'Shutdown PC on script completion')]
+ [Switch]$ShutDownOnComplete = $false,
+ [Parameter(HelpMessage = 'Removal of windows services.')]
+ [ValidateSet('None', 'List', 'Advanced', 'Select', IgnoreCase = $true)]
+ [String]$Services,
+ [Parameter(HelpMessage = 'Set USB booting support')]
+ [ValidateSet('Off', 'Legacy', 'UEFI', IgnoreCase = $true)]
+ [String]$FlashToUSB = "Off",
+ [Parameter(Mandatory = $false, HelpMessage = 'Set USB Drive to flash the ISO')]
+ [Int]$FlashUSBDriveNumber = -1
)
Begin
@@ -73,6 +111,7 @@ Function Optimize-Offline
$ErrorActionPreference = 'SilentlyContinue'
$Global:ProgressPreference = 'SilentlyContinue'
$Host.UI.RawUI.BackgroundColor = 'Black'
+ If ($PSVersionTable.PSVersion.Major -eq 7) { $PSStyle.OutputRendering = 'Host' }
Clear-Host
Test-Requirements
If (Get-WindowsImage -Mounted) { Dismount-Images; Clear-Host }
@@ -100,12 +139,43 @@ Function Optimize-Offline
#endregion Create the Working File Structure
#region Media Export
+ $SourcePath = [IO.FileInfo]$SourcePath
+ $allowedExtensions = @('.iso', '.wim', '.swm', '.esd')
+ If (-not $SourcePath.Exists -or [String]$SourcePath.Extension.ToLower() -notin $allowedExtensions) {
+ Add-Type -AssemblyName System.Windows.Forms
+
+ $FileBrowser = New-Object System.Windows.Forms.OpenFileDialog -Property @{
+ InitialDirectory = [Environment]::GetFolderPath('Desktop')
+ Filter = 'All allowed types|*.wim;*.swm;*.iso;*.esd;*.WIM;*.SWM;*.ISO;*.ESD'
+ Multiselect = $false
+ AddExtension = $true
+ CheckPathExists = $true
+ }
+
+ $null = $FileBrowser.ShowDialog()
+
+ if($FileBrowser.FileName){
+ $SourcePath = Get-Item -Path $FileBrowser.FileName
+ }
+ }
+
+ if(-not $SourcePath.Exists) { Throw ('Invalid source path: "{0}"' -f [String]$SourcePath) }
+
Switch ($SourcePath.Extension)
{
'.ISO'
{
- $ISOMount = (Mount-DiskImage -ImagePath $SourcePath.FullName -StorageType ISO -PassThru | Get-Volume).DriveLetter + ':'
- [Void](Get-PSDrive)
+ Try{
+ $DrivesBefore = [System.Collections.ArrayList]@()
+ Get-PSDrive -PSProvider FileSystem | Where-Object {$_.Free -eq 0} | ForEach-Object -Process {
+ [Void]$DrivesBefore.Add($PSItem.Name)
+ }
+ [Void](Mount-DiskImage -ImagePath $SourcePath.FullName -StorageType ISO)
+ $ISOMount = "$((Get-PSDrive -PSProvider FileSystem | Where-Object {$_.Free -eq 0 -and $_.Name -notin $DrivesBefore}).Name):"
+ } Catch {
+ $ISOMount = ""
+ }
+
If (!(Get-ChildItem -Path (GetPath -Path $ISOMount -Child sources) -Filter install* -File))
{
$PSCmdlet.WriteWarning($OptimizeData.InvalidWindowsInstallMedia -f $SourcePath.Name)
@@ -124,6 +194,10 @@ Function Optimize-Offline
ForEach ($Item In Get-ChildItem -Path $ISOMount -Recurse)
{
$ISOExport = $ISOMedia.FullName + $Item.FullName.Replace($ISOMount, $null)
+ $destPathDir = $(Split-Path $ISOExport)
+ If (!(Test-Path -Path $destPathDir)) {
+ [Void](New-Item -path $(Split-Path $ISOExport) -ItemType Directory -Force)
+ }
Copy-Item -Path $Item.FullName -Destination $ISOExport
}
Do
@@ -194,13 +268,25 @@ Function Optimize-Offline
}
#endregion Media Export
+ #region USB device selection
+ $null = $USBDrive
+ If ($FlashToUSB.ToLower().Trim() -ne "off" -and !$populateLists -and !$populateTemplates) {
+ $USBDrive = Get-Disk | Where-Object BusType -eq USB
+ If($FlashUSBDriveNumber -ge 0) {
+ $USBDrive = $USBDrive | Where-Object Number -eq $FlashUSBDriveNumber
+ } Else {
+ $USBDrive = $USBDrive | Out-GridView -Title 'Select USB Drive to Format' -OutputMode Single
+ }
+ }
+ #endregion USB device selection
+
#region Image and Metadata Validation
If ((Get-WindowsImage -ImagePath $InstallWim -ScratchDirectory $ScratchFolder -LogPath $DISMLog -LogLevel 1).Count -gt 1)
{
Do
{
$Host.UI.RawUI.WindowTitle = $OptimizeData.SelectWindowsEdition
- $EditionList = Get-WindowsImage -ImagePath $InstallWim -ScratchDirectory $ScratchFolder -LogPath $DISMLog -LogLevel 1 | Select-Object -Property @{ Label = 'Index'; Expression = { ($PSItem.ImageIndex) } }, @{ Label = 'Name'; Expression = { ($PSItem.ImageName) } }, @{ Label = 'Size (GB)'; Expression = { '{0:N2}' -f ($PSItem.ImageSize / 1GB) } } | Out-GridView -Title "Select the Windows 10 Edition to Optimize." -OutputMode Single
+ $EditionList = Get-WindowsImage -ImagePath $InstallWim -ScratchDirectory $ScratchFolder -LogPath $DISMLog -LogLevel 1 | Select-Object -Property @{ Label = 'Index'; Expression = { ($PSItem.ImageIndex) } }, @{ Label = 'Name'; Expression = { ($PSItem.ImageName) } }, @{ Label = 'Size (GB)'; Expression = { '{0:N2}' -f ($PSItem.ImageSize / 1GB) } } | Out-GridView -Title $OptimizeData.SelectWindowsEdition -OutputMode Single
}
While ($EditionList.Length -eq 0)
$ImageIndex = $EditionList.Index
@@ -211,6 +297,8 @@ Function Optimize-Offline
{
$Host.UI.RawUI.WindowTitle = "Validating Image Metadata."
$InstallInfo = $InstallWim | Get-ImageData -Index $ImageIndex -ErrorAction Stop
+ $Global:InstallInfo = $InstallInfo
+ $InstallInfo | ConvertTo-Json | Out-File -FilePath "$($OptimizeOffline.GUI.Main)\image_info.json" -Encoding UTF8 -Force -ErrorAction Ignore
}
Catch
{
@@ -219,6 +307,30 @@ Function Optimize-Offline
Break
}
+ If($OutputPath.ToLower().Trim() -eq 'select'){
+ Add-Type -AssemblyName System.Windows.Forms
+ If($SourcePath.Extension.ToLower() -eq '.iso'){
+ $SaveFileDialog = New-Object System.Windows.Forms.SaveFileDialog
+ $SaveFileDialog.InitialDirectory = [Environment]::GetFolderPath('Desktop')
+ $SaveFileDialog.FileName = ($($InstallInfo.Edition).Replace(' ', '') + "_$($InstallInfo.Build)")
+ $SaveFileDialog.Filter = "ISO files (*.iso)| *.iso"
+ If($SaveFileDialog.ShowDialog() -eq 'Ok'){
+ $OutputPath = $SaveFileDialog.FileName
+ }
+ } Else {
+ $FolderBrowserDialog = New-Object System.Windows.Forms.FolderBrowserDialog
+ $null = $FolderBrowserDialog.ShowDialog()
+ $OutputPath = $FolderBrowserDialog.SelectedPath
+ }
+ }
+
+ If ($InstallInfo.Build -ge 22000 -and -not $BootWim -and $ISOMedia.Exists)
+ {
+ Try { $BootWim = Get-ChildItem -Path (GetPath -Path $ISOMedia.FullName -Child sources) -Filter boot.* -File | Move-Item -Destination $ImageFolder -PassThru -ErrorAction Stop | Set-ItemProperty -Name IsReadOnly -Value $false -PassThru | Get-Item | Select-Object -ExpandProperty FullName }
+ Catch [Management.Automation.ItemNotFoundException] { Break }
+ $DynamicParams.BootImage = $true
+ }
+
If ($InstallInfo.VersionTable.Major -ne 10)
{
$PSCmdlet.WriteWarning($OptimizeData.UnsupportedImageVersion -f $InstallInfo.Version)
@@ -233,19 +345,19 @@ Function Optimize-Offline
Break
}
- If ($InstallInfo.InstallationType.Contains('Server') -or $InstallInfo.InstallationType.Contains('WindowsPE'))
+ If ($InstallInfo.InstallationType.Contains('WindowsPE'))
{
$PSCmdlet.WriteWarning($OptimizeData.UnsupportedImageType -f $InstallInfo.InstallationType)
$TempDirectory | Purge
Break
}
- If ($InstallInfo.Build -ge '17134' -and $InstallInfo.Build -le '19041')
+ If ($InstallInfo.Build -ge '17134')
{
If ($InstallInfo.Name -like "*LTSC*")
{
$DynamicParams.LTSC = $true
- If ($WindowsApps) { Remove-Variable -Name WindowsApps }
+ If ($WindowsApps -notin @('None')) { Remove-Variable -Name WindowsApps }
If ($Win32Calc.IsPresent) { $Win32Calc = ![Switch]::Present }
}
Else
@@ -366,9 +478,16 @@ Function Optimize-Offline
If ($DynamicParams.BootImage)
{
+ $BootWimImageIndex = 0
+ $BootWimImages = Get-WindowsImage -ImagePath $BootWim -ScratchDirectory $ScratchFolder -LogPath $DISMLog -LogLevel 1
+ Foreach($Image in $BootWimImages) {
+ If ($Image.ImageDescription -like "Microsoft Windows Setup*") {
+ $BootWimImageIndex = $Image.ImageIndex
+ }
+ }
Try
{
- $BootInfo = $BootWim | Get-ImageData -Index 2 -ErrorAction Stop
+ $BootInfo = $BootWim | Get-ImageData -Index $BootWimImageIndex -ErrorAction Stop
}
Catch
{
@@ -381,7 +500,7 @@ Function Optimize-Offline
$MountBootParams = @{
Path = $BootMount
ImagePath = $BootWim
- Index = 2
+ Index = $BootWimImageIndex
CheckIntegrity = $true
ScratchDirectory = $ScratchFolder
LogPath = $DISMLog
@@ -444,333 +563,656 @@ Function Optimize-Offline
}
#endregion Image Preparation
- #region Provisioned App Package Removal
- If ($WindowsApps -and (Get-AppxProvisionedPackage -Path $InstallMount -ScratchDirectory $ScratchFolder -LogPath $DISMLog -LogLevel 1).Count -gt 0)
- {
- $Host.UI.RawUI.WindowTitle = "Remove Provisioned App Packages."
- $AppxPackages = Get-AppxProvisionedPackage -Path $InstallMount -ScratchDirectory $ScratchFolder -LogPath $DISMLog -LogLevel 1 | Select-Object -Property DisplayName, PackageName | Sort-Object -Property DisplayName
- If ($InstallInfo.Build -eq '19041')
- {
- $AppxPackages = $AppxPackages | ForEach-Object -Process {
- $DisplayName = $PSItem.DisplayName; $PackageName = $PSItem.PackageName
- If ($DisplayName -eq 'Microsoft.549981C3F5F10') { $DisplayName = 'CortanaApp.View.App' }
- [PSCustomObject]@{ DisplayName = $DisplayName; PackageName = $PackageName }
+
+
+ If ($populateLists -or $populateTemplates) {
+
+ Try {
+ $Items = [System.Collections.ArrayList]@( )
+ $ItemsGUI = [System.Collections.ArrayList]@( )
+ Get-AppxPackages -Path $InstallMount -ScratchDirectory $ScratchFolder -LogPath $DISMLog | ForEach-Object -Process {
+ [Void]$Items.Add([String]$PSItem.DisplayName)
+ [Void]$ItemsGUI.Add(@{
+ PackageName = $PSItem.PackageName
+ DisplayName = $PSItem.DisplayName
+ Selected = $false
+ })
+ }
+ ## Populate WindowsApps template
+ Log "$($OptimizeData.Populating) $($OptimizeOffline.Lists.WindowsAppsTemplate)"
+ [ordered]@{
+ DisplayName = $Items
+ } | ConvertTo-Json | Out-File -FilePath $OptimizeOffline.Lists.WindowsAppsTemplate -Encoding UTF8 -Force -ErrorAction Ignore
+ $ItemsGUI | ConvertTo-Json | Out-File -FilePath $OptimizeOffline.GUI.RemovalTemplates.WindowsApps -Encoding UTF8 -Force -ErrorAction Ignore
+ Start-Sleep 1
+ If ($populateLists -and $WindowsApps -in @('Whitelist', 'Blacklist')) {
+ ## Populate WindowsApps selected type of list
+ Log "$($OptimizeData.Populating) $($OptimizeOffline.Lists.WindowsAppsList)"
+ Start-Sleep 1
+ $Items = $Items | Out-GridView -Title "Select windows apps to save to the $($WindowsApps)" -PassThru
+ If($Items -isnot [array]) {
+ $Items = @($Items)
+ }
+ [ordered]@{
+ DisplayName = $Items
+ } | ConvertTo-Json | Out-File -FilePath $OptimizeOffline.Lists.WindowsAppsList -Encoding UTF8 -Force -ErrorAction Ignore
+ }
+
+ $Items = [System.Collections.ArrayList]@( )
+ $ItemsGUI = [System.Collections.ArrayList]@( )
+ Get-SystemPackages | ForEach-Object -Process {
+ [Void]$Items.Add([String]$PSItem.DisplayName)
+ [Void]$ItemsGUI.Add(@{
+ DisplayName = $PSItem.DisplayName
+ Selected = $false
+ })
+ }
+ ## Populate SystemApps template
+ Log "$($OptimizeData.Populating) $($OptimizeOffline.Lists.SystemAppsTemplate)"
+ [ordered]@{
+ DisplayName = $Items
+ } | ConvertTo-Json | Out-File -FilePath $OptimizeOffline.Lists.SystemAppsTemplate -Encoding UTF8 -Force -ErrorAction Ignore
+ $ItemsGUI | ConvertTo-Json | Out-File -FilePath $OptimizeOffline.GUI.RemovalTemplates.SystemApps -Encoding UTF8 -Force -ErrorAction Ignore
+ Start-Sleep 1
+ If ($populateLists -and $SystemApps -in @('Whitelist', 'Blacklist')) {
+ ## Populate SystemApps selected type of list
+ Log "$($OptimizeData.Populating) $($OptimizeOffline.Lists.SystemAppsList)"
+ Start-Sleep 1
+ $Items = $Items | Out-GridView -Title "Select system apps to save to the $($SystemApps)" -PassThru
+ If($Items -isnot [array]) {
+ $Items = @($Items)
+ }
+ [ordered]@{
+ DisplayName = $Items
+ } | ConvertTo-Json | Out-File -FilePath $OptimizeOffline.Lists.SystemAppsList -Encoding UTF8 -Force -ErrorAction Ignore
+ }
+
+ $Items = [System.Collections.ArrayList]@( )
+ $ItemsGUI = [System.Collections.ArrayList]@( )
+ Get-CapabilityPackages -Path $InstallMount -ScratchDirectory $ScratchFolder -LogPath $DISMLog | ForEach-Object -Process {
+ [Void]$Items.Add([String]$PSItem.Name)
+ [Void]$ItemsGUI.Add(@{
+ Name = $PSItem.Name
+ Selected = $false
+ })
+ }
+ ## Populate capabilities template
+ Log "$($OptimizeData.Populating) $($OptimizeOffline.Lists.CapabilitiesTemplate)"
+ [ordered]@{
+ Name = $Items
+ } | ConvertTo-Json | Out-File -FilePath $OptimizeOffline.Lists.CapabilitiesTemplate -Encoding UTF8 -Force -ErrorAction Ignore
+ $ItemsGUI | ConvertTo-Json | Out-File -FilePath $OptimizeOffline.GUI.RemovalTemplates.Capabilities -Encoding UTF8 -Force -ErrorAction Ignore
+ Start-Sleep 1
+ If ($populateLists -and $Capabilities -in @('Whitelist', 'Blacklist')) {
+ ## Populate Capabilities selected type of list
+ Log "$($OptimizeData.Populating) $($OptimizeOffline.Lists.CapabilitiesList)"
+ Start-Sleep 1
+ $Items = $Items | Out-GridView -Title "Select capabilities to save to the $($Capabilities)" -PassThru
+ If($Items -isnot [array]) {
+ $Items = @($Items)
+ }
+ [ordered]@{
+ Name = $Items
+ } | ConvertTo-Json | Out-File -FilePath $OptimizeOffline.Lists.CapabilitiesList -Encoding UTF8 -Force -ErrorAction Ignore
+ }
+
+ $Items = [System.Collections.ArrayList]@( )
+ $ItemsGUI = [System.Collections.ArrayList]@( )
+ Get-OtherWindowsPackages -Path $InstallMount -ScratchDirectory $ScratchFolder -LogPath $DISMLog | ForEach-Object -Process {
+ [Void]$Items.Add([String]$PSItem.PackageName)
+ [Void]$ItemsGUI.Add(@{
+ PackageName = $PSItem.PackageName
+ Selected = $false
+ })
+ }
+ # Populate Packages template
+ Log "$($OptimizeData.Populating) $($OptimizeOffline.Lists.PackagesTemplate)"
+ [ordered]@{
+ PackageName = $Items
+ } | ConvertTo-Json | Out-File -FilePath $OptimizeOffline.Lists.PackagesTemplate -Encoding UTF8 -Force -ErrorAction Ignore
+ $ItemsGUI | ConvertTo-Json | Out-File -FilePath $OptimizeOffline.GUI.RemovalTemplates.Packages -Encoding UTF8 -Force -ErrorAction Ignore
+ Start-Sleep 1
+ If ($populateLists -and $Packages -in @('Whitelist', 'Blacklist')) {
+ ## Populate Packages selected type of list
+ Log "$($OptimizeData.Populating) $($OptimizeOffline.Lists.PackagesList)"
+ Start-Sleep 1
+ $Items = $Items | Out-GridView -Title "Select packages to save to the $($Packages)" -PassThru
+ If($Items -isnot [array]) {
+ $Items = @($Items)
+ }
+ [ordered]@{
+ PackageName = $Items
+ } | ConvertTo-Json | Out-File -FilePath $OptimizeOffline.Lists.PackagesList -Encoding UTF8 -Force -ErrorAction Ignore
+ }
+
+ $Items = [System.Collections.ArrayList]@( )
+ $ItemsGUI = [System.Collections.ArrayList]@( )
+ Get-OptionalEnabledFeatures -Path $InstallMount -ScratchDirectory $ScratchFolder -LogPath $DISMLog | ForEach-Object -Process {
+ [Void]$Items.Add([String]$PSItem.FeatureName)
+ [Void]$ItemsGUI.Add(@{
+ FeatureName = $PSItem.FeatureName
+ States = @("Enabled", "Disabled")
+ State = "Enabled"
+ OriginalState = "Enabled"
+ })
+ }
+ ## Populate FeaturesToDisable template
+ Log "$($OptimizeData.Populating) $($OptimizeOffline.Lists.FeaturesToDisableTemplate)"
+ [ordered]@{
+ FeatureName = $Items
+ } | ConvertTo-Json | Out-File -FilePath $OptimizeOffline.Lists.FeaturesToDisableTemplate -Encoding UTF8 -Force -ErrorAction Ignore
+ Start-Sleep 1
+ If ($populateLists -and $FeaturesToDisable -eq 'List') {
+ ## Populate FeaturesToDisable list
+ Log "$($OptimizeData.Populating) $($OptimizeOffline.Lists.FeaturesToDisableList)"
+ Start-Sleep 1
+ $Items = $Items | Out-GridView -Title "Select features to disable for saving to the FeaturesToDisable list" -PassThru
+ If($Items -isnot [array]) {
+ $Items = @($Items)
+ }
+ [ordered]@{
+ FeatureName = $Items
+ } | ConvertTo-Json | Out-File -FilePath $OptimizeOffline.Lists.FeaturesToDisableList -Encoding UTF8 -Force -ErrorAction Ignore
+ }
+
+ $Items = [System.Collections.ArrayList]@( )
+ Get-OptionalDisabledFeatures -Path $InstallMount -ScratchDirectory $ScratchFolder -LogPath $DISMLog | ForEach-Object -Process {
+ [Void]$Items.Add([String]$PSItem.FeatureName)
+ [Void]$ItemsGUI.Add(@{
+ FeatureName = $PSItem.FeatureName
+ States = @("Enabled", "Disabled")
+ State = "Disabled"
+ OriginalState = "Disabled"
+ })
+ }
+ ## Populate FeaturesToEnable template
+ Log "$($OptimizeData.Populating) $($OptimizeOffline.Lists.FeaturesToEnableTemplate)"
+ [ordered]@{
+ FeatureName = $Items
+ } | ConvertTo-Json | Out-File -FilePath $OptimizeOffline.Lists.FeaturesToEnableTemplate -Encoding UTF8 -Force -ErrorAction Ignore
+ Start-Sleep 1
+ If ($populateLists -and $FeaturesToEnable -eq 'List') {
+ ## Populate FeaturesToEnable list
+ Log "$($OptimizeData.Populating) $($OptimizeOffline.Lists.FeaturesToEnableList)"
+ Start-Sleep 1
+ $Items = $Items | Out-GridView -Title "Select features to disable for saving to the FeaturesToEnable list" -PassThru
+ If($Items -isnot [array]) {
+ $Items = @($Items)
+ }
+ [ordered]@{
+ FeatureName = $Items
+ } | ConvertTo-Json | Out-File -FilePath $OptimizeOffline.Lists.FeaturesToEnableList -Encoding UTF8 -Force -ErrorAction Ignore
}
+ $ItemsGUI | ConvertTo-Json | Out-File -FilePath $OptimizeOffline.GUI.RemovalTemplates.Features -Encoding UTF8 -Force -ErrorAction Ignore
+
+ RegHives -Load
+ $Items = Get-ImageServices
+ $ItemsGUI = [System.Collections.ArrayList]@( )
+ $Items | ForEach-Object -Process {
+ [Void]$ItemsGUI.Add(@{
+ Name = [String]$PSItem.name
+ Description = $PSItem.description
+ OriginalStart = $PSItem.startLabel
+ Start = $PSItem.startLabel
+ Starts = $OptimizeOffline.ServicesStartLabels
+ })
+ }
+ $JsonInfo = $OptimizeOffline.ServicesStartLabels | ForEach-Object -Process {
+ "$($OptimizeOffline.ServicesStartLabels.IndexOf($_)) = $_"
+ }
+ ## Populate Services template
+ Log "$($OptimizeData.Populating) $($OptimizeOffline.Lists.ServicesTemplate)"
+ [ordered]@{
+ __Info = $JsonInfo
+ Services = $Items
+ } | ConvertTo-Json | Out-File -FilePath $OptimizeOffline.Lists.ServicesTemplate -Encoding UTF8 -Force -ErrorAction Ignore
+ $ItemsGUI | ConvertTo-Json | Out-File -FilePath $OptimizeOffline.GUI.RemovalTemplates.Services -Encoding UTF8 -Force -ErrorAction Ignore
+ If ($populateLists -and $Services -in @('List', 'Advanced')) {
+ Log "$($OptimizeData.Populating) $($OptimizeOffline.Lists."Services$($Services)")"
+ Start-Sleep 1
+ $Items = $Items | Out-GridView -Title "Select services save to the list" -PassThru
+ If($Items -isnot [array]) {
+ $Items = @($Items)
+ }
+ $JsonData = [ordered]@{
+ __Info = $JsonInfo
+ Services = $Items
+ }
+ if($Services -eq 'List'){
+ $JsonData.Services = [System.Collections.ArrayList]@()
+ foreach ($Item in $Items) {
+ [Void]$JsonData.Services.Add($Item.name)
+ }
+ }
+ $JsonData | ConvertTo-Json | Out-File -FilePath $OptimizeOffline.Lists.Services$($Services) -Encoding UTF8 -Force -ErrorAction Ignore
+ }
+ RegHives -Unload
+
+ } Catch {
+ Log $Error[0]
+ } Finally {
+ Dismount-Images
+ @($TempDirectory, $DISMLog, $(GetPath -Path $Env:SystemRoot -Child 'Logs\DISM\dism.log')) | Purge -ErrorAction Ignore
}
- $RemovedAppxPackages = [Collections.Hashtable]::New()
- Switch ($PSBoundParameters.WindowsApps)
+ Return
+ }
+
+
+ #region Provisioned App Package Removal
+ $RemovedPackages = [Collections.Hashtable]::New();
+ $AppxPackages = Get-AppxPackages -Path $InstallMount -ScratchDirectory $ScratchFolder -LogPath $DISMLog
+ If ($WindowsApps -in $AllowedRemovalOptions)
+ {
+ Try
{
- 'Select'
+ $Host.UI.RawUI.WindowTitle = "Remove Provisioned App Packages."
+
+ $appsToRemove = [System.Collections.ArrayList]@()
+
+ $RemovedAppxPackages = [Collections.Hashtable]::New()
+ Switch ($PSBoundParameters.WindowsApps)
{
- Try
- {
- $AppxPackages | Out-GridView -Title "Select the Provisioned App Packages to Remove." -PassThru | ForEach-Object -Process {
- $RemoveAppxParams = @{
- Path = $InstallMount
- PackageName = $PSItem.PackageName
- ScratchDirectory = $ScratchFolder
- LogPath = $DISMLog
- LogLevel = 1
- ErrorAction = 'Stop'
- }
- Log ($OptimizeData.RemovingWindowsApp -f $PSItem.DisplayName)
- [Void](Remove-AppxProvisionedPackage @RemoveAppxParams)
- $RemovedAppxPackages.Add($PSItem.DisplayName, $PSItem.PackageName)
- }
- $DynamicParams.WindowsApps = $true
- }
- Catch
+ 'Select'
{
- Log $OptimizeData.FailedRemovingWindowsApps -Type Error -ErrorRecord $Error[0]
- Stop-Optimize
+ $appsToRemove = $AppxPackages | Out-GridView -Title "Select the Provisioned App Packages to Remove." -PassThru
+ Break
}
- Break
- }
- 'Whitelist'
- {
- If (Test-Path -Path $OptimizeOffline.AppxWhitelist)
+ 'Whitelist'
{
- Try
+ If (Test-Path -Path $OptimizeOffline.Lists.WindowsAppsList)
{
- If ($InstallInfo.Build -eq '19041')
- {
- $WhitelistJSON = Get-Content -Path $OptimizeOffline.AppxWhitelist -Raw -ErrorAction Stop
- If ($WhitelistJSON.Contains('Microsoft.549981C3F5F10')) { $WhitelistJSON = $WhitelistJSON.Replace('Microsoft.549981C3F5F10', 'CortanaApp.View.App') }
- $WhitelistJSON = $WhitelistJSON | ConvertFrom-Json -ErrorAction Stop
- }
- Else
- {
- $WhitelistJSON = Get-Content -Path $OptimizeOffline.AppxWhitelist -Raw -ErrorAction Stop | ConvertFrom-Json -ErrorAction Stop
- }
+ $AppsJson = Get-Content -Path $OptimizeOffline.Lists.WindowsAppsList -Raw -ErrorAction Stop | ConvertFrom-Json -ErrorAction Stop | Select-Object -ExpandProperty DisplayName
+
$AppxPackages | ForEach-Object -Process {
- If ($PSItem.DisplayName -notin $WhitelistJSON.DisplayName)
- {
- $RemoveAppxParams = @{
- Path = $InstallMount
- PackageName = $PSItem.PackageName
- ScratchDirectory = $ScratchFolder
- LogPath = $DISMLog
- LogLevel = 1
- ErrorAction = 'Stop'
+ $ToRemove = $true
+ Foreach($App in $AppsJson){
+ If ($PSItem.DisplayName -eq $App -or ($App -Match "\*" -and $PSItem.DisplayName -like $App))
+ {
+ $ToRemove = $false
+ Break
}
- Log ($OptimizeData.RemovingWindowsApp -f $PSItem.DisplayName)
- [Void](Remove-AppxProvisionedPackage @RemoveAppxParams)
- $RemovedAppxPackages.Add($PSItem.DisplayName, $PSItem.PackageName)
+ }
+ If($ToRemove){
+ [void]$appsToRemove.Add($PSItem)
}
}
- $DynamicParams.WindowsApps = $true
- }
- Catch
- {
- Log $OptimizeData.FailedRemovingWindowsApps -Type Error -ErrorRecord $Error[0]
- Stop-Optimize
}
+ Break
}
- Break
- }
- 'All'
- {
- Try
+ 'Blacklist'
{
- $AppxPackages | ForEach-Object -Process {
- $RemoveAppxParams = @{
- Path = $InstallMount
- PackageName = $PSItem.PackageName
- ScratchDirectory = $ScratchFolder
- LogPath = $DISMLog
- LogLevel = 1
- ErrorAction = 'Stop'
+ If (Test-Path -Path $OptimizeOffline.Lists.WindowsAppsList)
+ {
+ $AppsJson = Get-Content -Path $OptimizeOffline.Lists.WindowsAppsList -Raw -ErrorAction Stop | ConvertFrom-Json -ErrorAction Stop | Select-Object -ExpandProperty DisplayName
+
+ $AppxPackages | ForEach-Object -Process {
+ Foreach($App in $AppsJson){
+ If ($PSItem.DisplayName -eq $App -or ($App -Match "\*" -and $PSItem.DisplayName -like $App))
+ {
+ [void]$appsToRemove.Add($PSItem)
+ Break
+ }
+ }
}
- Log ($OptimizeData.RemovingWindowsApp -f $PSItem.DisplayName)
- [Void](Remove-AppxProvisionedPackage @RemoveAppxParams)
- $RemovedAppxPackages.Add($PSItem.DisplayName, $PSItem.PackageName)
}
- $DynamicParams.WindowsApps = $true
+ Break
}
- Catch
+ 'All'
{
- Log $OptimizeData.FailedRemovingWindowsApps -Type Error -ErrorRecord $Error[0]
- Stop-Optimize
+ $appsToRemove = $AppxPackages
+ Break
}
- Break
}
+ $appsToRemove | ForEach-Object -Process {
+ $RemoveAppxParams = @{
+ Path = $InstallMount
+ PackageName = $PSItem.PackageName
+ ScratchDirectory = $ScratchFolder
+ LogPath = $DISMLog
+ LogLevel = 1
+ ErrorAction = 'Stop'
+ }
+ Log ($OptimizeData.RemovingWindowsApp -f $PSItem.DisplayName)
+ If ($PSItem.DisplayName -notin @("Microsoft.SecHealthUI") -or [System.Environment]::OSVersion.Version.Build -lt '22000'){
+ [Void](Remove-AppxProvisionedPackage @RemoveAppxParams)
+ }
+ $RemovedAppxPackages.Add($PSItem.DisplayName, $PSItem.PackageName)
+ $RemovedPackages.Add($PSItem.DisplayName, $PSItem.PackageName)
+ }
+ $DynamicParams.WindowsApps = $($appsToRemove.Count -gt 0)
+ }
+ Catch
+ {
+ Log $OptimizeData.FailedRemovingWindowsApps -Type Error -ErrorRecord $Error[0]
+ Stop-Optimize
}
$Host.UI.RawUI.WindowTitle = $null; Clear-Host
}
+ $AppxPackages = Get-AppxPackages -Path $InstallMount -ScratchDirectory $ScratchFolder -LogPath $DISMLog
#endregion Provisioned App Package Removal
#region System App Removal
- If ($SystemApps.IsPresent)
+ If ($SystemApps -in $AllowedRemovalOptions)
{
Clear-Host
$Host.UI.RawUI.WindowTitle = "Remove System Apps."
- $PSCmdlet.WriteWarning($OptimizeData.SystemAppsWarning)
+
Start-Sleep 5
+
$InboxAppsKey = "HKLM:\WIM_HKLM_SOFTWARE\Microsoft\Windows\CurrentVersion\Appx\AppxAllUserStore\InboxApplications"
+
+ $InboxAppsPackages = Get-SystemPackages
+
RegHives -Load
- $InboxAppsPackages = Get-ChildItem -Path $InboxAppsKey -Name | ForEach-Object -Process {
- $DisplayName = $PSItem.Split('_')[0]; $PackageName = $PSItem
- If ($DisplayName -like '1527c705-839a-4832-9118-54d4Bd6a0c89') { $DisplayName = 'Microsoft.Windows.FilePicker' }
- If ($DisplayName -like 'c5e2524a-ea46-4f67-841f-6a9465d9d515') { $DisplayName = 'Microsoft.Windows.FileExplorer' }
- If ($DisplayName -like 'E2A4F912-2574-4A75-9BB0-0D023378592B') { $DisplayName = 'Microsoft.Windows.AppResolverUX' }
- If ($DisplayName -like 'F46D4000-FD22-4DB4-AC8E-4E1DDDE828FE') { $DisplayName = 'Microsoft.Windows.AddSuggestedFoldersToLibarayDialog' }
- [PSCustomObject]@{ DisplayName = $DisplayName; PackageName = $PackageName }
- } | Sort-Object -Property DisplayName | Out-GridView -Title "Remove System Apps." -PassThru
+
If ($InboxAppsPackages)
{
- Clear-Host
$RemovedSystemApps = [Collections.Hashtable]::New()
- Try
- {
- $InboxAppsPackages | ForEach-Object -Process {
+
+ $packagesToRemove = [System.Collections.ArrayList]@()
+
+ Try {
+
+ Switch ($PSBoundParameters.SystemApps)
+ {
+ 'Select'
+ {
+
+ $PSCmdlet.WriteWarning($OptimizeData.SystemAppsWarning)
+
+ $packagesToRemove = $InboxAppsPackages | Out-GridView -Title "Remove System Apps." -PassThru
+
+ Break
+ }
+ 'Whitelist'
+ {
+ If (Test-Path -Path $OptimizeOffline.Lists.SystemAppsList)
+ {
+ $SystemAppsJson = Get-Content -Path $OptimizeOffline.Lists.SystemAppsList -Raw -ErrorAction Stop | ConvertFrom-Json -ErrorAction Stop | Select-Object -ExpandProperty DisplayName
+ $InboxAppsPackages | ForEach-Object -Process {
+ $ToRemove = $true
+ Foreach($SystemApp in $SystemAppsJson){
+ If ($PSItem.DisplayName -eq $SystemApp -or ($SystemApp -Match "\*" -and $PSItem.DisplayName -like $SystemApp))
+ {
+ $ToRemove = $false
+ Break
+ }
+ }
+ If($ToRemove){
+ [void]$packagesToRemove.Add($PSItem)
+ }
+ }
+ }
+ Break
+ }
+ 'Blacklist'
+ {
+ If (Test-Path -Path $OptimizeOffline.Lists.SystemAppsList)
+ {
+ $SystemAppsJson = Get-Content -Path $OptimizeOffline.Lists.SystemAppsList -Raw -ErrorAction Stop | ConvertFrom-Json -ErrorAction Stop | Select-Object -ExpandProperty DisplayName
+ $InboxAppsPackages | ForEach-Object -Process {
+ Foreach($SystemApp in $SystemAppsJson){
+ If ($PSItem.DisplayName -eq $SystemApp -or ($SystemApp -Match "\*" -and $PSItem.DisplayName -like $SystemApp))
+ {
+ [void]$packagesToRemove.Add($PSItem)
+ Break
+ }
+ }
+ }
+ }
+ Break
+ }
+ 'All'
+ {
+ $packagesToRemove = $InboxAppsPackages
+ }
+ }
+
+ $packagesToRemove | ForEach-Object -Process {
$PackageKey = (GetPath -Path $InboxAppsKey -Child $PSItem.PackageName) -replace 'HKLM:', 'HKLM'
Log ($OptimizeData.RemovingSystemApp -f $PSItem.DisplayName)
$RET = StartExe $REG -Arguments ('DELETE "{0}" /F' -f $PackageKey) -ErrorAction Stop
If ($RET -eq 1) { Log ($OptimizeData.FailedRemovingSystemApp -f $PSItem.DisplayName) -Type Error; Continue }
$RemovedSystemApps.Add($PSItem.DisplayName, $PSItem.PackageName)
- Start-Sleep 2
+ $RemovedPackages.Add($PSItem.DisplayName, $PSItem.PackageName)
+ Start-Sleep 1
}
- $DynamicParams.SystemApps = $true
- }
- Catch
- {
+
+ $DynamicParams.SystemApps = $($packagesToRemove.Count -gt 0)
+ } Catch {
Log $OptimizeData.FailedRemovingSystemApps -Type Error -ErrorRecord $Error[0]
Stop-Optimize
}
- Finally
- {
- RegHives -Unload
- }
}
+ RegHives -Unload
$Host.UI.RawUI.WindowTitle = $null; Clear-Host
}
#endregion System App Removal
+ $DynamicParams.RemovedPackages = $RemovedPackages;
+
#region Removed Package Clean-up
- If ($DynamicParams.WindowsApps -or $DynamicParams.SystemApps)
+ If ($DynamicParams.WindowsApps)
{
- Log $OptimizeData.RemovedPackageCleanup
- If ($DynamicParams.WindowsApps)
+ If ($InstallInfo.Build -lt '19041')
{
- If ($InstallInfo.Build -lt '19041')
- {
- If ((Get-AppxProvisionedPackage -Path $InstallMount -ScratchDirectory $ScratchFolder -LogPath $DISMLog -LogLevel 1).Count -eq 0) { Get-ChildItem -Path (GetPath -Path $InstallMount -Child 'Program Files\WindowsApps') -Force | Purge -Force }
- Else { Get-ChildItem -Path (GetPath -Path $InstallMount -Child 'Program Files\WindowsApps') -Force | Where-Object -Property Name -In $RemovedAppxPackages.Values | Purge -Force }
- }
- Else
- {
- If ((Get-AppxProvisionedPackage -Path $InstallMount -ScratchDirectory $ScratchFolder -LogPath $DISMLog -LogLevel 1).Count -eq 0) { Get-ChildItem -Path (GetPath -Path $InstallMount -Child 'Program Files\WindowsApps') -Force | Purge -Force }
- }
+ If ($AppxPackages.Count -eq 0) { Get-ChildItem -Path (GetPath -Path $InstallMount -Child 'Program Files\WindowsApps') -Force | Purge -Force }
+ Else { Get-ChildItem -Path (GetPath -Path $InstallMount -Child 'Program Files\WindowsApps') -Force | Where-Object -Property Name -In $RemovedAppxPackages.Values | Purge -Force }
}
- RegHives -Load
- $Visibility = [Text.StringBuilder]::New('hide:')
- If ($RemovedAppxPackages.'Microsoft.WindowsMaps')
- {
- RegKey -Path "HKLM:\WIM_HKLM_SYSTEM\Maps" -Name "AutoUpdateEnabled" -Value 0 -Type DWord
- If (Test-Path -Path "HKLM:\WIM_HKLM_SYSTEM\ControlSet001\Services\MapsBroker") { RegKey -Path "HKLM:\WIM_HKLM_SYSTEM\ControlSet001\Services\MapsBroker" -Name "Start" -Value 4 -Type DWord }
- [Void]$Visibility.Append('maps;maps-downloadmaps;')
- }
- If ($RemovedAppxPackages.'Microsoft.Wallet' -and (Test-Path -Path "HKLM:\WIM_HKLM_SYSTEM\ControlSet001\Services\WalletService")) { RegKey -Path "HKLM:\WIM_HKLM_SYSTEM\ControlSet001\Services\WalletService" -Name "Start" -Value 4 -Type DWord }
- If ($RemovedAppxPackages.'Microsoft.XboxIdentityProvider' -and ($RemovedAppxPackages.Keys -like "*Xbox*").Count -gt 1 -or $RemovedSystemApps.'Microsoft.XboxGameCallableUI')
- {
- RegKey -Path "HKLM:\WIM_HKLM_SOFTWARE\Policies\Microsoft\Windows\GameDVR" -Name "AllowGameDVR" -Value 0 -Type DWord
- RegKey -Path "HKLM:\WIM_HKCU\Software\Microsoft\Windows\CurrentVersion\GameDVR" -Name "AppCaptureEnabled" -Value 0 -Type DWord
- RegKey -Path "HKLM:\WIM_HKCU\Software\Microsoft\Windows\CurrentVersion\GameDVR" -Name "AudioCaptureEnabled" -Value 0 -Type DWord
- RegKey -Path "HKLM:\WIM_HKCU\Software\Microsoft\Windows\CurrentVersion\GameDVR" -Name "CursorCaptureEnabled" -Value 0 -Type DWord
- RegKey -Path "HKLM:\WIM_HKCU\Software\Microsoft\GameBar" -Name "AutoGameModeEnabled" -Value 0 -Type DWord
- RegKey -Path "HKLM:\WIM_HKCU\Software\Microsoft\GameBar" -Name "AllowAutoGameMode" -Value 0 -Type DWord
- RegKey -Path "HKLM:\WIM_HKCU\Software\Microsoft\GameBar" -Name "UseNexusForGameBarEnabled" -Value 0 -Type DWord
- RegKey -Path "HKLM:\WIM_HKCU\Software\Microsoft\GameBar" -Name "ShowStartupPanel" -Value 0 -Type DWord
- RegKey -Path "HKLM:\WIM_HKCU\System\GameConfigStore" -Name "GameDVR_Enabled" -Value 0 -Type DWord
- RegKey -Path "HKLM:\WIM_HKCU\System\GameConfigStore" -Name "GameDVR_FSEBehavior" -Value 2 -Type DWord
- RegKey -Path "HKLM:\WIM_HKCU\System\GameConfigStore" -Name "GameDVR_FSEBehaviorMode" -Value 2 -Type DWord
- @("xbgm", "XblAuthManager", "XblGameSave", "xboxgip", "XboxGipSvc", "XboxNetApiSvc") | ForEach-Object -Process { If (Test-Path -Path "HKLM:\WIM_HKLM_SYSTEM\ControlSet001\Services\$($PSItem)") { RegKey -Path "HKLM:\WIM_HKLM_SYSTEM\ControlSet001\Services\$($PSItem)" -Name "Start" -Value 4 -Type DWord } }
- [Void]$Visibility.Append('gaming-gamebar;gaming-gamedvr;gaming-broadcasting;gaming-gamemode;gaming-xboxnetworking;quietmomentsgame;')
- If ($InstallInfo.Build -lt '17763') { [Void]$Visibility.Append('gaming-trueplay;') }
- }
- If ($RemovedAppxPackages.'Microsoft.YourPhone' -or $RemovedSystemApps.'Microsoft.Windows.CallingShellApp')
- {
- [Void]$Visibility.Append('mobile-devices;mobile-devices-addphone;mobile-devices-addphone-direct;')
- If (Test-Path -Path "HKLM:\WIM_HKLM_SYSTEM\ControlSet001\Services\PhoneSvc") { RegKey -Path "HKLM:\WIM_HKLM_SYSTEM\ControlSet001\Services\PhoneSvc" -Name "Start" -Value 4 -Type DWord }
- }
- If ($RemovedSystemApps.'Microsoft.MicrosoftEdge' -and !$MicrosoftEdge.IsPresent) { RegKey -Path "HKLM:\WIM_HKLM_SOFTWARE\Microsoft\EdgeUpdate" -Name "DoNotUpdateToEdgeWithChromium" -Value 1 -Type DWord }
- If ($RemovedSystemApps.'Microsoft.BioEnrollment')
- {
- RegKey -Path "HKLM:\WIM_HKLM_SOFTWARE\Policies\Microsoft\Biometrics" -Name "Enabled" -Value 0 -Type DWord
- RegKey -Path "HKLM:\WIM_HKLM_SOFTWARE\Policies\Microsoft\Biometrics\Credential Provider" -Name "Enabled" -Value 0 -Type DWord
- If (Test-Path -Path "HKLM:\WIM_HKLM_SYSTEM\ControlSet001\Services\WbioSrvc") { RegKey -Path "HKLM:\WIM_HKLM_SYSTEM\ControlSet001\Services\WbioSrvc" -Name "Start" -Value 4 -Type DWord }
- $DynamicParams.BioEnrollment = $true
- }
- If ($RemovedSystemApps.'Microsoft.Windows.SecureAssessmentBrowser')
- {
- RegKey -Path "HKLM:\WIM_HKLM_SOFTWARE\Microsoft\Windows\CurrentVersion\SecureAssessment" -Name "AllowScreenMonitoring" -Value 0 -Type DWord
- RegKey -Path "HKLM:\WIM_HKLM_SOFTWARE\Microsoft\Windows\CurrentVersion\SecureAssessment" -Name "AllowTextSuggestions" -Value 0 -Type DWord
- RegKey -Path "HKLM:\WIM_HKLM_SOFTWARE\Microsoft\Windows\CurrentVersion\SecureAssessment" -Name "RequirePrinting" -Value 0 -Type DWord
- }
- If ($RemovedSystemApps.'Microsoft.Windows.ContentDeliveryManager')
- {
- @("ContentDeliveryAllowed", "FeatureManagementEnabled", "OemPreInstalledAppsEnabled", "PreInstalledAppsEnabled", "PreInstalledAppsEverEnabled", "RotatingLockScreenEnabled",
- "RotatingLockScreenOverlayEnabled", "SilentInstalledAppsEnabled", "SoftLandingEnabled", "SystemPaneSuggestionsEnabled", "SubscribedContentEnabled",
- "SubscribedContent-202913Enabled", "SubscribedContent-202914Enabled", "SubscribedContent-280797Enabled", "SubscribedContent-280811Enabled", "SubscribedContent-280812Enabled",
- "SubscribedContent-280813Enabled", "SubscribedContent-280814Enabled", "SubscribedContent-280815Enabled", "SubscribedContent-280810Enabled", "SubscribedContent-280817Enabled",
- "SubscribedContent-310091Enabled", "SubscribedContent-310092Enabled", "SubscribedContent-310093Enabled", "SubscribedContent-310094Enabled", "SubscribedContent-314558Enabled",
- "SubscribedContent-314559Enabled", "SubscribedContent-314562Enabled", "SubscribedContent-314563Enabled", "SubscribedContent-314566Enabled", "SubscribedContent-314567Enabled",
- "SubscribedContent-338380Enabled", "SubscribedContent-338387Enabled", "SubscribedContent-338381Enabled", "SubscribedContent-338388Enabled", "SubscribedContent-338382Enabled",
- "SubscribedContent-338389Enabled", "SubscribedContent-338386Enabled", "SubscribedContent-338393Enabled", "SubscribedContent-346480Enabled", "SubscribedContent-346481Enabled",
- "SubscribedContent-353694Enabled", "SubscribedContent-353695Enabled", "SubscribedContent-353696Enabled", "SubscribedContent-353697Enabled", "SubscribedContent-353698Enabled",
- "SubscribedContent-353699Enabled", "SubscribedContent-88000044Enabled", "SubscribedContent-88000045Enabled", "SubscribedContent-88000105Enabled", "SubscribedContent-88000106Enabled",
- "SubscribedContent-88000161Enabled", "SubscribedContent-88000162Enabled", "SubscribedContent-88000163Enabled", "SubscribedContent-88000164Enabled", "SubscribedContent-88000165Enabled",
- "SubscribedContent-88000166Enabled") | ForEach-Object -Process { RegKey -Path "HKLM:\WIM_HKCU\Software\Microsoft\Windows\CurrentVersion\ContentDeliveryManager" -Name $PSItem -Value 0 -Type DWord }
- RegKey -Path "HKLM:\WIM_HKLM_SOFTWARE\Policies\Microsoft\Windows\CloudContent" -Name "DisableWindowsConsumerFeatures" -Value 1 -Type DWord
- RegKey -Path "HKLM:\WIM_HKCU\Software\Policies\Microsoft\Microsoft\Windows\CurrentVersion\PushNotifications" -Name "NoCloudApplicationNotification" -Value 1 -Type DWord
- }
- If ($RemovedSystemApps.'Microsoft.Windows.SecHealthUI')
- {
- RegKey -Path "HKLM:\WIM_HKLM_SOFTWARE\Policies\Microsoft\Windows Defender" -Name "DisableAntiSpyware" -Value 1 -Type DWord
- RegKey -Path "HKLM:\WIM_HKLM_SOFTWARE\Policies\Microsoft\Windows Defender\Spynet" -Name "SpyNetReporting" -Value 0 -Type DWord
- RegKey -Path "HKLM:\WIM_HKLM_SOFTWARE\Policies\Microsoft\Windows Defender\Spynet" -Name "SubmitSamplesConsent" -Value 2 -Type DWord
- RegKey -Path "HKLM:\WIM_HKLM_SOFTWARE\Policies\Microsoft\Windows Defender\MpEngine" -Name "MpEnablePus" -Value 0 -Type DWord
- RegKey -Path "HKLM:\WIM_HKLM_SOFTWARE\Policies\Microsoft\Windows Defender\Reporting" -Name "DisableEnhancedNotifications" -Value 1 -Type DWord
- RegKey -Path "HKLM:\WIM_HKLM_SOFTWARE\Policies\Microsoft\Windows Defender\Real-Time Protection" -Name "DisableBehaviorMonitoring" -Value 1 -Type DWord
- RegKey -Path "HKLM:\WIM_HKLM_SOFTWARE\Policies\Microsoft\Windows Defender\Real-Time Protection" -Name "DisableRealtimeMonitoring" -Value 1 -Type DWord
- RegKey -Path "HKLM:\WIM_HKLM_SOFTWARE\Policies\Microsoft\Windows Defender\Real-Time Protection" -Name "DisableOnAccessProtection" -Value 1 -Type DWord
- RegKey -Path "HKLM:\WIM_HKLM_SOFTWARE\Policies\Microsoft\Windows Defender\Real-Time Protection" -Name "DisableScanOnRealtimeEnable" -Value 1 -Type DWord
- RegKey -Path "HKLM:\WIM_HKLM_SOFTWARE\Policies\Microsoft\Windows Defender\Real-Time Protection" -Name "DisableIOAVProtection" -Value 1 -Type DWord
- RegKey -Path "HKLM:\WIM_HKLM_SOFTWARE\Policies\Microsoft\Windows Defender\Policy Manager" -Name "AllowBehaviorMonitoring" -Value 2 -Type DWord
- RegKey -Path "HKLM:\WIM_HKLM_SOFTWARE\Policies\Microsoft\Windows Defender\Policy Manager" -Name "AllowCloudProtection" -Value 0 -Type DWord
- RegKey -Path "HKLM:\WIM_HKLM_SOFTWARE\Policies\Microsoft\Windows Defender\Policy Manager" -Name "AllowRealtimeMonitoring" -Value 0 -Type DWord
- RegKey -Path "HKLM:\WIM_HKLM_SOFTWARE\Policies\Microsoft\Windows Defender\Policy Manager" -Name "SubmitSamplesConsent" -Value 2 -Type DWord
- RegKey -Path "HKLM:\WIM_HKLM_SOFTWARE\Policies\Microsoft\Windows Defender\UX Configuration" -Name "Notification_Suppress" -Value 1 -Type DWord
- RegKey -Path "HKLM:\WIM_HKLM_SOFTWARE\Policies\Microsoft\MRT" -Name "DontOfferThroughWUAU" -Value 1 -Type DWord
- RegKey -Path "HKLM:\WIM_HKLM_SOFTWARE\Policies\Microsoft\MRT" -Name "DontReportInfectionInformation" -Value 1 -Type DWord
- RegKey -Path "HKLM:\WIM_HKLM_SOFTWARE\Policies\Microsoft\Windows Defender Security Center\Systray" -Name "HideSystray" -Value 1 -Type DWord
- RegKey -Path "HKLM:\WIM_HKLM_SOFTWARE\Microsoft\Windows Defender\Features" -Name "TamperProtection" -Value 0 -Type DWord -Force
- RegKey -Path "HKLM:\WIM_HKCU\Software\Microsoft\Windows Security Health\State" -Name "AccountProtection_MicrosoftAccount_Disconnected" -Value 1 -Type DWord
- RegKey -Path "HKLM:\WIM_HKCU\Software\Microsoft\Windows Security Health\State" -Name "AppAndBrowser_EdgeSmartScreenOff" -Value 0 -Type DWord
- RegKey -Path "HKLM:\WIM_HKCU\Software\Microsoft\Windows\CurrentVersion\AppHost" -Name "SmartScreenEnabled" -Value "Off" -Type String
- RegKey -Path "HKLM:\WIM_HKLM_SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer" -Name "SmartScreenEnabled" -Value "Off" -Type String
- RegKey -Path "HKLM:\WIM_HKLM_SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Explorer" -Name "SmartScreenEnabled" -Value "Off" -Type String
- RegKey -Path "HKLM:\WIM_HKLM_SOFTWARE\Microsoft\Windows\CurrentVersion\AppHost" -Name "EnableWebContentEvaluation" -Value 0 -Type DWord
- RegKey -Path "HKLM:\WIM_HKCU\Software\Microsoft\Windows\CurrentVersion\AppHost" -Name "EnableWebContentEvaluation" -Value 0 -Type DWord
- RegKey -Path "HKLM:\WIM_HKLM_SOFTWARE\Policies\Microsoft\Windows\System" -Name "EnableSmartScreen" -Value 0 -Type DWord
- @("SecurityHealthService", "WinDefend", "WdNisSvc", "WdNisDrv", "WdBoot", "WdFilter", "Sense") | ForEach-Object -Process { If (Test-Path -Path "HKLM:\WIM_HKLM_SYSTEM\ControlSet001\Services\$($PSItem)") { RegKey -Path "HKLM:\WIM_HKLM_SYSTEM\ControlSet001\Services\$($PSItem)" -Name "Start" -Value 4 -Type DWord } }
- @("HKLM:\WIM_HKLM_SOFTWARE\Classes\*\shellex\ContextMenuHandlers\EPP", "HKLM:\WIM_HKLM_SOFTWARE\Classes\Directory\shellex\ContextMenuHandlers\EPP", "HKLM:\WIM_HKLM_SOFTWARE\Classes\Drive\shellex\ContextMenuHandlers\EPP",
- "HKLM:\WIM_HKLM_SYSTEM\ControlSet001\Control\WMI\AutoLogger\DefenderApiLogger", "HKLM:\WIM_HKLM_SYSTEM\ControlSet001\Control\WMI\AutoLogger\DefenderAuditLogger") | Purge
- Remove-KeyProperty -Path "HKLM:\WIM_HKLM_SOFTWARE\Microsoft\Windows\CurrentVersion\Run" -Name "SecurityHealth"
- If (!$DynamicParams.LTSC -or $MicrosoftEdge.IsPresent)
- {
- RegKey -Path "HKLM:\WIM_HKLM_SOFTWARE\Policies\Microsoft\MicrosoftEdge\PhishingFilter" -Name "EnabledV9" -Value 0 -Type DWord
- RegKey -Path "HKLM:\WIM_HKLM_SOFTWARE\WOW6432Node\Policies\Microsoft\MicrosoftEdge\PhishingFilter" -Name "EnabledV9" -Value 0 -Type DWord
- }
- If ($InstallInfo.Build -ge '17763')
- {
- RegKey -Path "HKLM:\WIM_HKLM_SOFTWARE\Policies\Microsoft\Windows Defender\SmartScreen" -Name "ConfigureAppInstallControlEnabled" -Value 1 -Type DWord
- RegKey -Path "HKLM:\WIM_HKLM_SOFTWARE\Policies\Microsoft\Windows Defender\SmartScreen" -Name "ConfigureAppInstallControl" -Value "Anywhere" -Type String
- }
- [Void]$Visibility.Append('windowsdefender;')
- $DynamicParams.SecHealthUI = $true
- }
- If ($Visibility.Length -gt 5)
- {
- RegKey -Path "HKLM:\WIM_HKLM_SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\Explorer" -Name "SettingsPageVisibility" -Value $Visibility.ToString().TrimEnd(';') -Type String
- RegKey -Path "HKLM:\WIM_HKCU\Software\Microsoft\Windows\CurrentVersion\Policies\Explorer" -Name "SettingsPageVisibility" -Value $Visibility.ToString().TrimEnd(';') -Type String
+ Else
+ {
+ If ($AppxPackages.Count -eq 0) { Get-ChildItem -Path (GetPath -Path $InstallMount -Child 'Program Files\WindowsApps') -Force | Purge -Force }
}
- RegHives -Unload
- If ($DynamicParams.BioEnrollment -and (Get-WindowsCapability -Path $InstallMount -Name *Hello* -ScratchDirectory $ScratchFolder -LogPath $DISMLog -LogLevel 1 | Where-Object -Property State -EQ Installed))
+ }
+ RegHives -Load
+ $Visibility = [Text.StringBuilder]::New('hide:')
+ If ($RemovedPackages.'Microsoft.WindowsMaps' -or ($AppxPackages | Where-Object {$_.DisplayName -eq "Microsoft.WindowsMaps"}).Count -eq 0)
+ {
+ Log "Applying Windows Maps removal tweak"
+ Start-Sleep 1
+ RegKey -Path "HKLM:\WIM_HKLM_SYSTEM\Maps" -Name "AutoUpdateEnabled" -Value 0 -Type DWord
+ If (Test-Path -Path "HKLM:\WIM_HKLM_SYSTEM\ControlSet001\Services\MapsBroker") { RegKey -Path "HKLM:\WIM_HKLM_SYSTEM\ControlSet001\Services\MapsBroker" -Name "Start" -Value 4 -Type DWord }
+ [Void]$Visibility.Append('maps;maps-downloadmaps;')
+ }
+ If (($RemovedPackages.'Microsoft.Wallet' -or ($AppxPackages | Where-Object {$_.DisplayName -eq "Microsoft.Wallet"}).Count -eq 0) -and (Test-Path -Path "HKLM:\WIM_HKLM_SYSTEM\ControlSet001\Services\WalletService")) {
+ Log "Applying Microsoft Wallet removal tweak"
+ Start-Sleep 1
+ RegKey -Path "HKLM:\WIM_HKLM_SYSTEM\ControlSet001\Services\WalletService" -Name "Start" -Value 4 -Type DWord
+ }
+ If (($RemovedPackages.'Microsoft.XboxIdentityProvider' -and ($RemovedPackages.Keys -like "*Xbox*").Count -gt 1 -or $RemovedPackages.'Microsoft.XboxGameCallableUI') -or ($AppxPackages | Where-Object {$_.DisplayName -like "*Xbox*"}).Count -eq 0)
+ {
+ Log "Applying Xbox apps removal tweak"
+ Start-Sleep 1
+ RegKey -Path "HKLM:\WIM_HKLM_SOFTWARE\Policies\Microsoft\Windows\GameDVR" -Name "AllowGameDVR" -Value 0 -Type DWord
+ RegKey -Path "HKLM:\WIM_HKCU\Software\Microsoft\Windows\CurrentVersion\GameDVR" -Name "AppCaptureEnabled" -Value 0 -Type DWord
+ RegKey -Path "HKLM:\WIM_HKCU\Software\Microsoft\Windows\CurrentVersion\GameDVR" -Name "AudioCaptureEnabled" -Value 0 -Type DWord
+ RegKey -Path "HKLM:\WIM_HKCU\Software\Microsoft\Windows\CurrentVersion\GameDVR" -Name "CursorCaptureEnabled" -Value 0 -Type DWord
+ RegKey -Path "HKLM:\WIM_HKCU\Software\Microsoft\GameBar" -Name "AutoGameModeEnabled" -Value 0 -Type DWord
+ RegKey -Path "HKLM:\WIM_HKCU\Software\Microsoft\GameBar" -Name "AllowAutoGameMode" -Value 0 -Type DWord
+ RegKey -Path "HKLM:\WIM_HKCU\Software\Microsoft\GameBar" -Name "UseNexusForGameBarEnabled" -Value 0 -Type DWord
+ RegKey -Path "HKLM:\WIM_HKCU\Software\Microsoft\GameBar" -Name "ShowStartupPanel" -Value 0 -Type DWord
+ RegKey -Path "HKLM:\WIM_HKCU\System\GameConfigStore" -Name "GameDVR_Enabled" -Value 0 -Type DWord
+ RegKey -Path "HKLM:\WIM_HKCU\System\GameConfigStore" -Name "GameDVR_FSEBehavior" -Value 2 -Type DWord
+ RegKey -Path "HKLM:\WIM_HKCU\System\GameConfigStore" -Name "GameDVR_FSEBehaviorMode" -Value 2 -Type DWord
+ @("xbgm", "XblAuthManager", "XblGameSave", "xboxgip", "XboxGipSvc", "XboxNetApiSvc") | ForEach-Object -Process { If (Test-Path -Path "HKLM:\WIM_HKLM_SYSTEM\ControlSet001\Services\$($PSItem)") { RegKey -Path "HKLM:\WIM_HKLM_SYSTEM\ControlSet001\Services\$($PSItem)" -Name "Start" -Value 4 -Type DWord } }
+ [Void]$Visibility.Append('gaming-gamebar;gaming-gamedvr;gaming-broadcasting;gaming-gamemode;gaming-xboxnetworking;quietmomentsgame;')
+ If ($InstallInfo.Build -lt '17763') { [Void]$Visibility.Append('gaming-trueplay;') }
+ }
+ If ($RemovedPackages.'Microsoft.YourPhone' -or $RemovedPackages.'Microsoft.Windows.CallingShellApp' -or $($AppxPackages | Where-Object {$_.DisplayName -eq "Microsoft.YourPhone"}).Count -eq 0)
+ {
+ Log "Applying YourPhone removal tweak"
+ Start-Sleep 1
+ [Void]$Visibility.Append('mobile-devices;mobile-devices-addphone;mobile-devices-addphone-direct;')
+ If (Test-Path -Path "HKLM:\WIM_HKLM_SYSTEM\ControlSet001\Services\PhoneSvc") { RegKey -Path "HKLM:\WIM_HKLM_SYSTEM\ControlSet001\Services\PhoneSvc" -Name "Start" -Value 4 -Type DWord }
+ }
+ If ($RemovedPackages.'Microsoft.MicrosoftEdge' -and !$MicrosoftEdge.IsPresent) {
+ Log "Applying Microsoft Edge removal tweak"
+ Start-Sleep 1
+ RegKey -Path "HKLM:\WIM_HKLM_SOFTWARE\Microsoft\EdgeUpdate" -Name "DoNotUpdateToEdgeWithChromium" -Value 1 -Type DWord
+ }
+ If ($RemovedPackages.'Microsoft.BioEnrollment')
+ {
+ Log "Applying Microsoft BioEnrollment removal tweak"
+ Start-Sleep 1
+ RegKey -Path "HKLM:\WIM_HKLM_SOFTWARE\Policies\Microsoft\Biometrics" -Name "Enabled" -Value 0 -Type DWord
+ RegKey -Path "HKLM:\WIM_HKLM_SOFTWARE\Policies\Microsoft\Biometrics\Credential Provider" -Name "Enabled" -Value 0 -Type DWord
+ If (Test-Path -Path "HKLM:\WIM_HKLM_SYSTEM\ControlSet001\Services\WbioSrvc") { RegKey -Path "HKLM:\WIM_HKLM_SYSTEM\ControlSet001\Services\WbioSrvc" -Name "Start" -Value 4 -Type DWord }
+ [Void]$Visibility.Append('signinoptions-launchfaceenrollment;signinoptions-launchfingerprintenrollment;')
+ $DynamicParams.BioEnrollment = $true
+ }
+ If ($RemovedPackages.'Microsoft.Windows.SecureAssessmentBrowser')
+ {
+ Log "Applying SecureAssessmentBrowser removal tweak"
+ Start-Sleep 1
+ RegKey -Path "HKLM:\WIM_HKLM_SOFTWARE\Microsoft\Windows\CurrentVersion\SecureAssessment" -Name "AllowScreenMonitoring" -Value 0 -Type DWord
+ RegKey -Path "HKLM:\WIM_HKLM_SOFTWARE\Microsoft\Windows\CurrentVersion\SecureAssessment" -Name "AllowTextSuggestions" -Value 0 -Type DWord
+ RegKey -Path "HKLM:\WIM_HKLM_SOFTWARE\Microsoft\Windows\CurrentVersion\SecureAssessment" -Name "RequirePrinting" -Value 0 -Type DWord
+ }
+ If ($RemovedPackages.'Microsoft.Windows.ContentDeliveryManager' -or $SelectiveRegistry.Disable3rdPartyApps)
+ {
+ Log "Applying ContentDeliveryManager removal tweak"
+ Start-Sleep 1
+ @("ContentDeliveryAllowed", "FeatureManagementEnabled", "OemPreInstalledAppsEnabled", "PreInstalledAppsEnabled", "PreInstalledAppsEverEnabled", "RotatingLockScreenEnabled",
+ "RotatingLockScreenOverlayEnabled", "SilentInstalledAppsEnabled", "SoftLandingEnabled", "SystemPaneSuggestionsEnabled", "SubscribedContentEnabled",
+ "SubscribedContent-202913Enabled", "SubscribedContent-202914Enabled", "SubscribedContent-280797Enabled", "SubscribedContent-280811Enabled", "SubscribedContent-280812Enabled",
+ "SubscribedContent-280813Enabled", "SubscribedContent-280814Enabled", "SubscribedContent-280815Enabled", "SubscribedContent-280810Enabled", "SubscribedContent-280817Enabled",
+ "SubscribedContent-310091Enabled", "SubscribedContent-310092Enabled", "SubscribedContent-310093Enabled", "SubscribedContent-310094Enabled", "SubscribedContent-314558Enabled",
+ "SubscribedContent-314559Enabled", "SubscribedContent-314562Enabled", "SubscribedContent-314563Enabled", "SubscribedContent-314566Enabled", "SubscribedContent-314567Enabled",
+ "SubscribedContent-338380Enabled", "SubscribedContent-338387Enabled", "SubscribedContent-338381Enabled", "SubscribedContent-338388Enabled", "SubscribedContent-338382Enabled",
+ "SubscribedContent-338389Enabled", "SubscribedContent-338386Enabled", "SubscribedContent-338393Enabled", "SubscribedContent-346480Enabled", "SubscribedContent-346481Enabled",
+ "SubscribedContent-353694Enabled", "SubscribedContent-353695Enabled", "SubscribedContent-353696Enabled", "SubscribedContent-353697Enabled", "SubscribedContent-353698Enabled",
+ "SubscribedContent-353699Enabled", "SubscribedContent-88000044Enabled", "SubscribedContent-88000045Enabled", "SubscribedContent-88000105Enabled", "SubscribedContent-88000106Enabled",
+ "SubscribedContent-88000161Enabled", "SubscribedContent-88000162Enabled", "SubscribedContent-88000163Enabled", "SubscribedContent-88000164Enabled", "SubscribedContent-88000165Enabled",
+ "SubscribedContent-88000166Enabled") | ForEach-Object -Process { RegKey -Path "HKLM:\WIM_HKCU\Software\Microsoft\Windows\CurrentVersion\ContentDeliveryManager" -Name $PSItem -Value 0 -Type DWord }
+ RegKey -Path "HKLM:\WIM_HKLM_SOFTWARE\Policies\Microsoft\Windows\CloudContent" -Name "DisableWindowsConsumerFeatures" -Value 1 -Type DWord
+ RegKey -Path "HKLM:\WIM_HKCU\Software\Policies\Microsoft\Microsoft\Windows\CurrentVersion\PushNotifications" -Name "NoCloudApplicationNotification" -Value 1 -Type DWord
+
+ If ($InstallInfo.Build -ge "22000") {
+ RegKey -Path "HKLM:\WIM_HKLM_SOFTWARE\Microsoft\PolicyManager\current\device\Start" -Name "ConfigureStartPins" -Type String -Value '{"pinnedList": [{}]}'
+ RegKey -Path "HKLM:\WIM_HKLM_SOFTWARE\Microsoft\PolicyManager\current\device\Start" -Name "ConfigureStartPins_ProviderSet" -Type Dword -Value "0"
+ }
+ }
+ If ($DormantDefender.IsPresent -or $RemovedPackages.'Microsoft.Windows.SecHealthUI' -or $RemovedPackages.'Microsoft.SecHealthUI' -or (($AppxPackages | Where-Object {$_.DisplayName -eq 'Microsoft.SecHealthUI'}).Count -eq 0 -and $InstallInfo.Build -ge 22000))
+ {
+ Log "Applying Defender removal tweak"
+ Start-Sleep 1
+ RegKey -Path "HKLM:\WIM_HKLM_SOFTWARE\Policies\Microsoft\Windows Defender" -Name "DisableAntiSpyware" -Value 1 -Type DWord
+
+ RegKey -Path "HKLM:\WIM_HKLM_SOFTWARE\Policies\Microsoft\Windows Defender" -Name "PUAProtection" -Value 1 -Type DWord
+
+ RegKey -Path "HKLM:\WIM_HKLM_SOFTWARE\Policies\Microsoft\Windows Defender\Spynet" -Name "SpyNetReporting" -Value 0 -Type DWord
+ RegKey -Path "HKLM:\WIM_HKLM_SOFTWARE\Policies\Microsoft\Windows Defender\Spynet" -Name "SubmitSamplesConsent" -Value 2 -Type DWord
+ RegKey -Path "HKLM:\WIM_HKLM_SOFTWARE\Policies\Microsoft\Windows Defender\MpEngine" -Name "MpEnablePus" -Value 0 -Type DWord
+ RegKey -Path "HKLM:\WIM_HKLM_SOFTWARE\Policies\Microsoft\Windows Defender\Reporting" -Name "DisableEnhancedNotifications" -Value 1 -Type DWord
+ RegKey -Path "HKLM:\WIM_HKLM_SOFTWARE\Policies\Microsoft\Windows Defender\Real-Time Protection" -Name "DisableBehaviorMonitoring" -Value 1 -Type DWord
+ RegKey -Path "HKLM:\WIM_HKLM_SOFTWARE\Policies\Microsoft\Windows Defender\Real-Time Protection" -Name "DisableRealtimeMonitoring" -Value 1 -Type DWord
+ RegKey -Path "HKLM:\WIM_HKLM_SOFTWARE\Policies\Microsoft\Windows Defender\Real-Time Protection" -Name "DisableOnAccessProtection" -Value 1 -Type DWord
+ RegKey -Path "HKLM:\WIM_HKLM_SOFTWARE\Policies\Microsoft\Windows Defender\Real-Time Protection" -Name "DisableScanOnRealtimeEnable" -Value 1 -Type DWord
+ RegKey -Path "HKLM:\WIM_HKLM_SOFTWARE\Policies\Microsoft\Windows Defender\Real-Time Protection" -Name "DisableIOAVProtection" -Value 1 -Type DWord
+ RegKey -Path "HKLM:\WIM_HKLM_SOFTWARE\Policies\Microsoft\Windows Defender\Policy Manager" -Name "AllowBehaviorMonitoring" -Value 2 -Type DWord
+ RegKey -Path "HKLM:\WIM_HKLM_SOFTWARE\Policies\Microsoft\Windows Defender\Policy Manager" -Name "AllowCloudProtection" -Value 0 -Type DWord
+ RegKey -Path "HKLM:\WIM_HKLM_SOFTWARE\Policies\Microsoft\Windows Defender\Policy Manager" -Name "AllowRealtimeMonitoring" -Value 0 -Type DWord
+ RegKey -Path "HKLM:\WIM_HKLM_SOFTWARE\Policies\Microsoft\Windows Defender\Policy Manager" -Name "SubmitSamplesConsent" -Value 2 -Type DWord
+ RegKey -Path "HKLM:\WIM_HKLM_SOFTWARE\Policies\Microsoft\Windows Defender\UX Configuration" -Name "Notification_Suppress" -Value 1 -Type DWord
+
+ RegKey -Path "HKLM:\WIM_HKLM_SOFTWARE\Policies\Microsoft\Windows Defender\UX Configuration" -Name "UILockdown" -Value 0 -Type DWord
+ RegKey -Path "HKLM:\WIM_HKLM_SOFTWARE\Policies\Microsoft\Windows Defender Security Center\Notifications" -Name "DisableNotifications" -Value 1 -Type DWord
+
+ RegKey -Path "HKLM:\WIM_HKLM_SOFTWARE\Policies\Microsoft\MRT" -Name "DontOfferThroughWUAU" -Value 1 -Type DWord
+ RegKey -Path "HKLM:\WIM_HKLM_SOFTWARE\Policies\Microsoft\MRT" -Name "DontReportInfectionInformation" -Value 1 -Type DWord
+ RegKey -Path "HKLM:\WIM_HKLM_SOFTWARE\Policies\Microsoft\Windows Defender Security Center\Systray" -Name "HideSystray" -Value 1 -Type DWord
+ RegKey -Path "HKLM:\WIM_HKLM_SOFTWARE\Microsoft\Windows Defender\Features" -Name "TamperProtection" -Value 0 -Type DWord -Force
+ RegKey -Path "HKLM:\WIM_HKCU\Software\Microsoft\Windows Security Health\State" -Name "AccountProtection_MicrosoftAccount_Disconnected" -Value 1 -Type DWord
+ RegKey -Path "HKLM:\WIM_HKCU\Software\Microsoft\Windows Security Health\State" -Name "AppAndBrowser_EdgeSmartScreenOff" -Value 0 -Type DWord
+ RegKey -Path "HKLM:\WIM_HKCU\Software\Microsoft\Windows\CurrentVersion\AppHost" -Name "SmartScreenEnabled" -Value "Off" -Type String
+ RegKey -Path "HKLM:\WIM_HKLM_SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer" -Name "SmartScreenEnabled" -Value "Off" -Type String
+ RegKey -Path "HKLM:\WIM_HKLM_SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Explorer" -Name "SmartScreenEnabled" -Value "Off" -Type String
+ RegKey -Path "HKLM:\WIM_HKLM_SOFTWARE\Microsoft\Windows\CurrentVersion\AppHost" -Name "EnableWebContentEvaluation" -Value 0 -Type DWord
+ RegKey -Path "HKLM:\WIM_HKCU\Software\Microsoft\Windows\CurrentVersion\AppHost" -Name "EnableWebContentEvaluation" -Value 0 -Type DWord
+ RegKey -Path "HKLM:\WIM_HKLM_SOFTWARE\Microsoft\Windows\CurrentVersion\AppHost" -Name "PreventOverride" -Value 0 -Type DWord -Force
+ RegKey -Path "HKLM:\WIM_HKCU\Software\Microsoft\Windows\CurrentVersion\AppHost" -Name "PreventOverride" -Value 0 -Type DWord -Force
+
+ RegKey -Path "HKLM:\WIM_HKLM_SOFTWARE\Microsoft\Edge\SmartScreenEnabled" -Name "(default)" -Value 0 -Type DWord -Force
+ RegKey -Path "HKLM:\WIM_HKCU\Software\Microsoft\Edge\SmartScreenEnabled" -Name "(default)" -Value 0 -Type DWord -Force
+
+ RegKey -Path "HKLM:\WIM_HKLM_SOFTWARE\Microsoft\Edge\SmartScreenPuaEnabled" -Name "(default)" -Value 0 -Type DWord -Force
+ RegKey -Path "HKLM:\WIM_HKCU\Software\Microsoft\Edge\SmartScreenPuaEnabled" -Name "(default)" -Value 0 -Type DWord -Force
+
+
+ RegKey -Path "HKLM:\WIM_HKLM_SOFTWARE\Policies\Microsoft\Windows\System" -Name "EnableSmartScreen" -Value 0 -Type DWord
+ RegKey -Path "HKLM:\WIM_HKLM_SOFTWARE\Policies\Microsoft\Windows\System" -Name "ShellSmartScreenLevel" -Value 0 -Type DWord -Force
+ @("SecurityHealthService", "WinDefend", "WdNisSvc", "WdNisDrv", "WdBoot", "WdFilter", "Sense", "webthreatdefsvc", "webthreatdefusersvc") | ForEach-Object -Process { If (Test-Path -Path "HKLM:\WIM_HKLM_SYSTEM\ControlSet001\Services\$($PSItem)") { RegKey -Path "HKLM:\WIM_HKLM_SYSTEM\ControlSet001\Services\$($PSItem)" -Name "Start" -Value 4 -Type DWord } }
+ @("HKLM:\WIM_HKLM_SOFTWARE\Classes\*\shellex\ContextMenuHandlers\EPP", "HKLM:\WIM_HKLM_SOFTWARE\Classes\Directory\shellex\ContextMenuHandlers\EPP", "HKLM:\WIM_HKLM_SOFTWARE\Classes\Drive\shellex\ContextMenuHandlers\EPP",
+ "HKLM:\WIM_HKLM_SYSTEM\ControlSet001\Control\WMI\AutoLogger\DefenderApiLogger", "HKLM:\WIM_HKLM_SYSTEM\ControlSet001\Control\WMI\AutoLogger\DefenderAuditLogger") | Purge
+ Remove-KeyProperty -Path "HKLM:\WIM_HKLM_SOFTWARE\Microsoft\Windows\CurrentVersion\Run" -Name "SecurityHealth"
+ If (!$DynamicParams.LTSC -or $MicrosoftEdge.IsPresent -or $InstallInfo.Build -ge 22000)
{
- Try
- {
- Log $OptimizeData.RemovingBiometricCapability
- [Void](Get-WindowsCapability -Path $InstallMount -Name *Hello* -ScratchDirectory $ScratchFolder -LogPath $DISMLog -LogLevel 1 | Where-Object -Property State -EQ Installed | Remove-WindowsCapability -Path $InstallMount -ScratchDirectory $ScratchFolder -LogPath $DISMLog -LogLevel 1 -ErrorAction Stop)
- }
- Catch
- {
- Log $OptimizeData.FailedRemovingBiometricCapability -Type Error -ErrorRecord $Error[0]
- Start-Sleep 3
- }
+ RegKey -Path "HKLM:\WIM_HKLM_SOFTWARE\Policies\Microsoft\MicrosoftEdge\PhishingFilter" -Name "EnabledV9" -Value 0 -Type DWord
+ RegKey -Path "HKLM:\WIM_HKLM_SOFTWARE\WOW6432Node\Policies\Microsoft\MicrosoftEdge\PhishingFilter" -Name "EnabledV9" -Value 0 -Type DWord
}
- If ($DynamicParams.SecHealthUI -and (Get-WindowsOptionalFeature -Path $InstallMount -FeatureName Windows-Defender-Default-Definitions -ScratchDirectory $ScratchFolder -LogPath $DISMLog -LogLevel 1 | Where-Object -Property State -EQ Enabled))
+ If ($InstallInfo.Build -ge '17763')
{
- Try
- {
- $DisableDefenderOptionalFeature = @{
+ RegKey -Path "HKLM:\WIM_HKLM_SOFTWARE\Policies\Microsoft\Windows Defender\SmartScreen" -Name "ConfigureAppInstallControlEnabled" -Value 1 -Type DWord
+ RegKey -Path "HKLM:\WIM_HKLM_SOFTWARE\Policies\Microsoft\Windows Defender\SmartScreen" -Name "ConfigureAppInstallControl" -Value "Anywhere" -Type String
+ }
+ [Void]$Visibility.Append('windowsdefender;')
+ $DynamicParams.SecHealthUI = $true
+ Log $OptimizeData.DisableDefender
+ Clear-Host
+ }
+ If ($Visibility.Length -gt 5)
+ {
+ RegKey -Path "HKLM:\WIM_HKLM_SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\Explorer" -Name "SettingsPageVisibility" -Value $Visibility.ToString().TrimEnd(';') -Type String
+ RegKey -Path "HKLM:\WIM_HKCU\Software\Microsoft\Windows\CurrentVersion\Policies\Explorer" -Name "SettingsPageVisibility" -Value $Visibility.ToString().TrimEnd(';') -Type String
+ }
+ If($RemovedPackages."Microsoft.Windows.Search") {
+ $DynamicParams.RemovedWindowsSearchPackage = $true
+ }
+ RegHives -Unload
+ If ($DynamicParams.BioEnrollment -and (Get-WindowsCapability -Path $InstallMount -Name *Hello* -ScratchDirectory $ScratchFolder -LogPath $DISMLog -LogLevel 1 | Where-Object -Property State -EQ Installed))
+ {
+ Try
+ {
+ Get-WindowsCapability -Path $InstallMount -Name *Hello* -ScratchDirectory $ScratchFolder -LogPath $DISMLog -LogLevel 1 | Where-Object -Property State -EQ Installed | ForEach-Object -Process {
+ $RemoveBiometricCapability = @{
Path = $InstallMount
- FeatureName = 'Windows-Defender-Default-Definitions'
- Remove = $true
- NoRestart = $true
+ Name = $PSItem.Name
ScratchDirectory = $ScratchFolder
LogPath = $DISMLog
LogLevel = 1
ErrorAction = 'Stop'
}
- Log $OptimizeData.DisablingDefenderOptionalFeature
- [Void](Disable-WindowsOptionalFeature @DisableDefenderOptionalFeature)
+ Log ($OptimizeData.RemovingBiometricCapability -f $PSItem.Name)
+ [Void](Remove-WindowsCapability @RemoveBiometricCapability)
}
- Catch
- {
- Log $OptimizeData.FailedDisablingDefenderOptionalFeature -Type Error -ErrorRecord $Error[0]
- Start-Sleep 3
+ }
+ Catch
+ {
+ Log $OptimizeData.FailedRemovingBiometricCapability -Type Error -ErrorRecord $Error[0]
+ Start-Sleep 3
+ }
+ }
+ If ($DynamicParams.SecHealthUI -and (Get-WindowsOptionalFeature -Path $InstallMount -FeatureName Windows-Defender-Default-Definitions -ScratchDirectory $ScratchFolder -LogPath $DISMLog -LogLevel 1 | Where-Object -Property State -EQ Enabled))
+ {
+ Try
+ {
+ $DisableDefenderOptionalFeature = @{
+ Path = $InstallMount
+ FeatureName = 'Windows-Defender-Default-Definitions'
+ Remove = $true
+ NoRestart = $true
+ ScratchDirectory = $ScratchFolder
+ LogPath = $DISMLog
+ LogLevel = 1
+ ErrorAction = 'Stop'
}
+ Log $OptimizeData.DisablingDefenderOptionalFeature
+ [Void](Disable-WindowsOptionalFeature @DisableDefenderOptionalFeature)
+ }
+ Catch
+ {
+ Log $OptimizeData.FailedDisablingDefenderOptionalFeature -Type Error -ErrorRecord $Error[0]
+ Start-Sleep 3
}
}
#endregion Removed Package Clean-up
@@ -785,16 +1227,72 @@ Function Optimize-Offline
#endregion Import Custom App Associations
#region Windows Capability and Cabinet File Package Removal
- If ($Capabilities.IsPresent)
+ If ($Capabilities -in $AllowedRemovalOptions)
{
Clear-Host
$Host.UI.RawUI.WindowTitle = "Remove Windows Capabilities."
- $WindowsCapabilities = Get-WindowsCapability -Path $InstallMount -ScratchDirectory $ScratchFolder -LogPath $DISMLog -LogLevel 1 | Where-Object { $PSItem.Name -notlike "*Language.Basic*" -and $PSItem.Name -notlike "*TextToSpeech*" -and $PSItem.State -eq 'Installed' } | Select-Object -Property Name, State | Sort-Object -Property Name | Out-GridView -Title "Remove Windows Capabilities." -PassThru
+ $WindowsCapabilities = Get-CapabilityPackages -Path $InstallMount -ScratchDirectory $ScratchFolder -LogPath $DISMLog
+
If ($WindowsCapabilities)
{
Try
{
- $WindowsCapabilities | ForEach-Object -Process {
+
+ $capabilitiesToRemove = [System.Collections.ArrayList]@()
+
+ Switch ($PSBoundParameters.Capabilities)
+ {
+ 'Select'
+ {
+ $capabilitiesToRemove = $WindowsCapabilities | Out-GridView -Title "Remove Windows Capabilities." -PassThru
+
+ Break
+ }
+ 'Whitelist'
+ {
+ If (Test-Path -Path $OptimizeOffline.Lists.CapabilitiesList)
+ {
+ $Names = Get-Content -Path $OptimizeOffline.Lists.CapabilitiesList -Raw -ErrorAction Stop | ConvertFrom-Json -ErrorAction Stop | Select-Object -ExpandProperty Name
+
+ $WindowsCapabilities | ForEach-Object -Process {
+ $ToRemove = $true
+ Foreach($Name in $Names){
+ If ($PSItem.Name -eq $Name -or ($Name -match "\*" -and $PSItem.Name -like $Name)){
+ $ToRemove = $false
+ Break
+ }
+ }
+ If($ToRemove){
+ [void]$capabilitiesToRemove.Add($PSItem)
+ }
+ }
+ }
+ Break
+ }
+ 'Blacklist'
+ {
+ If (Test-Path -Path $OptimizeOffline.Lists.CapabilitiesList)
+ {
+ $Names = Get-Content -Path $OptimizeOffline.Lists.CapabilitiesList -Raw -ErrorAction Stop | ConvertFrom-Json -ErrorAction Stop | Select-Object -ExpandProperty Name
+
+ $WindowsCapabilities | ForEach-Object -Process {
+ Foreach($Name in $Names){
+ If ($PSItem.Name -eq $Name -or ($Name -match "\*" -and $PSItem.Name -like $Name)){
+ [void]$capabilitiesToRemove.Add($PSItem)
+ Break
+ }
+ }
+ }
+ }
+ Break
+ }
+ 'All'
+ {
+ $capabilitiesToRemove = $WindowsCapabilities
+ }
+ }
+
+ $capabilitiesToRemove | ForEach-Object -Process {
$RemoveCapabilityParams = @{
Path = $InstallMount
Name = $PSItem.Name
@@ -803,10 +1301,11 @@ Function Optimize-Offline
LogLevel = 1
ErrorAction = 'Stop'
}
- Log ($OptimizeData.RemovingWindowsCapability -f $PSItem.Name.Split('~')[0])
+ Log ($OptimizeData.RemovingWindowsCapability -f $PSItem.Name)
[Void](Remove-WindowsCapability @RemoveCapabilityParams)
}
- $DynamicParams.Capabilities = $true
+
+ $DynamicParams.Capabilities = $($capabilitiesToRemove.Count -gt 0)
}
Catch
{
@@ -817,16 +1316,74 @@ Function Optimize-Offline
}
}
- If ($Packages.IsPresent)
+ If ($Packages -in $AllowedRemovalOptions)
{
Clear-Host
$Host.UI.RawUI.WindowTitle = "Remove Windows Packages."
- $WindowsPackages = Get-WindowsPackage -Path $InstallMount -ScratchDirectory $ScratchFolder -LogPath $DISMLog -LogLevel 1 | Where-Object { $PSItem.ReleaseType -eq 'OnDemandPack' -or $PSItem.ReleaseType -eq 'LanguagePack' -or $PSItem.ReleaseType -eq 'FeaturePack' -and $PSItem.PackageName -notlike "*20H2Enablement*" -and $PSItem.PackageName -notlike "*LanguageFeatures-Basic*" -and $PSItem.PackageName -notlike "*LanguageFeatures-TextToSpeech*" -and $PSItem.PackageState -eq 'Installed' } | Select-Object -Property PackageName, ReleaseType | Sort-Object -Property PackageName | Out-GridView -Title "Remove Windows Packages." -PassThru
+
+ $WindowsPackages = Get-OtherWindowsPackages -Path $InstallMount -ScratchDirectory $ScratchFolder -LogPath $DISMLog
+
If ($WindowsPackages)
{
+ $packagesToRemove = [System.Collections.ArrayList]@()
Try
{
- $WindowsPackages | ForEach-Object -Process {
+
+ Switch ($PSBoundParameters.Packages) {
+ 'Select'
+ {
+ $packagesToRemove = $WindowsPackages | Out-GridView -Title "Remove Windows Packages." -PassThru
+ Break
+ }
+ 'Whitelist'
+ {
+
+ If (Test-Path -Path $OptimizeOffline.Lists.PackagesList)
+ {
+ $PackageNames = Get-Content -Path $OptimizeOffline.Lists.PackagesList -Raw -ErrorAction Stop | ConvertFrom-Json -ErrorAction Stop | Select-Object -ExpandProperty PackageName
+
+ $WindowsPackages | ForEach-Object -Process {
+ $ToRemove = $true
+ Foreach($PackageName in $PackageNames){
+ If ($PSItem.PackageName -eq $PackageName -or ($PackageName -Match "\*" -and $PSItem.PackageName -like $PackageName))
+ {
+ $ToRemove = $false
+ Break
+ }
+ }
+ If($ToRemove){
+ [void]$packagesToRemove.Add($PSItem)
+ }
+ }
+ }
+ Break
+ }
+ 'Blacklist'
+ {
+
+ If (Test-Path -Path $OptimizeOffline.Lists.PackagesList)
+ {
+ $PackageNames = Get-Content -Path $OptimizeOffline.Lists.PackagesList -Raw -ErrorAction Stop | ConvertFrom-Json -ErrorAction Stop | Select-Object -ExpandProperty PackageName
+
+ $WindowsPackages | ForEach-Object -Process {
+ Foreach($PackageName in $PackageNames){
+ If ($PSItem.PackageName -eq $PackageName -or ($PackageName -Match "\*" -and $PSItem.PackageName -like $PackageName))
+ {
+ [void]$packagesToRemove.Add($PSItem)
+ Break
+ }
+ }
+ }
+ }
+ Break
+ }
+ 'All'
+ {
+ $packagesToRemove = $WindowsPackages
+ }
+ }
+
+ $packagesToRemove | ForEach-Object -Process {
$RemovePackageParams = @{
Path = $InstallMount
PackageName = $PSItem.PackageName
@@ -836,10 +1393,10 @@ Function Optimize-Offline
LogLevel = 1
ErrorAction = 'Stop'
}
- Log ($OptimizeData.RemovingWindowsPackage -f $PSItem.PackageName.Replace('Package', $null).Split('~')[0].TrimEnd('-'))
+ Log ($OptimizeData.RemovingWindowsPackage -f $PSItem.PackageName)
[Void](Remove-WindowsPackage @RemovePackageParams)
}
- $DynamicParams.Packages = $true
+ $DynamicParams.Packages = $($packagesToRemove.Count -gt 0)
}
Catch
{
@@ -852,9 +1409,6 @@ Function Optimize-Offline
#endregion Windows Capability and Cabinet File Package Removal
#region Disable Unsafe Optional Features
- <#
- @('SMB1Protocol', 'MicrosoftWindowsPowerShellV2Root') | ForEach-Object -Process { Get-WindowsOptionalFeature -Path $InstallMount -FeatureName $PSItem -ScratchDirectory $ScratchFolder -LogPath $DISMLog -LogLevel 1 | Where-Object -Property State -EQ Disabled | Disable-WindowsOptionalFeature -Path $InstallMount -Remove -NoRestart -ScratchDirectory $ScratchFolder -LogPath $DISMLog -LogLevel 1 }
- #>
ForEach ($Feature In @('SMB1Protocol', 'MicrosoftWindowsPowerShellV2Root'))
{
If (Get-WindowsOptionalFeature -Path $InstallMount -FeatureName $Feature -ScratchDirectory $ScratchFolder -LogPath $DISMLog -LogLevel 1 | Where-Object -Property State -EQ Enabled)
@@ -884,16 +1438,46 @@ Function Optimize-Offline
#endregion Disable Unsafe Optional Features
#region Disable/Enable Optional Features
- If ($Features.IsPresent)
+ If ($FeaturesToDisable -in $AllowedRemovalOptions)
{
Clear-Host
$Host.UI.RawUI.WindowTitle = "Disable Optional Features."
- $DisableFeatures = Get-WindowsOptionalFeature -Path $InstallMount -ScratchDirectory $ScratchFolder -LogPath $DISMLog -LogLevel 1 | Where-Object -Property State -EQ Enabled | Select-Object -Property FeatureName, State | Sort-Object -Property FeatureName | Out-GridView -Title "Disable Optional Features." -PassThru
- If ($DisableFeatures)
- {
+
+ $EnabledFeatures = Get-OptionalEnabledFeatures -Path $InstallMount -ScratchDirectory $ScratchFolder -LogPath $DISMLog
+
+ If ($EnabledFeatures)
+ {
+ $FeaturesToDisableList = [System.Collections.ArrayList]@()
+ Switch ($PSBoundParameters.FeaturesToDisable) {
+ 'Select'
+ {
+ $FeaturesToDisableList = $EnabledFeatures | Out-GridView -Title "Disable Optional Features." -PassThru
+ Break
+ }
+ "List"
+ {
+ If (Test-Path -Path $OptimizeOffline.Lists.FeaturesToDisableList)
+ {
+ $JSON = Get-Content -Path $OptimizeOffline.Lists.FeaturesToDisableList -Raw -ErrorAction Stop | ConvertFrom-Json -ErrorAction Stop
+
+ $EnabledFeatures | ForEach-Object -Process {
+ If ($PSItem.FeatureName -in $JSON.FeatureName)
+ {
+ [void]$FeaturesToDisableList.Add($PSItem)
+ }
+ }
+ }
+
+ Break
+ }
+ 'All'
+ {
+ $FeaturesToDisableList = $EnabledFeatures
+ }
+ }
Try
{
- $DisableFeatures | ForEach-Object -Process {
+ $FeaturesToDisableList | ForEach-Object -Process {
$DisableFeatureParams = @{
Path = $InstallMount
FeatureName = $PSItem.FeatureName
@@ -907,7 +1491,7 @@ Function Optimize-Offline
Log ($OptimizeData.DisablingOptionalFeature -f $PSItem.FeatureName)
[Void](Disable-WindowsOptionalFeature @DisableFeatureParams)
}
- $DynamicParams.DisabledOptionalFeatures = $true
+ $DynamicParams.DisabledOptionalFeatures = $($FeaturesToDisableList.Count -gt 0)
}
Catch
{
@@ -916,14 +1500,50 @@ Function Optimize-Offline
}
$Host.UI.RawUI.WindowTitle = $null; Clear-Host
}
+ }
+ if ($FeaturesToEnable -in $AllowedRemovalOptions){
Clear-Host
$Host.UI.RawUI.WindowTitle = "Enable Optional Features."
- $EnableFeatures = Get-WindowsOptionalFeature -Path $InstallMount -ScratchDirectory $ScratchFolder -LogPath $DISMLog -LogLevel 1 | Where-Object { $PSItem.FeatureName -notlike "SMB1Protocol*" -and $PSItem.FeatureName -ne "Windows-Defender-Default-Definitions" -and $PSItem.FeatureName -notlike "MicrosoftWindowsPowerShellV2*" -and $PSItem.State -eq "Disabled" } | Select-Object -Property FeatureName, State | Sort-Object -Property FeatureName | Out-GridView -Title "Enable Optional Features." -PassThru
- If ($EnableFeatures)
+
+ $DisabledFeatures = Get-OptionalDisabledFeatures -Path $InstallMount -ScratchDirectory $ScratchFolder -LogPath $DISMLog
+
+ If ($DisabledFeatures)
{
+
+ $FeaturesToEnableList = [System.Collections.ArrayList]@()
+
+ Switch ($PSBoundParameters.FeaturesToEnable) {
+ 'Select'
+ {
+ $FeaturesToEnableList = $DisabledFeatures | Out-GridView -Title "Enable Optional Features." -PassThru
+
+ Break
+ }
+ "List"
+ {
+ If (Test-Path -Path $OptimizeOffline.Lists.FeaturesToEnableList)
+ {
+ $JSON = Get-Content -Path $OptimizeOffline.Lists.FeaturesToEnableList -Raw -ErrorAction Stop | ConvertFrom-Json -ErrorAction Stop
+
+ $DisabledFeatures | ForEach-Object -Process {
+ If ($PSItem.FeatureName -in $JSON.FeatureName)
+ {
+ [void]$FeaturesToEnableList.Add($PSItem)
+ }
+ }
+ }
+
+ Break
+ }
+ "All"
+ {
+ $FeaturesToEnableList = $DisabledFeatures
+ }
+ }
+
Try
{
- $EnableFeatures | ForEach-Object -Process {
+ $FeaturesToEnableList | ForEach-Object -Process {
$EnableFeatureParams = @{
Path = $InstallMount
FeatureName = $PSItem.FeatureName
@@ -938,7 +1558,7 @@ Function Optimize-Offline
Log ($OptimizeData.EnablingOptionalFeature -f $PSItem.FeatureName)
[Void](Enable-WindowsOptionalFeature @EnableFeatureParams)
}
- $DynamicParams.EnabledOptionalFeatures = $true
+ $DynamicParams.EnabledOptionalFeatures = $($FeaturesToEnableList.Count -gt 0)
}
Catch
{
@@ -950,6 +1570,89 @@ Function Optimize-Offline
}
#endregion Disable/Enable Optional Features
+ #region disable windows services
+ if ($PSBoundParameters.Services -in $AllowedRemovalOptions){
+ $ServicesToRemove = [System.Collections.ArrayList]@()
+ $ServicesToRemoveNames = @{}
+ $StartValues = @(0,1,2,3,4)
+
+ Clear-Host
+ $Host.UI.RawUI.WindowTitle = $OptimizeData.ServicesModifying
+
+ Try{
+ RegHives -Load
+
+ Switch($PSBoundParameters.Services){
+ "List"
+ {
+ $JSON = Get-Content -Path $OptimizeOffline.Lists.ServicesList -Raw -ErrorAction Stop | ConvertFrom-Json -ErrorAction Stop
+
+ $JSON.Services | ForEach-Object -Process {
+ If (Test-Path -Path "HKLM:\WIM_HKLM_SYSTEM\ControlSet001\Services\$($PSItem)")
+ {
+ $FolderKeys = Get-ItemProperty -Path "HKLM:\WIM_HKLM_SYSTEM\ControlSet001\Services\$($PSItem)"
+
+ If($null -ne $FolderKeys.Start){
+ [void]$ServicesToRemove.Add(@{
+ name = $PSItem
+ start = 4
+ })
+ }
+
+ }
+ }
+ }
+ "Advanced"
+ {
+ $JSON = Get-Content -Path $OptimizeOffline.Lists.ServicesAdvanced -Raw -ErrorAction Stop | ConvertFrom-Json -ErrorAction Stop
+
+ $JSON.Services | ForEach-Object -Process {
+ If (Test-Path -Path "HKLM:\WIM_HKLM_SYSTEM\ControlSet001\Services\$($PSItem.name)")
+ {
+ $FolderKeys = Get-ItemProperty -Path "HKLM:\WIM_HKLM_SYSTEM\ControlSet001\Services\$($PSItem.name)"
+
+ If($null -eq $PSItem.start) {
+ $PSItem.start = 4
+ }
+
+ If($null -ne $FolderKeys.Start -and [int]$PSItem.start -in $StartValues){
+ [void]$ServicesToRemove.Add($PSItem)
+ }
+
+ }
+ }
+ }
+ "Select"
+ {
+ $ServicesToRemove = Get-ImageServices | Out-GridView -PassThru -Title $OptimizeData.ChooseServicesTitle
+ }
+ }
+
+ $ServicesToRemove | ForEach-Object -Process {
+ $Start = If ($PSBoundParameters.Services -eq "Select") {4} Else {[Int]$PSItem.start}
+ Log "$($OptimizeData.ServiceModifying): $($PSItem.name), Start: $($OptimizeOffline.ServicesStartLabels[$Start])"
+ RegKey -Path "HKLM:\WIM_HKLM_SYSTEM\ControlSet001\Services\$($PSItem.name)" -Name "Start" -Type DWord -Value $Start
+ $ServicesToRemoveNames[$PSItem.name] = $Start
+ Start-Sleep 1
+ }
+ $DynamicParams.DisabledWindowsServices = $($ServicesToRemove.Count -gt 0)
+
+ # If the Delivery Optimization service has a SetState value of 'Disabled' in the Services.json file, set the delivery optimization download mode to bypass.
+ If ($null -ne $ServicesToRemoveNames['DoSvc'] -and $ServicesToRemoveNames['DoSvc'] -eq 4){
+ Log $OptimizeData.DeliveryOptimizationBypass
+ RegKey -Path "HKLM:\WIM_HKLM_SOFTWARE\Microsoft\Windows\CurrentVersion\DeliveryOptimization\Config" -Name "DODownloadMode" -Type DWord -Value 100
+ Start-Sleep 1
+ }
+ RegHives -Unload
+ } Catch {
+ Log $OptimizeData.ServicesRemovalFailed -Type Error -ErrorRecord $Error[0]
+ Stop-Optimize
+ }
+
+ $Host.UI.RawUI.WindowTitle = $null; Clear-Host
+ }
+ #endregion disable windows services
+
#region DeveloperMode Integration
If ($DeveloperMode.IsPresent -and (Test-Path -Path $OptimizeOffline.DevMode -Filter *DeveloperMode-Desktop-Package*.cab) -and !(Get-WindowsPackage -Path $InstallMount -ScratchDirectory $ScratchFolder -LogPath $DISMLog -LogLevel 1 | Where-Object -Property PackageName -Like *DeveloperMode*))
{
@@ -978,21 +1681,27 @@ Function Optimize-Offline
#endregion DeveloperMode Integration
#region Windows Store Integration
- If ($WindowsStore.IsPresent -and (Test-Path -Path $OptimizeOffline.WindowsStore -Filter Microsoft.WindowsStore*.appxbundle) -and !(Get-AppxProvisionedPackage -Path $InstallMount -ScratchDirectory $ScratchFolder -LogPath $DISMLog -LogLevel 1 | Where-Object -Property DisplayName -EQ Microsoft.WindowsStore))
+ $DynamicParams.WindowsStore = ($AppxPackages | Where-Object -Property DisplayName -EQ Microsoft.WindowsStore)
+ $DynamicParams.DisableDeliveryOptimization = (!$DynamicParams.WindowsStore -and $($AppxPackages | Where-Object -Property DisplayName -eq "Microsoft.DesktopAppInstaller").Count -eq 0)
+ If ($WindowsStore.IsPresent -and (Test-Path -Path $OptimizeOffline.WindowsStore -Filter Microsoft.WindowsStore*.*xbundle) -and !$DynamicParams.WindowsStore)
{
Log $OptimizeData.IntegratingWindowsStore
- $StoreBundle = Get-ChildItem -Path $OptimizeOffline.WindowsStore -Filter Microsoft.WindowsStore*.appxbundle -File | Select-Object -ExpandProperty FullName
- $PurchaseBundle = Get-ChildItem -Path $OptimizeOffline.WindowsStore -Filter Microsoft.StorePurchaseApp*.appxbundle -File | Select-Object -ExpandProperty FullName
- $XboxBundle = Get-ChildItem -Path $OptimizeOffline.WindowsStore -Filter Microsoft.XboxIdentityProvider*.appxbundle -File | Select-Object -ExpandProperty FullName
- $InstallerBundle = Get-ChildItem -Path $OptimizeOffline.WindowsStore -Filter Microsoft.DesktopAppInstaller*.appxbundle -File | Select-Object -ExpandProperty FullName
+ $StoreBundle = Get-ChildItem -Path $OptimizeOffline.WindowsStore -Filter Microsoft.WindowsStore*.*xbundle -File | Select-Object -ExpandProperty FullName
+ $PurchaseBundle = Get-ChildItem -Path $OptimizeOffline.WindowsStore -Filter Microsoft.StorePurchaseApp*.*xbundle -File | Select-Object -ExpandProperty FullName
+ $XboxBundle = Get-ChildItem -Path $OptimizeOffline.WindowsStore -Filter Microsoft.XboxIdentityProvider*.*xbundle -File | Select-Object -ExpandProperty FullName
+ $InstallerBundle = Get-ChildItem -Path $OptimizeOffline.WindowsStore -Filter Microsoft.DesktopAppInstaller*.*xbundle -File | Select-Object -ExpandProperty FullName
$StoreLicense = Get-ChildItem -Path $OptimizeOffline.WindowsStore -Filter Microsoft.WindowsStore*.xml -File | Select-Object -ExpandProperty FullName
$PurchaseLicense = Get-ChildItem -Path $OptimizeOffline.WindowsStore -Filter Microsoft.StorePurchaseApp*.xml -File | Select-Object -ExpandProperty FullName
$XboxLicense = Get-ChildItem -Path $OptimizeOffline.WindowsStore -Filter Microsoft.XboxIdentityProvider*.xml -File | Select-Object -ExpandProperty FullName
$InstallerLicense = Get-ChildItem -Path $OptimizeOffline.WindowsStore -Filter Microsoft.DesktopAppInstaller*.xml -File | Select-Object -ExpandProperty FullName
- $DependencyPackages = [Collections.Generic.List[String]]::New()
- $DependencyPackages = Get-ChildItem -Path $OptimizeOffline.WindowsStore -Filter Microsoft.VCLibs*.appx -File | Select-Object -ExpandProperty FullName
- $DependencyPackages += Get-ChildItem -Path $OptimizeOffline.WindowsStore -Filter *Native.Framework*.appx -File | Select-Object -ExpandProperty FullName
- $DependencyPackages += Get-ChildItem -Path $OptimizeOffline.WindowsStore -Filter *Native.Runtime*.appx -File | Select-Object -ExpandProperty FullName
+
+ $DependencyVCLibs = Get-ChildItem -Path $OptimizeOffline.WindowsStore -Filter Microsoft.VCLibs.140.00_*.appx -File | Select-Object -ExpandProperty FullName
+ $DependencyVCLibsUWPDesktop = Get-ChildItem -Path $OptimizeOffline.WindowsStore -Filter Microsoft.VCLibs.140.00.UWPDesktop_*.appx -File | Select-Object -ExpandProperty FullName
+ $DependencyXAML26 = Get-ChildItem -Path $OptimizeOffline.WindowsStore -Filter Microsoft.UI.Xaml.2.6_*.appx -File | Select-Object -ExpandProperty FullName
+ $DependencyXAML27 = Get-ChildItem -Path $OptimizeOffline.WindowsStore -Filter Microsoft.UI.Xaml.2.7_*.appx -File | Select-Object -ExpandProperty FullName
+ $DependencyNativeFramework = Get-ChildItem -Path $OptimizeOffline.WindowsStore -Filter Microsoft.NET.Native.Framework*.appx -File | Select-Object -ExpandProperty FullName
+ $DependencyNativeRuntime = Get-ChildItem -Path $OptimizeOffline.WindowsStore -Filter Microsoft.NET.Native.Runtime*.appx -File | Select-Object -ExpandProperty FullName
+
If (!$DynamicParams.DeveloperMode)
{
RegHives -Load
@@ -1001,6 +1710,11 @@ Function Optimize-Offline
}
Try
{
+ $DependencyPackages = [Collections.Generic.List[String]]::New()
+ $DependencyPackages += $DependencyNativeFramework
+ $DependencyPackages += $DependencyNativeRuntime
+ $DependencyPackages += $DependencyVCLibs
+ $DependencyPackages += $DependencyXAML27
$StorePackage = @{
Path = $InstallMount
PackagePath = $StoreBundle
@@ -1012,41 +1726,60 @@ Function Optimize-Offline
ErrorAction = 'Stop'
}
[Void](Add-AppxProvisionedPackage @StorePackage)
- $PurchasePackage = @{
- Path = $InstallMount
- PackagePath = $PurchaseBundle
- DependencyPackagePath = $DependencyPackages
- LicensePath = $PurchaseLicense
- ScratchDirectory = $ScratchFolder
- LogPath = $DISMLog
- LogLevel = 1
- ErrorAction = 'Stop'
+
+ If ($PurchaseBundle -and $PurchaseLicense) {
+ $DependencyPackages = [Collections.Generic.List[String]]::New()
+ $DependencyPackages += $DependencyNativeFramework
+ $DependencyPackages += $DependencyNativeRuntime
+ $DependencyPackages += $DependencyVCLibs
+ $PurchasePackage = @{
+ Path = $InstallMount
+ PackagePath = $PurchaseBundle
+ DependencyPackagePath = $DependencyPackages
+ LicensePath = $PurchaseLicense
+ ScratchDirectory = $ScratchFolder
+ LogPath = $DISMLog
+ LogLevel = 1
+ ErrorAction = 'Stop'
+ }
+ [Void](Add-AppxProvisionedPackage @PurchasePackage)
}
- [Void](Add-AppxProvisionedPackage @PurchasePackage)
- $XboxPackage = @{
- Path = $InstallMount
- PackagePath = $XboxBundle
- DependencyPackagePath = $DependencyPackages
- LicensePath = $XboxLicense
- ScratchDirectory = $ScratchFolder
- LogPath = $DISMLog
- LogLevel = 1
- ErrorAction = 'Stop'
+
+ If ($XboxBundle -and $XboxLicense) {
+ $DependencyPackages = [Collections.Generic.List[String]]::New()
+ $DependencyPackages += $DependencyNativeFramework
+ $DependencyPackages += $DependencyNativeRuntime
+ $DependencyPackages += $DependencyVCLibs
+ $XboxPackage = @{
+ Path = $InstallMount
+ PackagePath = $XboxBundle
+ DependencyPackagePath = $DependencyPackages
+ LicensePath = $XboxLicense
+ ScratchDirectory = $ScratchFolder
+ LogPath = $DISMLog
+ LogLevel = 1
+ ErrorAction = 'Stop'
+ }
+ [Void](Add-AppxProvisionedPackage @XboxPackage)
}
- [Void](Add-AppxProvisionedPackage @XboxPackage)
- $DependencyPackages.Clear()
- $DependencyPackages = Get-ChildItem -Path $OptimizeOffline.WindowsStore -Filter *Native.Runtime*.appx -File | Select-Object -ExpandProperty FullName
- $InstallerPackage = @{
- Path = $InstallMount
- PackagePath = $InstallerBundle
- DependencyPackagePath = $DependencyPackages
- LicensePath = $InstallerLicense
- ScratchDirectory = $ScratchFolder
- LogPath = $DISMLog
- LogLevel = 1
- ErrorAction = 'Stop'
+
+
+ If ($InstallerBundle -and $InstallerLicense -and $DependencyVCLibsUWPDesktop -and $DependencyXAML26) {
+ $DependencyPackages = [Collections.Generic.List[String]]::New()
+ $DependencyPackages += $DependencyVCLibsUWPDesktop
+ $DependencyPackages += $DependencyXAML26
+ $InstallerPackage = @{
+ Path = $InstallMount
+ PackagePath = $InstallerBundle
+ DependencyPackagePath = $DependencyPackages
+ LicensePath = $InstallerLicense
+ ScratchDirectory = $ScratchFolder
+ LogPath = $DISMLog
+ LogLevel = 1
+ ErrorAction = 'Stop'
+ }
+ [Void](Add-AppxProvisionedPackage @InstallerPackage)
}
- [Void](Add-AppxProvisionedPackage @InstallerPackage)
$DynamicParams.WindowsStore = $true
}
Catch
@@ -1164,7 +1897,7 @@ Function Optimize-Offline
[IO.File]::WriteAllText((GetPath -Path $EdgeAppPath.FullName -Child master_preferences), (@'
{"distribution":{"system_level":true,"do_not_create_desktop_shortcut":true,"do_not_create_quick_launch_shortcut":true,"do_not_create_taskbar_shortcut":true}}
'@).Trim(), [Text.UTF8Encoding]::New($true))
- $Base64String = [Convert]::ToBase64String([Text.Encoding]::Unicode.GetBytes( { Get-ChildItem -Path @("HKLM:\SOFTWARE\Microsoft\Active Setup\Installed Components", "HKLM:\SOFTWARE\WOW6432Node\Microsoft\Active Setup\Installed Components") -Recurse | Get-ItemProperty | Select-Object -Property PSPath, StubPath | Where-Object -Property StubPath -Match configure-user-settings | ForEach-Object -Process { Remove-Item -Path $PSItem.PSPath -Force }; Get-ChildItem -Path "$Env:SystemDrive\Users\*\Desktop" -Filter *lnk -Recurse | Where-Object -Property Name -Like *Edge* | Remove-Item -Force }))
+ $Base64String = [Convert]::ToBase64String([Text.Encoding]::Unicode.GetBytes({ Get-ChildItem -Path @("HKLM:\SOFTWARE\Microsoft\Active Setup\Installed Components", "HKLM:\SOFTWARE\WOW6432Node\Microsoft\Active Setup\Installed Components") -Recurse | Get-ItemProperty | Select-Object -Property PSPath, StubPath | Where-Object -Property StubPath -Match configure-user-settings | ForEach-Object -Process { Remove-Item -Path $PSItem.PSPath -Force }; Get-ChildItem -Path "$Env:SystemDrive\Users\*\Desktop" -Filter *lnk -Recurse | Where-Object -Property Name -Like *Edge* | Remove-Item -Force }))
RegKey -Path "HKLM:\WIM_HKLM_SOFTWARE\Microsoft\Windows\CurrentVersion\RunOnce" -Name "EdgeCleanup" -Value "%SYSTEMROOT%\System32\WindowsPowerShell\v1.0\powershell.exe -ExecutionPolicy Bypass -NoProfile -EncodedCommand $Base64String" -Type ExpandString
RegKey -Path "HKLM:\WIM_HKLM_SOFTWARE\Policies\Microsoft\EdgeUpdate" -Name "CreateDesktopShortcutDefault" -Value 0 -Type DWord
RegKey -Path "HKLM:\WIM_HKLM_SOFTWARE\WOW6432Node\Policies\Microsoft\EdgeUpdate" -Name "CreateDesktopShortcutDefault" -Value 0 -Type DWord
@@ -1172,6 +1905,7 @@ Function Optimize-Offline
RegKey -Path "HKLM:\WIM_HKLM_SOFTWARE\WOW6432Node\Policies\Microsoft\Edge" -Name "HideFirstRunExperience" -Value 1 -Type DWord
RegKey -Path "HKLM:\WIM_HKLM_SOFTWARE\Policies\Microsoft\Edge" -Name "BackgroundModeEnabled" -Value 0 -Type DWord
RegKey -Path "HKLM:\WIM_HKLM_SOFTWARE\WOW6432Node\Policies\Microsoft\Edge" -Name "BackgroundModeEnabled" -Value 0 -Type DWord
+ If (($InstallInfo.Build -eq '19041' -and (Get-ItemPropertyValue -Path "HKLM:\WIM_HKLM_SOFTWARE\Microsoft\Windows NT\CurrentVersion" -Name UBR -ErrorAction Ignore) -ge 1023) -or $InstallInfo.Build -gt '19041') { RegKey -Path "HKLM:\WIM_HKLM_SOFTWARE\Policies\Microsoft\Windows\Windows Feeds" -Name "EnableFeeds" -Value 0 -Type DWord }
}
RegHives -Unload
}
@@ -1298,6 +2032,7 @@ Function Optimize-Offline
17763 { 'RS5'; Break }
18362 { '19H2'; Break }
19041 { '20H1'; Break }
+ default { 'Insider'; Break }
}
If ($DaRT.Contains('Setup') -and $DynamicParams.BootImage)
{
@@ -1443,7 +2178,7 @@ Function Optimize-Offline
}
If ($Additional.RegistryTemplates -and (Test-Path -Path (GetPath -Path $OptimizeOffline.RegistryTemplates -Child *.reg)))
{
- Import-RegistryTemplates
+ Import-Registry -Path $OptimizeOffline.RegistryTemplates
Start-Sleep 3
}
If ($Additional.LayoutModification -and (Test-Path -Path (GetPath -Path $OptimizeOffline.LayoutModification -Child *.xml)))
@@ -1463,10 +2198,29 @@ Function Optimize-Offline
Start-Sleep 3
}
}
+ If ($Additional.LayoutModification -and $InstallInfo.Build -ge "22000" -and (Test-Path -Path (GetPath -Path $OptimizeOffline.LayoutModification -Child *.json)))
+ {
+ Try
+ {
+ Log $OptimizeData.ApplyingLayoutModification
+ Copy-Item -Path (GetPath -Path $OptimizeOffline.LayoutModification -Child *.json) -Destination (GetPath -Path $InstallMount -Child 'Users\Default\AppData\Local\Microsoft\Windows\Shell\LayoutModification.json') -Force -ErrorAction Stop
+ $DynamicParams.LayoutModification = $true
+ }
+ Catch
+ {
+ Log $OptimizeData.FailedApplyingLayoutModification -Type Error -ErrorRecord $Error[0]
+ }
+ Finally
+ {
+ Start-Sleep 3
+ }
+ }
If ($Additional.Unattend -and (Test-Path -Path (GetPath -Path $OptimizeOffline.Unattend -Child unattend.xml)))
{
Try
{
+ Unblock-File -Path (GetPath -Path $OptimizeOffline.Unattend -Child unattend.xml)
+ Log $OptimizeData.ApplyingAnswerFile
$ApplyUnattendParams = @{
UnattendPath = '{0}\unattend.xml' -f $OptimizeOffline.Unattend
Path = $InstallMount
@@ -1475,7 +2229,6 @@ Function Optimize-Offline
LogLevel = 1
ErrorAction = 'Stop'
}
- Log $OptimizeData.ApplyingAnswerFile
[Void](Use-WindowsUnattend @ApplyUnattendParams)
(GetPath -Path $InstallMount -Child 'Windows\Panther') | Create
Copy-Item -Path (GetPath -Path $OptimizeOffline.Unattend -Child unattend.xml) -Destination (GetPath -Path $InstallMount -Child 'Windows\Panther') -Force
@@ -1489,7 +2242,10 @@ Function Optimize-Offline
}
If ($Additional.Drivers)
{
- Get-ChildItem -Path $OptimizeOffline.Drivers -Recurse -Force | ForEach-Object -Process { $PSItem.Attributes = 0x80 }
+ Get-ChildItem -Path $OptimizeOffline.Drivers -Recurse -Force | ForEach-Object -Process {
+ Unblock-File -Path $PSItem.FullName
+ Set-ItemProperty -Path $PSItem.FullName -Name IsReadOnly -Value $false -ErrorAction Ignore
+ }
If (Get-ChildItem -Path $OptimizeOffline.InstallDrivers -Include *.inf -Recurse -Force)
{
Try
@@ -1591,22 +2347,33 @@ Function Optimize-Offline
}
}
#endregion Additional Content Integration
-
+ #region selective registry
+ Get-ChildItem -Path $OptimizeOffline.SelectiveRegistry -Filter *.ps1 -Recurse | ForEach-Object -Process {
+ & $_.FullName
+ }
+ #endregion selective registry
+ #region custom registry
+ If (Test-Path -Path $OptimizeOffline.CustomRegistry)
+ {
+ Import-Registry -Path $OptimizeOffline.CustomRegistry
+ Start-Sleep 3
+ }
+ #endregion custom registry
#region Component Store Clean-up
If ($ComponentCleanup.IsPresent)
{
If (!(Test-Path -Path (GetPath -Path $InstallMount -Child 'Windows\WinSxS\pending.xml')))
{
Log ($OptimizeData.ComponentStoreCleanup -f $InstallInfo.Name)
- If ($InstallInfo.Build -ge '18362') { $RegClean = 3 }
- Else { $RegClean = 0 }
+ If ($InstallInfo.Build -ge '18362') { $RegClean = 3 } Else { $RegClean = 0 }
RegHives -Load
RegKey -Path "HKLM:\WIM_HKLM_SOFTWARE\Microsoft\Windows\CurrentVersion\SideBySide\Configuration" -Name "DisableResetbase" -Value 1 -Type DWord
RegKey -Path "HKLM:\WIM_HKLM_SOFTWARE\Microsoft\Windows\CurrentVersion\SideBySide\Configuration" -Name "SupersededActions" -Value $RegClean -Type DWord
RegHives -Unload
+ $CleanupLog = (GetPath -Path $LogFolder -Child ComponentCleanup.log)
Try
{
- $RET = StartExe $DISM -Arguments ('/Image:"{0}" /Cleanup-Image /StartComponentCleanup /ScratchDir:"{1}" /LogPath:"{2}" /LogLevel:1' -f $InstallMount, $ScratchFolder, $DISMLog) -ErrorAction Stop
+ $RET = StartExe $DISM -Arguments ('/Image:"{0}" /Cleanup-Image /StartComponentCleanup /ScratchDir:"{1}" /LogPath:"{2}" /LogLevel:1' -f $InstallMount, $ScratchFolder, $CleanupLog) -ErrorAction Stop
If ($RET -eq 0) { $DynamicParams.ComponentCleanup = $true }
Else { Throw }
}
@@ -1614,6 +2381,10 @@ Function Optimize-Offline
{
Log ($OptimizeData.FailedComponentStoreCleanup -f $InstallInfo.Name) -Type Error
}
+ Finally
+ {
+ $CleanupLog | Purge -ErrorAction Ignore
+ }
}
Else
{
@@ -1623,7 +2394,7 @@ Function Optimize-Offline
#endregion Component Store Clean-up
#region Start Menu Clean-up
- If (!$DynamicParams.LayoutModification)
+ If (!$DynamicParams.LayoutModification -and $InstallInfo.Build -le '19044')
{
$LayoutTemplate = @"
9NBLGGH4NNS1microsoft.desktopappinstaller_8wekyb3d8bbwee1a39502-1ffc-44f0-8c28-0034168e09ff2c3f1d47-426d-c7d7-face-ef1add208818False2016-04-14T15:58:20.6111541Z2016-04-14T15:58:20.4032196Z2016-04-14T15:58:20.4032196ZFAAAAMAAAADJAAAACgAAAAMAAQAdvg9XAgDLAAAAEAAAAK/8fFGLE5YXLOpiiSIEJQrOAAAAWAAAAG0AaQBjAHIAbwBzAG8AZgB0AC4AZABlAHMAawB0AG8AcABhAHAAcABpAG4AcwB0AGEAbABsAGUAcgBfADgAdwBlAGsAeQBiADMAZAA4AGIAYgB3AGUAAADNAAAAIgAAAAEAPHRzkyJyTeprvahJYVs0C0HSgOyvT4hrOkNjQkRP3ZkgAAAABAAAABy+D1fMAAAARAAAAAEAAgBIa5/IGWUu4VPS25nTkLR8ppTVf6vcPSq/gcYDNJ9lN2zTLbFu6TvvW9vRaJ+VeOW+RRkKhoksVH7Pt7QD1r6bgFx+w8DBVQVIbEe2VcpuymyNmZ2W4wEaZRbCfq2+g9k=eLMrCQLsZziDD7p7OTk+r0/1PlW/QvNCd1tuouOIatqECfL1vw0ssHqzwztfAKlLvpaQ1NnB6MlW4wBdOziLQs6TNUNIseASPZWl9s/0qUb85+BpOoFPt+A2t0C0+1Y33UqlpBsXOLndXgySGorBjbRBEDrpX4HFrOfuyGkUSbMVFgSr0H6xXRbLJmYTId0Oy2bPCpRfTqDwqS1x71+IDSBel8I8fs6UHYdYhGvFVqiOtg2+eeuD5pd6I5wiYLIXkfzu6/66QDT7kR1LJ+zgEJCFfauUft1vUIYjTj4evPLZUXRrK7ff8ktfaoppD3o7ToN4C3XSik9HzcsEfhLeUg==oVSJXItDsaAIfwyR9bhh/ZSppCAO+in9POLWdC2/TQodgeHZzbdBvxJvKhpbrq6ZP0FsSElLwRoLAmv7zIuVw3Vb7tfQt5bjCDHRAG9fesNlYKV3ybyNrHyzglfZPRB5UJZw32yi03zQa+LLa05fjs6joEmlHc5BrGQrGrbNMBahz4cmuxKC4/dhEb7JZFUkc0MRhs/M3Ve511HQfKuG+92g1OffJdRsAPzWRdskPoN35knnqno7F85OBmGV/LNBgdtDWUH6di1eUCQFeKGfMp+Q/LFUX9jawTTEPn72tYbpYASug05Skcg6KTHlcLGzevxGw7BYsOsqfDka5n0YGw==AAEAAQ==
\ No newline at end of file
diff --git a/Packages/WindowsStore/Microsoft.NET.Native.Framework.2.2_2.2.27912.0_x64__8wekyb3d8bbwe.Appx b/Packages/WindowsStore/Microsoft.NET.Native.Framework.2.2_2.2.27912.0_x64__8wekyb3d8bbwe.Appx
deleted file mode 100644
index 072ccf4..0000000
Binary files a/Packages/WindowsStore/Microsoft.NET.Native.Framework.2.2_2.2.27912.0_x64__8wekyb3d8bbwe.Appx and /dev/null differ
diff --git a/Packages/WindowsStore/Microsoft.NET.Native.Framework.2.2_2.2.27912.0_x86__8wekyb3d8bbwe.Appx b/Packages/WindowsStore/Microsoft.NET.Native.Framework.2.2_2.2.27912.0_x86__8wekyb3d8bbwe.Appx
deleted file mode 100644
index 2f3e382..0000000
Binary files a/Packages/WindowsStore/Microsoft.NET.Native.Framework.2.2_2.2.27912.0_x86__8wekyb3d8bbwe.Appx and /dev/null differ
diff --git a/Packages/WindowsStore/Microsoft.NET.Native.Runtime.2.2_2.2.28604.0_x64__8wekyb3d8bbwe.Appx b/Packages/WindowsStore/Microsoft.NET.Native.Runtime.2.2_2.2.28604.0_x64__8wekyb3d8bbwe.Appx
deleted file mode 100644
index e70937b..0000000
Binary files a/Packages/WindowsStore/Microsoft.NET.Native.Runtime.2.2_2.2.28604.0_x64__8wekyb3d8bbwe.Appx and /dev/null differ
diff --git a/Packages/WindowsStore/Microsoft.NET.Native.Runtime.2.2_2.2.28604.0_x86__8wekyb3d8bbwe.Appx b/Packages/WindowsStore/Microsoft.NET.Native.Runtime.2.2_2.2.28604.0_x86__8wekyb3d8bbwe.Appx
deleted file mode 100644
index abf125b..0000000
Binary files a/Packages/WindowsStore/Microsoft.NET.Native.Runtime.2.2_2.2.28604.0_x86__8wekyb3d8bbwe.Appx and /dev/null differ
diff --git a/Packages/WindowsStore/Microsoft.StorePurchaseApp_12011.1000.2013.0_neutral_~_8wekyb3d8bbwe.appxbundle b/Packages/WindowsStore/Microsoft.StorePurchaseApp_12011.1000.2013.0_neutral_~_8wekyb3d8bbwe.appxbundle
deleted file mode 100644
index 76ead39..0000000
Binary files a/Packages/WindowsStore/Microsoft.StorePurchaseApp_12011.1000.2013.0_neutral_~_8wekyb3d8bbwe.appxbundle and /dev/null differ
diff --git a/Packages/WindowsStore/Microsoft.StorePurchaseApp_8wekyb3d8bbwe.xml b/Packages/WindowsStore/Microsoft.StorePurchaseApp_8wekyb3d8bbwe.xml
deleted file mode 100644
index 8133602..0000000
--- a/Packages/WindowsStore/Microsoft.StorePurchaseApp_8wekyb3d8bbwe.xml
+++ /dev/null
@@ -1 +0,0 @@
-9NBLGGH4LS1Fmicrosoft.storepurchaseapp_8wekyb3d8bbwea8301a7a-06f7-425e-8fb5-ebfb702440df2c3f1d47-426d-c7d7-face-ef1add208818False2016-04-01T22:02:43.4444915Z2016-04-01T22:02:43.0608594Z2016-04-01T22:02:43.0608594ZFAAAALoAAADJAAAACgAAAAMAAQAD8P5WAgDLAAAAEAAAAAYtUCgpnRSFHl1kRHEW15jOAAAAUgAAAG0AaQBjAHIAbwBzAG8AZgB0AC4AcwB0AG8AcgBlAHAAdQByAGMAaABhAHMAZQBhAHAAcABfADgAdwBlAGsAeQBiADMAZAA4AGIAYgB3AGUAAADNAAAAIgAAAAEAMPDiheq+DxYSDJaaOq7obPBL5IlMNiWK7M2dpI865e8gAAAABAAAAAPw/lbMAAAARAAAAAEAAgCVOMM09off+6NXUn50Ct6Pw0Nc1vQYj/q1lncPdmHi2L06skc87Z+WxfZQmqdsuERDP/S/l3I1ThyK+o9S+73WwnqdrNUltStkbVpNc1Fq5IKTPRvEU6bTBjRLvJ064AE=S0Gc1y9ck1pyaQn0jbLG2eI6Jkw/AjTu9Rpyc1u9qedNB1C5e9jKBLf0B3GTnALSnt87G0dqLZru6kqBLLjXoLUChtxgf4NA8J9MMeQeEWfuFtv1j5rucmvfEsRlU/dKs1q46z7GKzIX0Yl3dAEkbEKAEdUqvdBijjuRDwLckOVz0rBvFZy4qwQ+W2hP0UfgDoHiPdS9vi5VE8odzB0SO/MUxpAT/DuixrWVghqqyU9x+uVMYE9C328mNDTK3bkRiCR/bzl4EsoShTVNxdQrRFnnlB3vaOIUEg5Ge6OkGrYp69M4f82k92rH3OzlQr+qdm2UkKNAMkpI5mrwo2zuGA==oVSJXItDsaAIfwyR9bhh/ZSppCAO+in9POLWdC2/TQodgeHZzbdBvxJvKhpbrq6ZP0FsSElLwRoLAmv7zIuVw3Vb7tfQt5bjCDHRAG9fesNlYKV3ybyNrHyzglfZPRB5UJZw32yi03zQa+LLa05fjs6joEmlHc5BrGQrGrbNMBahz4cmuxKC4/dhEb7JZFUkc0MRhs/M3Ve511HQfKuG+92g1OffJdRsAPzWRdskPoN35knnqno7F85OBmGV/LNBgdtDWUH6di1eUCQFeKGfMp+Q/LFUX9jawTTEPn72tYbpYASug05Skcg6KTHlcLGzevxGw7BYsOsqfDka5n0YGw==AAEAAQ==
\ No newline at end of file
diff --git a/Packages/WindowsStore/Microsoft.VCLibs.140.00_14.0.27810.0_x64__8wekyb3d8bbwe.Appx b/Packages/WindowsStore/Microsoft.VCLibs.140.00_14.0.27810.0_x64__8wekyb3d8bbwe.Appx
deleted file mode 100644
index 7f03af3..0000000
Binary files a/Packages/WindowsStore/Microsoft.VCLibs.140.00_14.0.27810.0_x64__8wekyb3d8bbwe.Appx and /dev/null differ
diff --git a/Packages/WindowsStore/Microsoft.VCLibs.140.00_14.0.27810.0_x86__8wekyb3d8bbwe.Appx b/Packages/WindowsStore/Microsoft.VCLibs.140.00_14.0.27810.0_x86__8wekyb3d8bbwe.Appx
deleted file mode 100644
index 7e4bddd..0000000
Binary files a/Packages/WindowsStore/Microsoft.VCLibs.140.00_14.0.27810.0_x86__8wekyb3d8bbwe.Appx and /dev/null differ
diff --git a/Packages/WindowsStore/Microsoft.WindowsStore_12010.1001.213.0_neutral_~_8wekyb3d8bbwe.appxbundle b/Packages/WindowsStore/Microsoft.WindowsStore_12010.1001.213.0_neutral_~_8wekyb3d8bbwe.appxbundle
deleted file mode 100644
index 6c67162..0000000
Binary files a/Packages/WindowsStore/Microsoft.WindowsStore_12010.1001.213.0_neutral_~_8wekyb3d8bbwe.appxbundle and /dev/null differ
diff --git a/Packages/WindowsStore/Microsoft.WindowsStore_8wekyb3d8bbwe.xml b/Packages/WindowsStore/Microsoft.WindowsStore_8wekyb3d8bbwe.xml
deleted file mode 100644
index 2353283..0000000
--- a/Packages/WindowsStore/Microsoft.WindowsStore_8wekyb3d8bbwe.xml
+++ /dev/null
@@ -1 +0,0 @@
-9WZDNCRFJBMPmicrosoft.windowsstore_8wekyb3d8bbwe20ae9d1d-4b7d-4c35-b7d6-65e31396efd32c3f1d47-426d-c7d7-face-ef1add208818False2015-06-01T18:28:54.3098854Z2015-06-01T18:28:54.3574657Z2015-06-01T18:28:54.3574657ZFAAAALIAAADJAAAACgAAAAMAAQBmpGxVAgDLAAAAEAAAAPH+T+ZG4jK2WVtWB2o/p3bOAAAASgAAAG0AaQBjAHIAbwBzAG8AZgB0AC4AdwBpAG4AZABvAHcAcwBzAHQAbwByAGUAXwA4AHcAZQBrAHkAYgAzAGQAOABiAGIAdwBlAAAAzQAAACIAAAABAAaf7l9Jp21JeRrJKBhcbP6ODp40LTKLpK3I9WgJHJhOIAAAAAQAAABmpGxVzAAAAEQAAAABAAIAHJNoXjtSbcT3K6z4K6PvH4xijDdLWKmaFiS9nm3Qze7YKZpMaHEm1aiE13HD0bKHyHyl5tAXOn8UgIHHFZ8i6g==RRM/4J8WsRpcxBMBpyvG7aUsW0jEomzv7f++SIVEVDc=ZoYDzCjHhwPTGGBopKxKsXIuvKveOvKlLVFi3inlQUSG/4yJELe1Eu/3e02s2ImCRq/Zxkue+bWXcQG/YdD8MtAQ1Q1BcqqhW3/xQt7cRBX/dwE+SVxvyFr+l7kNkzg8r7UtMMTPHmVsdH5rGR6Ej0kEW8eqUvq9Tbs6MpXFOzwIYrqbwu+LEeWfmL1UZ0DgcGBEGRupgEBzxS362H6R//oReEN0OgSWUhMZcGBuI0rJIOICntxhU/dtsksxGwwoVPheAeCAdDvjZlShWERm0T9aQnOdDqhVY96sH0DTB90GVwXZsvzksXSzdSk4rbjHRinXBS/2HHXu49iy3dXBjg==oVSJXItDsaAIfwyR9bhh/ZSppCAO+in9POLWdC2/TQodgeHZzbdBvxJvKhpbrq6ZP0FsSElLwRoLAmv7zIuVw3Vb7tfQt5bjCDHRAG9fesNlYKV3ybyNrHyzglfZPRB5UJZw32yi03zQa+LLa05fjs6joEmlHc5BrGQrGrbNMBahz4cmuxKC4/dhEb7JZFUkc0MRhs/M3Ve511HQfKuG+92g1OffJdRsAPzWRdskPoN35knnqno7F85OBmGV/LNBgdtDWUH6di1eUCQFeKGfMp+Q/LFUX9jawTTEPn72tYbpYASug05Skcg6KTHlcLGzevxGw7BYsOsqfDka5n0YGw==AAEAAQ==
\ No newline at end of file
diff --git a/Packages/WindowsStore/Microsoft.XboxIdentityProvider_12.67.21001.0_neutral_~_8wekyb3d8bbwe.appxbundle b/Packages/WindowsStore/Microsoft.XboxIdentityProvider_12.67.21001.0_neutral_~_8wekyb3d8bbwe.appxbundle
deleted file mode 100644
index 22383e0..0000000
Binary files a/Packages/WindowsStore/Microsoft.XboxIdentityProvider_12.67.21001.0_neutral_~_8wekyb3d8bbwe.appxbundle and /dev/null differ
diff --git a/Packages/WindowsStore/Microsoft.XboxIdentityProvider_8wekyb3d8bbwe.xml b/Packages/WindowsStore/Microsoft.XboxIdentityProvider_8wekyb3d8bbwe.xml
deleted file mode 100644
index e4010ac..0000000
--- a/Packages/WindowsStore/Microsoft.XboxIdentityProvider_8wekyb3d8bbwe.xml
+++ /dev/null
@@ -1 +0,0 @@
-9WZDNCRD1HKWmicrosoft.xboxidentityprovider_8wekyb3d8bbwe15a58266-bcff-4ee0-91f9-315ff813936a2c3f1d47-426d-c7d7-face-ef1add208818False2016-02-20T19:07:41.1189892Z2016-02-20T19:07:40.9422576Z2016-02-20T19:07:40.9422576ZFAAAAMIAAADJAAAACgAAAAMAAQB9uchWAgDLAAAAEAAAABoq1MM/L6mkagTMGyNEhfvOAAAAWgAAAG0AaQBjAHIAbwBzAG8AZgB0AC4AeABiAG8AeABpAGQAZQBuAHQAaQB0AHkAcAByAG8AdgBpAGQAZQByAF8AOAB3AGUAawB5AGIAMwBkADgAYgBiAHcAZQAAAM0AAAAiAAAAAQDwzmDCtA2xOY++tCB7M16iflwLDnYpa1uHDY1XwsgdRyAAAAAEAAAAfbnIVswAAABEAAAAAQACAA1ST4slzJ4Gp3ms6V/TBuTK+mmQyhsquAlbksVmHOGGXfd2JnVaoKWScx8Dn6o88wWwQPqnWF/6QMISZLDXBgE=uvKEEs3RJfIFW/HdJ1h6CAkLr2PLsJGl07/6ndV0mLY=oA1IZpnzE4ocdvFwp3Obf57L9dSe/p/jYINwjGMINETHP2vohVdKsyBHfn9vKWao7nWuI5BYZJR1pfSlCtVQuJxavzaE+cCKtokJG+UYcRz/cJ8BBzi9sG2z62QrAbXGdFArvvaVM77s7DAjXgeGP4HWjSSM64k1aHGfKzfwexSgAyKetEto7nTrLleKtKWKxfx3CKLLRpbVBU+D//m+dXFuxIe+OCIMepFBr4udAYeAJYyFxgPKqHeqGrM8IAWoXHtZmoiKLFndDTpUsBNlvZLbyouw9W7rGYzkSE3htXIhExJilbTXXe+L5v4YD5w+1AalGAIJR42M9RZyYOGWLw==oVSJXItDsaAIfwyR9bhh/ZSppCAO+in9POLWdC2/TQodgeHZzbdBvxJvKhpbrq6ZP0FsSElLwRoLAmv7zIuVw3Vb7tfQt5bjCDHRAG9fesNlYKV3ybyNrHyzglfZPRB5UJZw32yi03zQa+LLa05fjs6joEmlHc5BrGQrGrbNMBahz4cmuxKC4/dhEb7JZFUkc0MRhs/M3Ve511HQfKuG+92g1OffJdRsAPzWRdskPoN35knnqno7F85OBmGV/LNBgdtDWUH6di1eUCQFeKGfMp+Q/LFUX9jawTTEPn72tYbpYASug05Skcg6KTHlcLGzevxGw7BYsOsqfDka5n0YGw==AAEAAQ==
\ No newline at end of file
diff --git a/Packages/WindowsStore/placeholder.txt b/Packages/WindowsStore/placeholder.txt
new file mode 100644
index 0000000..67c3297
--- /dev/null
+++ b/Packages/WindowsStore/placeholder.txt
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/README.md b/README.md
index 70ce7fe..050a72b 100644
--- a/README.md
+++ b/README.md
@@ -1,6 +1,6 @@
# Optimize-Offline #
-Optimize-Offline is a Windows Image (WIM/ESD) optimization module designed for Windows 10 versions 1803-to-2004 64-bit architectures.
+Optimize-Offline is a Windows Image (WIM/ESD) optimization module designed for Windows 10 versions 1803-to-2009 64-bit architectures.
## About Optimize-Offline ##
@@ -61,6 +61,8 @@ The following System Applications are safe to remove:
Cortana can also be removed, though doing so will render the default search feature inoperable and is only recommended if a 3rd party search program like Classic Shell will be used.
+AppResolverUX is a UWP app that not only issues the pop-up asking how to open a specific file that does not have its own dedicated app association, but also allows for the installation of DHC drivers. It is advised not to remove this System Application as doing so will prevent all Store, UWP/DHC driver apps from running and also prevent them from being manually installed.
+
**Some System Applications are required during the OOBE setup pass and their removal can cause setup to fail. Do not remove any System Application if you're unsure of its impact on a live system.**
### About Windows Capabilities and Packages ###
@@ -134,6 +136,33 @@ It is also recommended to be well versed and aware of all recovery tools Microso
Starting in Windows 8.1, Microsoft introduced a Metro-style calculator to replace its traditional Calculator. In Windows 10 non-LTSB/LTSC/Server editions, the traditional Calculator was entirely removed and replaced with a UWP (Universal Windows Platform) App version. This new UWP Calculator introduced a fairly bloated UI many users were simply not fond of and much preferred the simplicity of the traditional Calculator (now labeled Win32Calc.exe). Unfortunately, Microsoft never added the ability to revert back to the traditional Calculator nor released a downloadable package to install the traditional Calculator.
+### About Microsoft Defender
+
+> Microsoft Defender is the built-in antimalware and antivirus protection component of Microsoft Windows. [Microsoft Document](https://docs.microsoft.com/en-us/microsoft-365/security/defender-endpoint/microsoft-defender-antivirus-windows?view=o365-worldwide). Natively, unless replaced by another antivirus, the Defender application always starts with Windows. Optimize-Offline provides methods to regain control over the initial activation and ongoing operation of Microsoft Defender.
+
+***Optimize-Offline supplies two methods to control Microsoft Defender***
+
+- The first method is to remove the SecHealthUI package which totally and permanently disables Defender.
+- The second method is to apply the Dormant Defender parameter which provides greater flexibility in controlling Microsoft Defender.
+
+***Option #1 - remove the SecHealthUI package and permanently disable Defender***
+
+- For Windows 10: Remove SecHealthUI from System Applications. See [GitHub-DrEmpiricism](https://github.com/DrEmpiricism/Optimize-Offline#about-system-applications)
+- For Windows 11: SecHealthUI removal is handled by your chosen WindowsApps list. See [GitHub-gdeliana](https://github.com/gdeliana/Optimize-Offline/blob/master/README.md#using-component-removal-lists)
+
+***Option #2 - Apply the Dormant Defender parameter to gain full control of Defender***
+
+For all Windows builds. The Dormant Defender parameter applies entries and values to the image registry hives forcing Microsoft Defender into an inactive state.
+Dormant Defender fully disables Microsoft Defender, but by leaving the application and folder structure intact, retains the possibility to restore it to full functionality.
+
+To re-enable Defender apply the "Microsoft Defender Enable" script [GitHub-TairikuOokami](https://github.com/TairikuOokami/Windows/blob/main/Microsoft%20Defender%20Enable.bat).
+
+After Microsoft Defender is restored, retain full control by applying the "ToggleDefender" script [GitHub-AveYo](https://github.com/AveYo/LeanAndMean#toggledefender---lean-and-mean-snippet-by-aveyo-2020-2021).
+
+***Note:***
+
+If you apply both methods to control Microsoft Defender e.g. remove the SecHealthUI package and apply the Dormant Defender parameter, then the former removal method takes precedence. Meaning that the outcome of applying both methods is the same as if you only removed the SecHealthUI package.
+
### About Data Deduplication ###
> Data Deduplication, often called Dedup for short, is a feature of Windows Server 2016 that can help reduce the impact of redundant data on storage costs. When enabled, Data Deduplication optimizes free space on a volume by examining the data on the volume by looking for duplicated portions on the volume. Duplicated portions of the volume's dataset are stored once and are (optionally) compressed for additional savings. Data Deduplication optimizes redundancies without compromising data fidelity or integrity. [Microsoft Document](https://docs.microsoft.com/en-us/windows-server/storage/data-deduplication/overview)
@@ -195,3 +224,148 @@ Once you have edited the Configuration.json to your specific optimization requir
```PowerShell
.\Start-Optimize.ps1
```
+
+## Using Optimize-Offline as TrustedInstaller
+
+Running Optimize-Offline as Trusted Installer enhances every operation it performs including properly unloading the image. This enhanced capability is provided by the "Start-Optimize-BAU-TI.ps1" script. The script is a the custom-made version of the generic "RunAsTI" script [GitHub-AveYo](https://github.com/AveYo/LeanAndMean/blob/main/RunAsTI.bat) and includes a unique solution for providing the power of Trusted Installer, but still correctly loading the HKCU USER hive as opposed to Window's natively loading the TI SYSTEM hive.
+
+Open the custom configuration JSON file (Configuration.json) in any text editing program and edit any values for your specific optimization requirements. While editing the Configuration.json file, do not change the template structure and make sure its formatting is retained when adding or changing values.
+
+Once you have edited the Configuration.json to your specific optimization requirements, open an elevated PowerShell console in the root directory of the Optimize-Offline project and execute the Start-Optimize-BAU-TI call script:
+
+```PowerShell
+.\Start-Optimize-BAU-TI.ps1
+```
+
+## Using Optimize-Offline GUI
+
+For now there exists also a simple GUI variant that just prepares configuration.json file and is able to launch the script.
+
+To use the GUI version of the script, please run/double click:
+
+```
+.\Start-GUI.bat
+```
+
+Below you will find a detailed explanation of each of the GUI sections:
+
+* Source select button - Opens a file picker dialog. Choose the source of the modification process.
+* Output select button - Opens a file save dialog, where the modified output will be saved. By default the output is saved in a automatically created subfolder of the root directory of the script.
+* Refresh lists button - Will obtain all the available items for removal from the selected media. This automatically happens whenver a source file is chosen.
+* Process button - Launches the Optimize-Offline script and switches to the output tab, to view the console output of the script.
+* Select USB - Select the USB where to flash the modified target file
+* UEFI/LEGACY - Select the type of USB to create. Use legacy for older bioses.
+* General tab - contains general options that can be found in the configuration.json. By hovering the mouse on each of the options you will get a brief description of what the option does.
+* Windows Apps - Select the Windows apps to remove/protect from removal. Blacklist will remove the selected apps, whereas whitelist will remove the not selected.
+* System Apps - Select the System inbox apps to remove (some of them may render the installation unbootable). Blacklist will remove the selected system apps, whereas whitelist will remove the not selected.
+* Capabilities - Removes windows capabilities. Blacklist will remove the selected capabilities, whereas whitelist will remove the not selected.
+* Packages - Removes windows packages. Blacklist will remove the selected packages, whereas whitelist will remove the not selected.
+* Features - Sets the windows feature to enable or disable.
+* Services - Sets the startup of the windows services. BE CAREFUL!! not all the items listed are windows services. Due to the registry key containing also items such driver services that are not normal windows services.
+* Custom registry - Injects registry tweaks into the installation
+* Output - Shows an embeded console of the Optimize-Offline script output.
+
+## Using component removal lists
+
+Removal lists can be found in ./Content/Lists. There are 6 basic categories spread out through each of the subfolders. In each subcategory you will find a Whitelist, Blacklist and a template. The template contains all the possible packages to be inserted either in the blacklist or in the whitelist. The features contain only a list json and a template.
+
+- WindowsApps - WindowsAppsWhitelist.json, WindowsAppsBlacklist.json, WindowsAppsTemplate.json
+- SystemApps - SystemAppsWhitelist.json, SystemAppsBlacklist.json, SystemAppsTemplate.json
+- Capabilities - CapabilitiesWhitelist.json, CapabilitiesBlacklist.json, CapabilitiesTemplate.json
+- Packages - PackagesWhitelist.json, PackagesBlacklist.json, PackagesTemplate.json
+- FeaturesToEnable - FeaturesToEnableList.json, FeaturesToEnableTemplate.json
+- FeaturesToDisable - FeaturesToDisableList.json, FeaturesToDisableTemplate.json
+
+The template files can be filled by launching the script with the populateTemplates parameter
+
+```PowerShell
+.\Start-Optimize.ps1 -populateTemplates
+```
+
+In configuration.json the list parameters are the following:
+
+- WindowsApps - (All, None, Select, Whitelist, Blacklist), lists are in ./Content/Lists/WindowsApps
+- SystemApps - (All, None, Select, Whitelist, Blacklist), lists are in ./Content/Lists/SystemApps
+- Capabilities - (All, None, Select, Whitelist, Blacklist), lists are in ./Content/Lists/Capabilities
+- Packages - (All, None, Select, Whitelist, Blacklist), lists are in ./Content/Lists/Packages
+- FeaturesToEnable - (All, None, Select, List), lists are in ./Content/Lists/FeaturesToEnable
+- FeaturesToDisable - (All, None, Select, List), lists are in ./Content/Lists/FeaturesToDisable
+- Services - (None, Select, List, Advanced), lists are in ./Content/Lists/ServicesList.json, and in ./Content/Lists/ServicesAdvanced.json when advanced parameter is set in configuration.json
+
+## Generating template component removal lists
+
+The component removal lists mentioned above contain package names that are found in the windows system. Each version of windows may change the names and entries of it's components. For updating the lists or even helping you in generating custom ones according to the windows build you have, use the command:
+
+`.\Start-Optimize -populateTemplates`
+
+This command will find all the available windows apps, system apps and capabilities and will fill the corresponding json located in ./Content/Lists . Afterwards feel free to cherry pick the package names and insert them according to your needs in the removal lists in subfolder ./Content/Lists.
+
+To populate the lists interactively by clicking item in grid guis and as well populating the templates (for later making manual changes to the lists by copying and pasting), use this command:
+Code:
+
+`.\Start-Optimize.ps1 -populateLists`
+
+Please note that the interactive filling of lists, will fill the list chosen in configuration.json. So first set up configuration.json with the proper list method!! If no list methods are specified in configuration.json the populateLists will just populate the templates, as it doesn't have info about which lists to fill, so it will be basically the same behaviour like populateTemplates.
+
+## Flashing to USB
+
+In order to flash to an USB device, please set the key FlashToUSB to "UEFI" or "Legacy" value.
+The Legacy option uses `\boot\bootsect.exe /nt60` method.
+The UEFI method creates a special UEFI partition in the USB drive and then sets it as bootable.
+Depending on your bios capabilities and on the boot method, choose the right method for your PC.
+
+## Custom Icons
+
+You can customize the icons of the windows local disk volume and of the ISO/USB volumes.
+To set a custom windows local disk icon place it under `Content\Assets\windows.ico`
+To set a custom USB drive/ISO disk icon place it under `Content\Assets\setup.ico`
+
+## Windows services removal
+
+***==Services Template==***
+Use populateTemplates feature to assign your images available services to ServicesTemplate.json
+ Some filtering out of non-service related entries is complete in the provided ServicesTemplate.json, but each OS requires more filtering.
+
+***==List==***
+Set the Services parameter in configuration.json: List
+Assigns the start behavior of the services listed in ServicesList.json to "Disabled"
+ For Services you want to disable, copy the service object "name" . . .
+ . . . from /Content/Lists/Services/ServicesTemplate.json -> /Content/Lists/Services/ServicesList.json
+ Alternatively, if you already have a list of services you know you want to disable, add their names following the pattern seen in the provided example ServicesList.json
+
+***==Advanced==***
+Set the Services parameter in configuration.json: Advanced
+Useful for specifying any type of start behavior (including "4" "Disabled") to the services listed in ServicesAdvanced.json
+ Specify the start behavior of each service by copying the object . . .
+ Code:
+ {
+ name: [SERVICE_DISPLAYNAME],
+ start: [0,1,2,3,4],
+ description?: [optional, not used in the code, but just for you to know more about the services you're including]
+ }
+ . . . from /Content/Lists/Services/ServicesTemplate.json -> /Content/Lists/Services/ServicesAdvanced.json
+
+## Selecting the output path and filename
+
+You can override the default path for ISO/WIM/SWM/ESD files by entering a specific path with an optional filename in Configuration.json "OutputPath" key. The possible key values are the following:
+
+- default - is the default value for this setting and represents the default behavior of the script
+- select - will popup a save file dialog for ISO input and a choose directory dialog for WIM/SWM/ESD inputs
+- your specific path - you can as well specify the exact path of the output. For WIM/SWM/ESD files the path will chose only the directory path and any filename will be ignored.
+- your specific path with {filename} variable for ISO inputs - The name of the ISO can be left to the script to be specified automatically based on the filename convention: {Windows_Edition}_{Build_nr}.ISO (ex. Professional_22000.ISO)
+
+## Selective registry tweaks
+
+- DisableWindowsUpgrade - Tweak will prevent windows update from receiving cummulative updates and feature updates
+- DisableWindowsUpdateMicrosoft - Applies the official developers solution to prevents Windows Update from connecting to Microsoft update services. This includes connecting to the MS Store to download apps. [Microsoft Document] (https://docs.microsoft.com/en-us/windows/privacy/manage-connections-from-windows-operating-system-components-to-microsoft-services#bkmk-wu) Easy to turn on an off using a toggle script [GitHub Gist] (https://gist.github.com/espanafly/3041ce74cd2493d349e58c31630f98e5)
+- DisableDriverUpdate - Will disable windows update from updating hw drivers
+- DormantOneDrive - Disables the startup installation of Onedrive, but allows you to manually install by using the dormant physical setup file
+- Disable3rdPartyApps - Will remove the 3rd party apps installed with windows
+- W11ClassicContextMenu - Will make the context menu look like in W10 (builds >= 22000)
+- ExplorerUIRibbon - Enables the classic explorer UI ribbon (not available on builds >= 22500)
+- ClassicSearchExplorer - Tweak is needed in case you uninstall Search app or when applying the /Content/Additional/Setup/Set-Additional.ps1 on an online image. Works only on builds higher than 18363.
+- RemoveTaskbarPinnedIcons - Tries to remove based on system version the automatically pinned taskbar icons
+- DisableTeamsApp - Will remove Microsoft Teams from installing at the first logon
+- DisableVirtualizationSecurity - Disables Core integrity and Virtualization based security (builds >= 22000)
+- RunAsTiContextMenu - Adds Powershell as trusted installer context menu entry
+- AmoledBlackTheme - Enables pitch black AMOLED theme on W10 and W11 all builds
diff --git a/Remove_Failure_no_prompts.cmd b/Remove_Failure_no_prompts.cmd
new file mode 100644
index 0000000..6804f92
--- /dev/null
+++ b/Remove_Failure_no_prompts.cmd
@@ -0,0 +1,72 @@
+@setlocal DisableDelayedExpansion
+@echo off
+set _args=
+set _args=%*
+if not defined _args goto :NoProgArgs
+for %%A in (%_args%) do (
+if /i "%%A"=="-wow" set _rel1=1
+if /i "%%A"=="-arm" set _rel2=1
+)
+:NoProgArgs
+set "_cmdf=%~f0"
+if exist "%SystemRoot%\Sysnative\cmd.exe" if not defined _rel1 (
+setlocal EnableDelayedExpansion
+start %SystemRoot%\Sysnative\cmd.exe /c ""!_cmdf!" -wow "
+exit /b
+)
+if exist "%SystemRoot%\SysArm32\cmd.exe" if /i %PROCESSOR_ARCHITECTURE%==AMD64 if not defined _rel2 (
+setlocal EnableDelayedExpansion
+start %SystemRoot%\SysArm32\cmd.exe /c ""!_cmdf!" -arm "
+exit /b
+)
+set "_Null=1>nul 2>nul"
+set "SysPath=%SystemRoot%\System32"
+if exist "%SystemRoot%\Sysnative\reg.exe" (set "SysPath=%SystemRoot%\Sysnative")
+set "Path=%SysPath%;%SystemRoot%;%SysPath%\Wbem;%SysPath%\WindowsPowerShell\v1.0\"
+reg.exe query HKU\S-1-5-19 %_Null% || (echo.&echo This script require administrator privileges.&goto :TheEnd)
+set _drv=%~d0
+set "xOS=%PROCESSOR_ARCHITECTURE%"
+if /i %PROCESSOR_ARCHITECTURE%==x86 (if defined PROCESSOR_ARCHITEW6432 set "xOS=%PROCESSOR_ARCHITEW6432%")
+set "_key=HKLM\SOFTWARE\Microsoft\WIMMount\Mounted Images"
+set regKeyPathFound=1
+set wowRegKeyPathFound=1
+reg.exe query "HKLM\Software\Wow6432Node\Microsoft\Windows Kits\Installed Roots" /v KitsRoot10 %_Null% || set wowRegKeyPathFound=0
+reg.exe query "HKLM\Software\Microsoft\Windows Kits\Installed Roots" /v KitsRoot10 %_Null% || set regKeyPathFound=0
+if %wowRegKeyPathFound% equ 0 (
+ if %regKeyPathFound% equ 0 (
+ goto :precheck
+ ) else (
+ set regKeyPath=HKLM\Software\Microsoft\Windows Kits\Installed Roots
+ )
+) else (
+ set regKeyPath=HKLM\Software\Wow6432Node\Microsoft\Windows Kits\Installed Roots
+)
+for /f "skip=2 tokens=2*" %%i in ('reg.exe query "%regKeyPath%" /v KitsRoot10') do set "KitsRoot=%%j"
+set "DandIRoot=%KitsRoot%Assessment and Deployment Kit\Deployment Tools"
+if exist "%DandIRoot%\%xOS%\DISM\dism.exe" (
+set "Path=%DandIRoot%\%xOS%\DISM;%SysPath%;%SystemRoot%;%SysPath%\Wbem;%SysPath%\WindowsPowerShell\v1.0\"
+cd \
+)
+
+:precheck
+@cls
+for /f "tokens=3*" %%a in ('reg.exe query "%_key%" /s /v "Mount Path" 2^>nul ^| findstr /i /c:"Mount Path"') do (set "_mount=%%b"&call :CLN)
+dism.exe /English /Cleanup-Wim
+dism.exe /English /Cleanup-Mountpoints
+goto :TheEnd
+
+:CLN
+dism.exe /English /Image:"%_mount%" /Get-Packages %_Null%
+dism.exe /English /Unmount-Wim /MountDir:"%_mount%" /Discard
+if exist "%_mount%\" rmdir /s /q "%_mount%\" %_Null%
+if exist "%_mount%" (
+mkdir %_drv%\_del286 %_Null%
+robocopy %_drv%\_del286 "%_mount%" /MIR /R:1 /W:1 /NFL /NDL /NP /NJH /NJS %_Null%
+rmdir /s /q %_drv%\_del286\ %_Null%
+rmdir /s /q "%_mount%" %_Null%
+)
+exit /b
+
+:TheEnd
+echo.
+goto :eof
diff --git a/Src/GUI/Configuration_definition.json b/Src/GUI/Configuration_definition.json
new file mode 100644
index 0000000..6c0e408
--- /dev/null
+++ b/Src/GUI/Configuration_definition.json
@@ -0,0 +1,289 @@
+{
+ "Main": {
+ "Label": "Main",
+ "Column": 1,
+ "Controls": [
+ {
+ "Name": "DormantDefender",
+ "Label": "Disable Windows Defender/Security",
+ "Type": "Switch",
+ "Binding": "DormantDefender",
+ "Description": "Disable Windows defender while retaining the option to reactivate it."
+ },
+ {
+ "Name": "Registry",
+ "Label": "Apply Registry tweaks",
+ "Type": "Switch",
+ "Binding": "Registry",
+ "Description": "For the specifics check file: .\\Src\\Public\\Set-RegistryProperties.ps1"
+ },
+ {
+ "Name": "ComponentCleanup",
+ "Label": "Clean the Component Store",
+ "Type": "Switch",
+ "Binding": "ComponentCleanup",
+ "Description": "compresses all superseded components, thus reducing the size of the Component Store"
+ },
+ {
+ "Name": "Win32Calc",
+ "Label": "Integrate classic windows calculator",
+ "Type": "Switch",
+ "Binding": "Win32Calc",
+ "Description": "Integrates the traditional Win32 Calculator into the image."
+ },
+ {
+ "Name": "DeveloperMode",
+ "Label": "Developer mode",
+ "Type": "Switch",
+ "Binding": "DeveloperMode",
+ "Description": "Enables developer mode"
+ },
+ {
+ "Name": "WindowsStore",
+ "Label": "Integrate Windows Store",
+ "Type": "Switch",
+ "Binding": "WindowsStore",
+ "Description": "Integrate Windows Store"
+ },
+ {
+ "Name": "Dedup",
+ "Label": "Integrate Windows Server Data Deduplication",
+ "Type": "Switch",
+ "Binding": "Dedup",
+ "Description": "Integrates the Windows Server Data Deduplication Feature into the image."
+ },
+ {
+ "Name": "MicrosoftEdge",
+ "Label": "Integrate Microsoft Edge Chromium",
+ "Type": "Switch",
+ "Binding": "MicrosoftEdge",
+ "Description": "Only works on windows 10 builds without Edge Chromium",
+ "Restrictions": [
+ {
+ "Build": "18362",
+ "Criteria": "min"
+ },
+ {
+ "Build": "19041",
+ "Criteria": "max"
+ }
+ ]
+ },
+ {
+ "Name": "ISO",
+ "Label": "Prompt at boot",
+ "Type": "ComboBox",
+ "Description": "Prompt at boot",
+ "Values": ["Prompt", "No-Prompt"],
+ "Binding": "ISO",
+ "ShowNone": false
+ },
+ {
+ "Name": "CompressionType",
+ "Label": "WIM/ESD compression level",
+ "Type": "ComboBox",
+ "Description": "WIM/ESD compression level",
+ "Values": ["None", "Fast", "Maximum", "Solid"],
+ "Binding": "CompressionType",
+ "ShowNone": false
+ },
+ {
+ "Name": "ShutDownOnComplete",
+ "Label": "Turn off pc on script completion",
+ "Type": "Switch",
+ "Binding": "ShutDownOnComplete",
+ "Description": "Turn off pc on script completion, when clicking the process button"
+ }
+ ]
+ },
+ "Additional": {
+ "Label": "Additional",
+ "Column": 0,
+ "Controls": [
+ {
+ "Name": "Setup",
+ "Label": "Apply Setup Content",
+ "Type": "Switch",
+ "Binding": "Additional.Setup",
+ "Description": "Integrates user-specific content added to the 'Content/Additional' directory into the image when enabled"
+ },
+ {
+ "Name": "Wallpaper",
+ "Label": "Apply Wallpaper",
+ "Type": "Switch",
+ "Binding": "Additional.Wallpaper",
+ "Description": "Integrates 'Content\\Additional\\Wallpaper\\Windows 10 HD' wallpapers in the image"
+ },
+ {
+ "Name": "SystemLogo",
+ "Label": "Apply System Logo",
+ "Type": "Switch",
+ "Binding": "Additional.SystemLogo",
+ "Description": "Integrates a custom system logo into the image. Place the logo in 'Content\\Additional\\SystemLogo'"
+ },
+ {
+ "Name": "LockScreen",
+ "Label": "Apply LockScreen",
+ "Type": "Switch",
+ "Binding": "Additional.LockScreen",
+ "Description": "Converts and integrates a custom lockscreen into the image. Place the lockscreen files into 'Content\\Additional\\LockScreen'"
+ },
+ {
+ "Name": "RegistryTemplates",
+ "Label": "Apply Additional Registry",
+ "Type": "Switch",
+ "Binding": "Additional.RegistryTemplates",
+ "Description": "Custom registry template (.reg) files placed in the '\\Content\\Additional\\RegistryTemplates' folder are imported by Optimize-Offline into the offline image's appropriate registry hive."
+ },
+ {
+ "Name": "LayoutModification",
+ "Label": "Apply custom Start Menu layout",
+ "Type": "Switch",
+ "Binding": "Additional.LayoutModification",
+ "Description": "Imports a custom LayoutModification.xml to provision the Start layout.If adding additional user content, place any custom Start Menu layout XML/JSON (LayoutModification.xml/LayoutModification.json) file to be added to the image in '\\Content\\Additional\\LayoutModification'"
+ },
+ {
+ "Name": "Unattend",
+ "Label": "Apply answer file",
+ "Type": "Switch",
+ "Binding": "Additional.Unattend",
+ "Description": "Place the answer file (unattend.xml) into '\\Content\\Additional\\Unattend' folder"
+ },
+ {
+ "Name": "Drivers",
+ "Label": "Integrate Windows drivers",
+ "Type": "Switch",
+ "Binding": "Additional.Drivers",
+ "Description": "Place the drivers into '\\Content\\Additional\\Drivers' folder"
+ },
+ {
+ "Name": "NetFx3",
+ "Label": "Integrate .Net Framework 3.5",
+ "Type": "Switch",
+ "Binding": "Additional.NetFx3",
+ "Description": "Integrates the .NET Framework 3 payload packages into the image and enables the NetFx3 optional feature. Works only when input is an ISO image."
+ }
+ ]
+ },
+ "SelectiveRegistry": {
+ "Label": "Selective registry",
+ "Column": 0,
+ "Controls": [
+ {
+ "Name": "DisableWindowsUpgrade",
+ "Label": "Disable Windows upgrade",
+ "Type": "Switch",
+ "Binding": "SelectiveRegistry.DisableWindowsUpgrade",
+ "Description": "Disables the ability to upgrade to newer versions of Windows"
+ },
+ {
+ "Name": "DisableWindowsUpdateMicrosoft",
+ "Label": "Disabling Windows update contacting Microsoft servers",
+ "Type": "Switch",
+ "Binding": "SelectiveRegistry.DisableWindowsUpdateMicrosoft",
+ "Description": "This disables completely the windows update services and Microsoft Store downloading"
+ },
+ {
+ "Name": "DisableDriverUpdate",
+ "Label": "Disable Windows driver update",
+ "Type": "Switch",
+ "Binding": "SelectiveRegistry.DisableDriverUpdate",
+ "Description": "Disabled Windows update from automatically updating drivers"
+ },
+ {
+ "Name": "DormantOneDrive",
+ "Label": "Disable Microsoft OneDrive",
+ "Type": "Switch",
+ "Binding": "SelectiveRegistry.DormantOneDrive",
+ "Description": "Disables Onedrive installation after OOBE run"
+ },
+ {
+ "Name": "Disable3rdPartyApps",
+ "Label": "Disable 3rd party app installation",
+ "Type": "Switch",
+ "Binding": "SelectiveRegistry.Disable3rdPartyApps",
+ "Description": "Disables ContentDeliveryManager from installing 3rd party apps. This tweak is activated also in case the system app 'ContentDeliveryManager' is removed from the system apps tab."
+ },
+ {
+ "Name": "ExplorerUIRibbon",
+ "Label": "Classic Explorer UI ribbon",
+ "Type": "Switch",
+ "Binding": "SelectiveRegistry.ExplorerUIRibbon",
+ "Description": "Add the explorer UI ribbon in Windows 10"
+ },
+ {
+ "Name": "ClassicSearchExplorer",
+ "Label": "Explorer classic file search",
+ "Type": "Switch",
+ "Binding": "SelectiveRegistry.ClassicSearchExplorer",
+ "Description": "Disables modern UWP explorer file search"
+ },
+ {
+ "Name": "RemoveTaskbarPinnedIcons",
+ "Label": "Remove taskbar pinned icons",
+ "Type": "Switch",
+ "Binding": "SelectiveRegistry.RemoveTaskbarPinnedIcons",
+ "Description": "Removes taskbar pinned icons"
+ },
+ {
+ "Name": "DisableTeamsApp",
+ "Label": "Remove Microsoft Teams App",
+ "Type": "Switch",
+ "Binding": "SelectiveRegistry.DisableTeamsApp",
+ "Description": "Removes Microsoft Teams App"
+ },
+ {
+ "Name": "RunAsTiContextMenu",
+ "Label": "Add Run As Trusted Installer context menu entry",
+ "Type": "Switch",
+ "Binding": "SelectiveRegistry.RunAsTiContextMenu",
+ "Description": "Add Run As Trusted Installer context menu entry"
+ }
+ ]
+ },
+ "Specific": {
+ "Label": "Specific",
+ "Column": 1,
+ "Controls": [
+ {
+ "Name": "W11ClassicContextMenu",
+ "Label": "W11 Classic context menus",
+ "Type": "Switch",
+ "Binding": "SelectiveRegistry.W11ClassicContextMenu",
+ "Description": "Makes context menus classic looking, as in W10",
+ "Restrictions": [
+ {
+ "Build": "22000",
+ "Criteria": "min"
+ }
+ ]
+ },
+ {
+ "Name": "DisableVirtualizationSecurity",
+ "Label": "W11 Disable Virtualization Security",
+ "Type": "Switch",
+ "Binding": "SelectiveRegistry.DisableVirtualizationSecurity",
+ "Description": "Disables Core integrity and Virtualization based security (builds >= 22000)",
+ "Restrictions": [
+ {
+ "Build": "22000",
+ "Criteria": "min"
+ }
+ ]
+ },
+ {
+ "Name": "AmoledBlackTheme",
+ "Label": "W11 Add AMOLED Black Theme",
+ "Type": "Switch",
+ "Binding": "SelectiveRegistry.AmoledBlackTheme",
+ "Description": "W11 Add AMOLED Black Theme",
+ "Restrictions": [
+ {
+ "Build": "22000",
+ "Criteria": "min"
+ }
+ ]
+ }
+ ]
+ }
+}
diff --git a/Src/GUI/RemovalTemplates/CapabilitiesTemplate.json b/Src/GUI/RemovalTemplates/CapabilitiesTemplate.json
new file mode 100644
index 0000000..5051d94
--- /dev/null
+++ b/Src/GUI/RemovalTemplates/CapabilitiesTemplate.json
@@ -0,0 +1,3 @@
+[
+
+]
diff --git a/Src/GUI/RemovalTemplates/FeaturesTemplate.json b/Src/GUI/RemovalTemplates/FeaturesTemplate.json
new file mode 100644
index 0000000..5051d94
--- /dev/null
+++ b/Src/GUI/RemovalTemplates/FeaturesTemplate.json
@@ -0,0 +1,3 @@
+[
+
+]
diff --git a/Src/GUI/RemovalTemplates/PackagesTemplate.json b/Src/GUI/RemovalTemplates/PackagesTemplate.json
new file mode 100644
index 0000000..9fc873f
--- /dev/null
+++ b/Src/GUI/RemovalTemplates/PackagesTemplate.json
@@ -0,0 +1,3 @@
+[
+
+]
diff --git a/Src/GUI/RemovalTemplates/ServicesTemplate.json b/Src/GUI/RemovalTemplates/ServicesTemplate.json
new file mode 100644
index 0000000..c9c513b
--- /dev/null
+++ b/Src/GUI/RemovalTemplates/ServicesTemplate.json
@@ -0,0 +1,3 @@
+[
+
+]
\ No newline at end of file
diff --git a/Src/GUI/RemovalTemplates/SystemAppsTemplate.json b/Src/GUI/RemovalTemplates/SystemAppsTemplate.json
new file mode 100644
index 0000000..df9e79a
--- /dev/null
+++ b/Src/GUI/RemovalTemplates/SystemAppsTemplate.json
@@ -0,0 +1,3 @@
+[
+
+]
\ No newline at end of file
diff --git a/Src/GUI/RemovalTemplates/WindowsAppsTemplate.json b/Src/GUI/RemovalTemplates/WindowsAppsTemplate.json
new file mode 100644
index 0000000..df9e79a
--- /dev/null
+++ b/Src/GUI/RemovalTemplates/WindowsAppsTemplate.json
@@ -0,0 +1,3 @@
+[
+
+]
\ No newline at end of file
diff --git a/Src/GUI/Start.ps1 b/Src/GUI/Start.ps1
new file mode 100644
index 0000000..44cad9b
--- /dev/null
+++ b/Src/GUI/Start.ps1
@@ -0,0 +1,781 @@
+Add-Type -AssemblyName PresentationFramework, System.Windows.Forms
+
+$Global:Error.Clear()
+
+$RootPath = $PSScriptRoot
+
+$OO_Root_Path = (Get-Item -Path "$RootPath\..\..\").FullName
+$OO_Lists_Path = "$($OO_Root_Path)Content\Lists\"
+$ConsoleSTDOutPath = "$($OO_Root_Path)ConsoleOut.txt"
+$CustomRegistryPath = "$($OO_Root_Path)\Content\CustomRegistry.reg"
+
+$RemovalTypes = @("Blacklist", "Whitelist")
+$ListTypes = @("WindowsApps", "SystemApps", "Capabilities", "Packages", "Services", "Features")
+$ListTypesNoRemoval = @("Services", "Features")
+$ListColumns = @{
+ "WindowsApps" = @("DisplayName", "PackageName")
+ "SystemApps" = @("DisplayName")
+ "Capabilities" = @("Name")
+ "Packages" = @("PackageName")
+ "Services" = @("Name", "Description")
+ "Features" = @("FeatureName", "OriginalState")
+}
+$ListMainKey = @{
+ "WindowsApps" = "DisplayName"
+ "SystemApps" = "DisplayName"
+ "Capabilities" = "Name"
+ "Packages" = "PackageName"
+ "Services" = "Services"
+ "Features" = "FeatureName"
+}
+$ListColumnsComboBox = @{
+ "Features" = @("State")
+ "Services" = @("Start")
+}
+
+Function CleanVars {
+ Remove-Variable -Name Configuration, ConfigurationDef -ErrorAction Ignore
+ Remove-Variable -Name OO_GUI_FlashUSBDriveNumber, OO_GUI_Timer, OO_GUI_Job -ErrorAction Ignore -Scope Global
+ Foreach($ListType in $ListTypes) {
+ Remove-Variable -Name "$($ListType)Template" -ErrorAction Ignore -Scope Global
+ }
+ If (Test-Path -Path "$ConsoleSTDOutPath") {
+ Remove-Item -Path "$ConsoleSTDOutPath"
+ }
+}
+
+CleanVars
+
+$Global:OO_GUI_FlashUSBDriveNumber = -1
+
+$Global:OO_GUI_Timer = New-Object System.Windows.Forms.Timer
+$Global:OO_GUI_Timer.Interval = 3000
+
+$Global:OO_GUI_Job = $null
+
+
+$Configuration_path = (Get-Item -Path "$($OO_Root_Path)Configuration.json").FullName
+
+## Import XAML files
+Get-ChildItem -Path "$RootPath\XAML" -Filter *.xaml -Recurse | ForEach-Object -Process {
+ New-Variable -Name "$($_.BaseName)XAML" -Value (Get-Content -Raw -Path $_.FullName) -Scope Script
+}
+
+## Import the List templates
+Function Import-Templates {
+ Foreach($ListType in $ListTypes){
+ If(Test-Path -Path "$RootPath\RemovalTemplates\$($ListType)Template.json") {
+ $JSON = Get-Content -Raw -Path "$RootPath\RemovalTemplates\$($ListType)Template.json" -ErrorAction Stop | ConvertFrom-Json -ErrorAction Stop
+ } Else {
+ $JSON = @()
+ }
+ If(!$JSON){
+ $JSON = @()
+ }
+ ## Sync GUI list data from OO list data
+ Switch($ListType) {
+ "Services"{
+ $Key = $ListMainKey.$ListType
+ $List_OO = $(Get-Content -Raw -Path "$OO_Lists_Path\Services\ServicesList.json" -ErrorAction Stop | ConvertFrom-Json -ErrorAction Stop).$Key
+ If($List_OO){
+ Foreach($Item in $JSON) {
+ Foreach($ItemOO in $List_OO) {
+ If ($Item.Name -eq $ItemOO -or ($ItemOO -Match "\*" -and $Item.Name -like $ItemOO)){
+ $Item.Start = $Item.Starts[4]
+ Break
+ }
+ }
+ }
+ }
+ $List_OO = $(Get-Content -Raw -Path "$OO_Lists_Path\Services\ServicesAdvanced.json" -ErrorAction Stop | ConvertFrom-Json -ErrorAction Stop).$Key
+ If($List_OO){
+ Foreach($Item in $JSON) {
+ Foreach($ItemOO in $List_OO) {
+ If($Item.Name -eq $ItemOO.name) {
+ $Item.Start = $Item.Starts[$ItemOO.start]
+ Break
+ }
+ }
+ }
+ }
+ }
+ "Features" {
+ $Key = $ListMainKey.$ListType
+ $List_OO_ToDisable = $(Get-Content -Raw -Path "$OO_Lists_Path\FeaturesToDisable\FeaturesToDisableList.json" -ErrorAction Stop | ConvertFrom-Json -ErrorAction Stop).$Key
+ $List_OO_ToEnable = $(Get-Content -Raw -Path "$OO_Lists_Path\FeaturesToEnable\FeaturesToEnableList.json" -ErrorAction Stop | ConvertFrom-Json -ErrorAction Stop).$Key
+ If($List_OO_ToDisable){
+ Foreach($Item in $JSON) {
+ Foreach($ItemOO in $List_OO_ToDisable){
+ If ($Item.$Key -eq $ItemOO -or ($ItemOO -Match "\*" -and $Item.$Key -like $ItemOO)){
+ $Item.State = "Disabled"
+ }
+ }
+ }
+ }
+ If($List_OO_ToEnable){
+ Foreach($Item in $JSON) {
+ Foreach($ItemOO in $List_OO_ToEnable){
+ If ($Item.$Key -eq $ItemOO -or ($ItemOO -Match "\*" -and $Item.$Key -like $ItemOO)){
+ $Item.State = "Enabled"
+ }
+ }
+ }
+ }
+ }
+ default {
+ If ($Configuration.$ListType){
+ $Type = $($Configuration.$ListType).Trim()
+ $Type = $Type.substring(0,1).toupper()+$Type.substring(1).tolower()
+ If ($RemovalTypes.IndexOf($Type) -gt -1){
+ $Key = $ListMainKey.$ListType
+ $List_OO = (Get-Content -Raw -Path "$OO_Lists_Path\$($ListType)\$($ListType)List.json" -ErrorAction Stop | ConvertFrom-Json -ErrorAction Stop).$Key
+ If($List_OO){
+ Foreach($Item in $JSON) {
+ Foreach($ItemOO in $List_OO){
+ If ($Item.$Key -eq $ItemOO -or ($ItemOO -Match "\*" -and $Item.$Key -like $ItemOO)){
+ $Item.Selected = $true
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ Remove-Variable -Name "$($ListType)Template" -Scope Global -ErrorAction Ignore
+ New-Variable -Name "$($ListType)Template" -Value $JSON -Scope Global
+ }
+}
+
+Import-Templates
+
+$ConfigurationDef = Get-Content -Path "$RootPath\Configuration_definition.json" -Raw -ErrorAction Stop | ConvertFrom-Json -ErrorAction Stop
+$Configuration = Get-Content -Path $Configuration_path -Raw -ErrorAction Stop | ConvertFrom-Json -ErrorAction Stop
+
+Function Save-List {
+ param([string]$ListType)
+ $PathList = "$($OO_Lists_Path)$($ListType)\$($ListType)List.json"
+ $PathTemplate = "$RootPath\RemovalTemplates\$($ListType)Template.json"
+ $Template = (Get-Variable -Name "$($ListType)Template" -ValueOnly -Scope Global)
+
+ If(!(Test-Path -Path $PathList) -or !(Test-Path -Path $PathTemplate)){
+ return
+ }
+ $List = @{ }
+ $Key = $ListMainKey.$ListType
+ $List.$Key = @( )
+ Foreach($Item in $Template){
+ If($Item.Selected){
+ $List.$Key += $Item.$Key
+ }
+ }
+
+ $Template | ConvertTo-Json | Out-File -FilePath $PathTemplate -Encoding UTF8 -Force -ErrorAction Ignore
+ $List | ConvertTo-Json | Out-File -FilePath $PathList -Encoding UTF8 -Force -ErrorAction Ignore
+}
+
+Function Save-Features {
+ $FeaturesToDisable = @()
+ $FeaturesToEnable = @()
+
+ Foreach($Feature in $Global:FeaturesTemplate){
+ If($Feature.State -eq "Enabled" -and $Feature.OriginalState -eq "Disabled"){
+ $FeaturesToEnable += $Feature.FeatureName
+ }
+ If($Feature.State -eq "Disabled" -and $Feature.OriginalState -eq "Enabled"){
+ $FeaturesToDisable += $Feature.FeatureName
+ }
+ }
+ $Global:FeaturesTemplate | ConvertTo-Json | Out-File -FilePath "$RootPath\RemovalTemplates\FeaturesTemplate.json" -Encoding UTF8 -Force -ErrorAction Ignore
+ @{FeatureName = $FeaturesToEnable} | ConvertTo-Json | Out-File -FilePath "$($OO_Lists_Path)FeaturesToEnable\FeaturesToEnableList.json" -Encoding UTF8 -Force -ErrorAction Ignore
+ @{FeatureName = $FeaturesToDisable} | ConvertTo-Json | Out-File -FilePath "$($OO_Lists_Path)FeaturesToDisable\FeaturesToDisableList.json" -Encoding UTF8 -Force -ErrorAction Ignore
+}
+Function Save-Services {
+ $Services = @()
+ Foreach($Service in $Global:ServicesTemplate){
+ If($Service.OriginalStart -ne $Service.Start) {
+ $Services += @{
+ name = $Service.Name
+ start = $Service.Starts.IndexOf($Service.Start)
+ description = $Service.Description
+ }
+ }
+ }
+ $Global:ServicesTemplate | ConvertTo-Json | Out-File -FilePath "$RootPath\RemovalTemplates\ServicesTemplate.json" -Encoding UTF8 -Force -ErrorAction Ignore
+ @{Services = $Services} | ConvertTo-Json | Out-File -FilePath "$($OO_Lists_Path)Services\ServicesAdvanced.json" -Encoding UTF8 -Force -ErrorAction Ignore
+}
+
+Function GenerateControlXaml {
+ param ($Control)
+
+ $XAML = $InputLayoutXAML
+ $InputControl = Switch ($Control.Type) {
+ "ComboBox" {
+ $ComboBoxXAML
+ }
+ "Switch" {
+ $CheckBoxXAML
+ }
+ default {""}
+ }
+
+ $InputControl = $InputControl.Replace("{Name}", $Control.Name)
+ $InputControl = $InputControl.Replace("{Label}", $Control.Label)
+
+ Switch ($Control.Type) {
+ "ComboBox" {
+ $InputControl = $InputControl.Replace("{Value}", $($Control.Values.IndexOf(($Configuration.($Control.Binding)))))
+ $InputControl = $InputControl.Replace("{Items}", $($(Foreach($Value in $Control.Values){"
+
+ "}) -join "`n"))
+ }
+ "Switch" {
+ $InputControl = $InputControl.Replace("{Value}", "{Binding Configuration.$($Control.Binding)}")
+ }
+ }
+
+ $InputControl = $InputControl.Replace("{Tooltip}", $(If($Control.Description){ $Control.Description } Else {""}))
+
+ $XAML = $XAML.Replace("{Input}", $InputControl)
+
+ return $XAML
+}
+
+Function Set-ControlsVisibility {
+ $ImageInfo = (Get-Content -Raw -Path "$RootPath\image_info.json" -ErrorAction Stop | ConvertFrom-Json -ErrorAction Stop)
+ If(!$ImageInfo -or !$ImageInfo.Build){
+ return
+ }
+ $ConfigurationDef.PSObject.Properties | ForEach-Object {
+ Foreach($Control in $_.Value.Controls) {
+ If($Control.Restrictions -and $Control.Restrictions.Count -gt 0){
+ $valid = $true
+ Foreach($Restriction in $Control.Restrictions) {
+ If($Restriction.Build -gt 0) {
+ Switch ($Restriction.Criteria) {
+ "min" {
+ If($ImageInfo.Build -gt 0 -and $ImageInfo.Build -lt $Restriction.Build)
+ {
+ $valid = $false
+ break
+ }
+ }
+ "max" {
+ If($ImageInfo.Build -gt 0 -and $ImageInfo.Build -gt $Restriction.Build)
+ {
+ $valid = $false
+ break
+ }
+ }
+ }
+ }
+ }
+ $ControlWPF = $Window.FindName($Control.Name)
+ $ControlWPF.Visibility = $(If (!$valid) {"Collapse"} Else {"Visible"})
+ Switch($Control.Type) {
+ "Switch" {
+ $ControlWPF.IsChecked = $false
+ }
+ "ComboBox" {
+ $ControlWPF.SelectedIndex = 0
+ }
+ }
+ }
+ }
+ }
+}
+
+Function GenerateTabLayout {
+ param ([string]$Content, [string]$TabHeader, [string]$Name, [switch]$NoScroll)
+ $XAML = $(If($NoScroll.IsPresent) {$TabLayoutXAML} Else {$TabScrollXAML})
+ $XAML = $XAML.Replace("{TabContent}", $Content)
+ $XAML = $XAML.Replace("{TabHeader}", $TabHeader)
+ $XAML = $XAML.Replace("{Name}", $Name)
+ return $XAML
+}
+
+Function GenerateMainConfigTab {
+ $XAML = $MainConfigTabXAML
+ $TabXAML = GenerateTabLayout -Content $XAML -TabHeader "General" -Name "GeneralTab"
+ $Cols = @{}
+ $ConfigurationDef.PSObject.Properties | ForEach-Object -Process {
+ $ControlsXAML = ""
+ Foreach ($Control in $_.Value.Controls) {
+ $ControlXAML = GenerateControlXaml -Control $Control
+ If($ControlXAML.Trim() -ne "") {
+ $ControlsXAML = $ControlsXAML + $ControlXAML
+ }
+ }
+ If($ControlsXAML -eq ""){
+ $ControlsXAML = "
+ "
+ }
+ $SectionXAML = $MainConfigGroupBoxXAML
+ $SectionXAML = $SectionXAML.Replace("{Header}", $_.Value.Label)
+ $SectionXAML = $SectionXAML.Replace("{Content}", $ControlsXAML)
+ If(!$Cols[$_.Value.Column]){
+ $Cols[$_.Value.Column] = ""
+ }
+ $Cols[$_.Value.Column] += $SectionXAML
+ }
+ $ColsXAML = ""
+ foreach($i in $Cols.keys){
+ $ColsXAML += "
+
+ $($Cols[$i])
+
+ "
+ }
+ $TabXAML = $TabXAML.Replace("{ColsXAML}", $ColsXAML)
+ $TabXAML = $TabXAML.Replace("{Cols}", $Cols.Count)
+ return $TabXAML
+}
+
+Function GenerateListTab {
+ param([string]$ListType, [string]$Header)
+ If(!($Configuration.$ListType)){
+ return ""
+ }
+ $Type = $($Configuration.$ListType).Trim()
+ $Type = $Type.substring(0,1).toupper()+$Type.substring(1).tolower()
+ $ListTypeSelectedIndex = $($RemovalTypes.IndexOf($Type))
+ If($ListTypeSelectedIndex -lt 0){
+ $ListTypeSelectedIndex = 0
+ }
+ $TabXAML = $ListRemovalTabXAML.Replace("{ListType}", $ListType)
+ $TabXAML = $TabXAML.Replace("{ListTypeSelectedIndex}", $ListTypeSelectedIndex)
+ $TabXAML = $TabXAML.Replace("{Columns}", $($(Foreach($Value in $ListColumns.$ListType){"
+
+ "}) -join "`n"))
+ return (GenerateTabLayout -NoScroll -Content $TabXAML -TabHeader $Header -Name "$($ListType)Tab")
+}
+
+Function GenerateListComboTab {
+ param([string]$ListType, [string]$Header)
+ $TabXAML = $ListRemovalComboTabXAML.Replace("{ListType}", $ListType)
+ $Columns = @()
+ Foreach($Column in $ListColumns.$ListType){
+ $Columns += "
+
+ "
+ }
+ Foreach($Column in $ListColumnsComboBox.$ListType){
+ $Columns += "
+
+
+
+
+
+
+
+ "
+ }
+ $TabXAML = $TabXAML.Replace("{Columns}", $Columns)
+ return (GenerateTabLayout -NoScroll -Content $TabXAML -TabHeader $Header -Name "$($ListType)Tab")
+}
+
+Function GenerateOutputTab {
+ $Content = $OutputTabXAML
+ return (GenerateTabLayout -NoScroll -Content $Content -TabHeader "Output" -Name "OutputTab")
+}
+
+
+Function GenerateCustomRegistryTab {
+ $Content = $CustomRegistryTabXAML
+ return (GenerateTabLayout -NoScroll -Content $Content -TabHeader "Custom Registry" -Name "CustomRegistryTab")
+}
+
+
+$TabsXAML = "
+$(GenerateMainConfigTab)
+$(GenerateListTab -ListType "WindowsApps" -Header "Windows Apps")
+$(GenerateListTab -ListType "SystemApps" -Header "System Apps")
+$(GenerateListTab -ListType "Capabilities" -Header "Capabilities")
+$(GenerateListTab -ListType "Packages" -Header "Packages")
+$(GenerateListComboTab -ListType "Features" -Header "Features")
+$(GenerateListComboTab -ListType "Services" -Header "Services")
+$(GenerateCustomRegistryTab)
+$(GenerateOutputTab)
+"
+$LayoutXAML = $LayoutXAML.Replace("{Tabs}", $TabsXAML)
+
+[xml]$XAML = @"
+$LayoutXAML
+"@
+
+$Reader = (New-Object System.Xml.XmlNodeReader $XAML)
+$Window = [Windows.Markup.XamlReader]::Load($Reader)
+
+If (!$Window) {
+ Exit
+}
+
+$Window.Add_Closing({
+ CleanVars
+ StopOO
+})
+
+$Window.Icon = "$RootPath\setup.ico"
+$BrowseSourcePathButton = $Window.FindName("Browse_SourcePath")
+$BrowseOutputPathButton = $Window.FindName("Browse_OutputPath")
+$ProcessButton = $Window.FindName("ProcessButton")
+$CancelButton = $Window.FindName("CancelButton")
+$PopulateButton = $Window.FindName("PopulateButton")
+$SelectUSB = $Window.FindName("SelectUSB")
+$SelectedUSB = $Window.FindName("SelectedUSB")
+$FlashToUSB = $Window.FindName("FlashToUSB")
+$SourcePath = $Window.FindName("SourcePath")
+$OutputPath = $Window.FindName("OutputPath")
+$OutputTab = $Window.FindName("OutputTab")
+$Console = $Window.FindName("Console")
+$CustomRegistry = $Window.FindName("CustomRegistry")
+$GeneralTab = $Window.FindName("GeneralTab")
+$WindowsAppsTab = $Window.FindName("WindowsAppsTab")
+$SystemAppsTab = $Window.FindName("SystemAppsTab")
+$CapabilitiesTab = $Window.FindName("CapabilitiesTab")
+$PackagesTab = $Window.FindName("PackagesTab")
+$FeaturesTab = $Window.FindName("FeaturesTab")
+$ServicesTab = $Window.FindName("ServicesTab")
+$CustomRegistryTab = $Window.FindName("CustomRegistryTab")
+
+Set-ControlsVisibility
+
+Foreach($ListType in $ListTypes) {
+ New-Variable -Name "$($ListType)ListView" -Value $Window.FindName("$($ListType)ListView")
+ New-Variable -Name "$($ListType)ListFilter" -Value $Window.FindName("$($ListType)ListFilter")
+ New-Variable -Name "$($ListType)ListType" -Value $Window.FindName("$($ListType)ListType")
+ New-Variable -Name "$($ListType)SelectAll" -Value $Window.FindName("$($ListType)SelectAll")
+ New-Variable -Name "$($ListType)SelectNone" -Value $Window.FindName("$($ListType)SelectNone")
+}
+
+Function SetControlsAccess {
+ param($Enabled)
+ $GeneralTab.IsEnabled = $Enabled
+ $WindowsAppsTab.IsEnabled = $Enabled
+ $SystemAppsTab.IsEnabled = $Enabled
+ $CapabilitiesTab.IsEnabled = $Enabled
+ $PackagesTab.IsEnabled = $Enabled
+ $FeaturesTab.IsEnabled = $Enabled
+ $ServicesTab.IsEnabled = $Enabled
+ $CustomRegistryTab.IsEnabled = $Enabled
+ $ProcessButton.IsEnabled = $Enabled
+ $CancelButton.IsEnabled = -not $Enabled
+ $PopulateButton.IsEnabled = $Enabled
+ $FlashToUSB.IsEnabled = $Enabled
+ $SelectUSB.IsEnabled = $Enabled
+ $SourcePath.IsEnabled = $Enabled
+ $BrowseSourcePathButton.IsEnabled = $Enabled
+ $OutputPath.IsEnabled = $Enabled
+ $BrowseOutputPathButton.IsEnabled = $Enabled
+}
+
+Function Save-Configuration {
+ foreach($ListType in $ListTypes){
+ If($Configuration.$ListType -and $ListTypesNoRemoval.IndexOf($ListType) -ge 0){
+ continue
+ }
+ $Control = $Window.FindName("$($ListType)ListType")
+ If($Configuration.$ListType -and $Control){
+ If($RemovalTypes.IndexOf($Control.SelectedItem.Content) -ge 0){
+ $Configuration.$ListType = $Control.SelectedItem.Content
+ } Else {
+ $Configuration.$ListType = $RemovalTypes[0]
+ }
+ }
+ }
+ $Configuration.Services = "Advanced"
+ $Configuration.FeaturesToEnable = "List"
+ $Configuration.FeaturesToDisable = "List"
+ $Configuration | ConvertTo-Json | Out-File -FilePath $Configuration_path -Encoding UTF8 -Force -ErrorAction Ignore
+}
+
+Function SetError {
+ param([string]$Err)
+ $OutputTab.IsSelected = $true
+ WriteToConsole -Text "`nError GUI: $Err" -Append
+}
+
+Function WriteToConsole {
+ param([string]$Text, [switch]$Append)
+
+ If($Append){
+ $Console.Text += $Text
+ } Else {
+ $Console.Text = $Text
+ }
+
+ $Console.ScrollToEnd()
+}
+
+Function RunOO {
+ param([switch]$populateTemplates)
+ $Global:populateTemplates = $populateTemplates
+ Try{
+ Save-Configuration
+ $OutputTab.IsSelected = $true
+ SetControlsAccess -Enabled $false
+ $Global:OO_GUI_Job = Start-Process powershell -WindowStyle Hidden -argument "Set-ExecutionPolicy Bypass -Scope Process -Force; & '$($OO_Root_Path)Start-Optimize.ps1' -GUI -FlashUSBDriveNumber $Global:OO_GUI_FlashUSBDriveNumber $(If($populateTemplates) {"-populateTemplates"} Else {''}) *>> '$($ConsoleSTDOutPath)'" -Verb RunAs -PassThru
+ $Global:OO_GUI_Timer.Start()
+ } Catch {
+ SetError -Err $Error[0]
+ SetControlsAccess -Enabled $true
+ $Global:OO_GUI_Timer.Stop()
+ If(Test-Path -path "$ConsoleSTDOutPath"){
+ Remove-Item -Path "$ConsoleSTDOutPath"
+ }
+ }
+}
+
+Function Kill-Tree {
+ Param([int]$ppid)
+ Get-CimInstance Win32_Process | Where-Object { $_.ParentProcessId -eq $ppid } | ForEach-Object { Kill-Tree $_.ProcessId } | Stop-Process -Id $ppid
+}
+
+Function StopOO {
+ If($Global:OO_GUI_Job) {
+ Kill-Tree $Global:OO_GUI_Job.Id
+ Stop-Process $Global:OO_GUI_Job
+ }
+}
+
+$ProcessButton.Add_Click({
+ RunOO
+})
+
+$CancelButton.Add_Click({
+ $continue = [System.Windows.MessageBox]::Show("Are you sure you want to cancel the processing job?", "Cancel processing", 'YesNo')
+ If($continue -eq 'Yes') {
+ StopOO
+ }
+})
+
+$PopulateButton.Add_Click({
+ RunOO -populateTemplates
+})
+
+$Window.DataContext = [PSCustomObject]@{
+ Configuration = [PSCustomObject]$Configuration
+}
+
+If(Test-Path -Path $Configuration.SourcePath) {
+ $SourcePath.Text = $Configuration.SourcePath
+ SetControlsAccess -Enabled $true
+}
+
+$OutputPath.Text = $Configuration.OutputPath
+$Configuration.FlashToUSB = "Off"
+
+$SelectedFlashToUSBIndex = @("UEFI", "Legacy").IndexOf($Configuration.FlashToUSB)
+If($SelectedFlashToUSBIndex -ge 0) {
+ $FlashToUSB.SelectedIndex = $SelectedFlashToUSBIndex
+}
+
+$BrowseSourcePathButton.Add_Click({
+ $FileBrowser = New-Object System.Windows.Forms.OpenFileDialog -Property @{
+ InitialDirectory = [Environment]::GetFolderPath('Desktop')
+ Filter = 'All allowed types|*.wim;*.swm;*.iso;*.esd;*.WIM;*.SWM;*.ISO;*.ESD'
+ Multiselect = $false
+ AddExtension = $true
+ CheckPathExists = $true
+ }
+
+ $null = $FileBrowser.ShowDialog()
+
+ If($FileBrowser.FileName -and $FileBrowser.FileName -ne $SourcePath.Text){
+ $SourcePath.Text = Get-Item -Path $FileBrowser.FileName
+ }
+})
+
+$BrowseOutputPathButton.Add_Click({
+ $SaveFileDialog = New-Object System.Windows.Forms.SaveFileDialog
+ $SaveFileDialog.InitialDirectory = [Environment]::GetFolderPath('Desktop')
+ $SourceExtension = (Get-Item $SourcePath.Text).Extension
+ $SaveFileDialog.Filter = "$($SourceExtension) files (*$($SourceExtension))| *$($SourceExtension)"
+ If($SaveFileDialog.ShowDialog() -eq 'Ok'){
+ $OutputPath.Text = $SaveFileDialog.FileName
+ }
+})
+
+$SourcePath.Add_TextChanged({
+ $Enabled = ("" -ne $SourcePath.Text.Trim() -and (Test-Path -Path $SourcePath.Text.Trim()))
+ $Configuration.SourcePath = $SourcePath.Text.Trim()
+ Save-Configuration
+ SetControlsAccess -Enabled $true
+ If($Enabled){
+ RunOO -populateTemplates
+ }
+})
+
+$OutputPath.Add_TextChanged({
+ $Configuration.OutputPath = $OutputPath.Text.Trim()
+ Save-Configuration
+})
+
+Foreach($ListType in $ListTypes) {
+
+ $SaveConfiguration = [ScriptBlock]::Create((Get-Item function:Save-Configuration).Definition)
+ $SaveList = [ScriptBlock]::Create((Get-Item function:Save-List).Definition)
+
+ $ListView = Get-Variable -Name "$($ListType)ListView" -ValueOnly
+
+ If(!$ListView){
+ Continue
+ }
+
+ $ListTemplate = (Get-Variable -Name "$($ListType)Template" -ValueOnly -Scope Global)
+ $ListView.ItemsSource = $ListTemplate
+
+ If($ListTypesNoRemoval.IndexOf($ListType) -eq -1){
+ (Get-Variable -Name "$($ListType)SelectAll" -ValueOnly).Add_Click({
+ $ListView.SelectAll()
+ $ListView.Focus()
+ }.GetNewClosure())
+ (Get-Variable -Name "$($ListType)SelectNone" -ValueOnly).Add_Click({
+ $ListView.UnselectAll()
+ $ListView.Focus()
+ }.GetNewClosure())
+ (Get-Variable -Name "$($ListType)ListType" -ValueOnly).Add_SelectionChanged({
+ $SaveConfiguration.Invoke()
+ $ListView.Focus()
+ }.GetNewClosure());
+ $ListView.Add_SelectionChanged({
+ $SaveList.Invoke($ListType)
+ }.GetNewClosure());
+ }
+
+ $ListFilter = Get-Variable -Name "$($ListType)ListFilter" -ValueOnly
+ $ListFilter.Add_TextChanged({
+ $ListTemplate = (Get-Variable -Name "$($ListType)Template" -ValueOnly -Scope Global)
+ If("" -eq $ListFilter.Text){
+ $ListView.ItemsSource = [PSCustomObject]$ListTemplate
+ $ListFilter.Focus()
+ return
+ }
+ $Filtered = @()
+ foreach($Item in $ListTemplate){
+ foreach($prop in $Item.PsObject.Properties)
+ {
+ If($prop.Value -like "*$($ListFilter.Text)*") {
+ $Filtered += $Item
+ Break
+ }
+ }
+ }
+ $ListView.ItemsSource = [PSCustomObject]$Filtered
+ $ListFilter.Focus()
+ }.GetNewClosure())
+}
+
+$TimerTick = {
+ If(Test-Path -Path "$ConsoleSTDOutPath"){
+ WriteToConsole -Text (Get-Content -Path "$ConsoleSTDOutPath" -Raw -Encoding utf8)
+ [Windows.Input.InputEventHandler]{ $Window.UpdateLayout() }
+ }
+ If($null -ne $Global:OO_GUI_Job.ExitCode){
+ $Global:OO_GUI_Timer.Stop()
+ SetControlsAccess -Enabled $true
+ If(Test-Path -Path "$ConsoleSTDOutPath"){
+ Remove-Item -Path "$ConsoleSTDOutPath"
+ }
+ Import-Templates
+ foreach($ListType in $ListTypes) {
+ $ListView = (Get-Variable -Name "$($ListType)ListView" -ValueOnly)
+ $ListView.ItemsSource = (Get-Variable -Name "$($ListType)Template" -ValueOnly -Scope Global)
+ }
+ Set-ControlsVisibility
+ Save-Configuration
+ WriteToConsole -Text "`nFinished" -Append
+ }
+}
+$Global:OO_GUI_Timer.Add_Tick($TimerTick)
+
+
+$ConfigurationDef.PSObject.Properties | ForEach-Object {
+ Foreach($Config in $_.Value.Controls) {
+ $Control = $Window.FindName($Config.Name)
+ If($Control){
+ Switch($Config.Type) {
+ "Combobox" {
+ $SaveConfiguration = [ScriptBlock]::Create((Get-Item function:Save-Configuration).Definition)
+ $Control.Add_SelectionChanged({
+ If($Config.Values.IndexOf($args[0].SelectedItem.Content) -gt -1){
+ $Configuration.($Config.Binding) = $args[0].SelectedItem.Content
+ }
+ $SaveConfiguration.Invoke()
+ }.GetNewClosure())
+ }
+ "Switch" {
+ $Control.Add_Checked({
+ Save-Configuration
+ })
+ $Control.Add_UnChecked({
+ Save-Configuration
+ })
+ }
+ }
+ }
+ }
+}
+
+$Window.FindName("FeaturesListView").Add_MouseLeave({
+ Save-Features
+})
+$Window.FindName("ServicesListView").Add_MouseLeave({
+ Save-Services
+})
+
+$FlashToUSB.Add_SelectionChanged({
+ If($Global:OO_GUI_FlashUSBDriveNumber -ge 0){
+ $Configuration.FlashToUSB = $FlashToUSB.SelectedItem.Content
+ } Else {
+ $Configuration.FlashToUSB = "Off"
+ }
+ Save-Configuration
+})
+$SelectUSB.Add_Click({
+ $SelectedUSB.IsEnabled = $false
+ $SelectedUSB.Visibility = "Collapsed"
+ $USBDrives = Get-Disk | Where-Object BusType -eq USB
+ If($USBDrives.Count -eq 0) {
+ [System.Windows.MessageBox]::Show('No USB drives found')
+ return
+ }
+ $USBDrive = $USBDrives | Out-GridView -Title 'Select USB Drive to Format' -OutputMode Single
+ If($USBDrive){
+ $SelectedUSB.Content = $USBDrive.FriendlyName
+ $Global:OO_GUI_FlashUSBDriveNumber = $USBDrive.Number
+ $Configuration.FlashToUSB = $FlashToUSB.SelectedItem.Content
+ Save-Configuration
+ $SelectedUSB.IsEnabled = $true
+ $SelectedUSB.Visibility = "Visible"
+ }
+})
+
+If(Test-Path -Path $CustomRegistryPath){
+ $CustomRegistry.Text = Get-Content -Path $CustomRegistryPath -Raw -ErrorAction Ignore
+}
+
+$CustomRegistry.Add_MouseLeave({
+ If($CustomRegistry.Text.Trim() -ne "Please input custom registry tweaks here."){
+ $CustomRegistry.Text.Trim() | Out-File -Path "$($OO_Root_Path)\Content\CustomRegistry.reg"
+ }
+});
+
+$Window.FindName("TabControl").Add_SelectionChanged({
+ $Window.UpdateLayout()
+ If($WindowsAppsTab.IsSelected){
+ $Window.FindName("WindowsAppsListView").Focus()
+ } Elseif ($SystemAppsTab.IsSelected){
+ $Window.FindName("SystemAppsListView").Focus()
+ } Elseif ($CapabilitiesTab.IsSelected){
+ $Window.FindName("CapabilitiesListView").Focus()
+ } Elseif ($PackagesTab.IsSelected){
+ $Window.FindName("PackagesListView").Focus()
+ }
+})
+
+Save-Configuration
+
+[Void]$Window.ShowDialog()
+
diff --git a/Src/GUI/XAML/CheckBox.xaml b/Src/GUI/XAML/CheckBox.xaml
new file mode 100644
index 0000000..8e73c7e
--- /dev/null
+++ b/Src/GUI/XAML/CheckBox.xaml
@@ -0,0 +1,20 @@
+
+ {Label}
+
+
+
+
+ {Tooltip}
+
+
\ No newline at end of file
diff --git a/Src/GUI/XAML/ComboBox.xaml b/Src/GUI/XAML/ComboBox.xaml
new file mode 100644
index 0000000..dc0e541
--- /dev/null
+++ b/Src/GUI/XAML/ComboBox.xaml
@@ -0,0 +1,13 @@
+
+
+ {Items}
+
\ No newline at end of file
diff --git a/Src/GUI/XAML/CustomRegistryTab.xaml b/Src/GUI/XAML/CustomRegistryTab.xaml
new file mode 100644
index 0000000..aea4ebe
--- /dev/null
+++ b/Src/GUI/XAML/CustomRegistryTab.xaml
@@ -0,0 +1,29 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Src/GUI/XAML/InputLayout.xaml b/Src/GUI/XAML/InputLayout.xaml
new file mode 100644
index 0000000..87cb86f
--- /dev/null
+++ b/Src/GUI/XAML/InputLayout.xaml
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
+ {Input}
+
\ No newline at end of file
diff --git a/Src/GUI/XAML/Layout.xaml b/Src/GUI/XAML/Layout.xaml
new file mode 100644
index 0000000..35bce2f
--- /dev/null
+++ b/Src/GUI/XAML/Layout.xaml
@@ -0,0 +1,52 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ UEFI
+ Legacy
+
+
+
+
+
+
+
+
+
+ {Tabs}
+
+
+
\ No newline at end of file
diff --git a/Src/GUI/XAML/ListRemovalComboTab.xaml b/Src/GUI/XAML/ListRemovalComboTab.xaml
new file mode 100644
index 0000000..9203dbc
--- /dev/null
+++ b/Src/GUI/XAML/ListRemovalComboTab.xaml
@@ -0,0 +1,25 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {Columns}
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Src/GUI/XAML/ListRemovalTab.xaml b/Src/GUI/XAML/ListRemovalTab.xaml
new file mode 100644
index 0000000..8c4b61a
--- /dev/null
+++ b/Src/GUI/XAML/ListRemovalTab.xaml
@@ -0,0 +1,32 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {Columns}
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Src/GUI/XAML/MainConfigGroupBox.xaml b/Src/GUI/XAML/MainConfigGroupBox.xaml
new file mode 100644
index 0000000..6207308
--- /dev/null
+++ b/Src/GUI/XAML/MainConfigGroupBox.xaml
@@ -0,0 +1,5 @@
+
+
+ {Content}
+
+
\ No newline at end of file
diff --git a/Src/GUI/XAML/MainConfigTab.xaml b/Src/GUI/XAML/MainConfigTab.xaml
new file mode 100644
index 0000000..0072a34
--- /dev/null
+++ b/Src/GUI/XAML/MainConfigTab.xaml
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
+ {ColsXAML}
+
diff --git a/Src/GUI/XAML/OutputTab.xaml b/Src/GUI/XAML/OutputTab.xaml
new file mode 100644
index 0000000..88c3415
--- /dev/null
+++ b/Src/GUI/XAML/OutputTab.xaml
@@ -0,0 +1,29 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Src/GUI/XAML/TabLayout.xaml b/Src/GUI/XAML/TabLayout.xaml
new file mode 100644
index 0000000..ced7f63
--- /dev/null
+++ b/Src/GUI/XAML/TabLayout.xaml
@@ -0,0 +1,5 @@
+
+
+ {TabContent}
+
+
\ No newline at end of file
diff --git a/Src/GUI/XAML/TabScroll.xaml b/Src/GUI/XAML/TabScroll.xaml
new file mode 100644
index 0000000..b35bd95
--- /dev/null
+++ b/Src/GUI/XAML/TabScroll.xaml
@@ -0,0 +1,7 @@
+
+
+
+ {TabContent}
+
+
+
\ No newline at end of file
diff --git a/Src/GUI/image_info.json b/Src/GUI/image_info.json
new file mode 100644
index 0000000..c677510
--- /dev/null
+++ b/Src/GUI/image_info.json
@@ -0,0 +1,3 @@
+{
+
+}
diff --git a/Src/GUI/setup.ico b/Src/GUI/setup.ico
new file mode 100644
index 0000000..fbd1184
Binary files /dev/null and b/Src/GUI/setup.ico differ
diff --git a/Src/Offline-Resources.psm1 b/Src/Offline-Resources.psm1
index 3cee6c8..290892d 100644
--- a/Src/Offline-Resources.psm1
+++ b/Src/Offline-Resources.psm1
@@ -3,11 +3,11 @@
#Requires -Version 5.1
<#
===========================================================================
- Created with: SAPIEN Technologies, Inc., PowerShell Studio 2021 v5.8.191
+ Created with: SAPIEN Technologies, Inc., PowerShell Studio 2023 v5.8.218
Created on: 11/20/2019 11:53 AM
Created by: BenTheGreat
Filename: Offline-Resources.psm1
- Last updated: 06/22/2021
+ Last updated: 02/16/2023
-------------------------------------------------------------------------
Module Name: Offline-Resources
===========================================================================
@@ -43,13 +43,14 @@ $OptimizeOffline.Directory = (Resolve-FullPath -Path $OptimizeOffline.Path -Spli
$OptimizeOffline.Culture = 'en-US'
$OptimizeOffline.Resources = (Resolve-FullPath -Path $OptimizeOffline.Directory -Child Src)
$OptimizeOffline.Content = (Resolve-FullPath -Path $OptimizeOffline.Directory -Child Content)
+$OptimizeOffline.CustomRegistry = (Resolve-FullPath -Path $OptimizeOffline.Content -Child CustomRegistry.reg)
$OptimizeOffline.LocalizedData = (Resolve-FullPath -Path $OptimizeOffline.Directory -Child $OptimizeOffline.Culture)
$OptimizeOffline.Additional = (Resolve-FullPath -Path $OptimizeOffline.Content -Child Additional)
+$OptimizeOffline.Assets = (Resolve-FullPath -Path $OptimizeOffline.Content -Child Assets)
$OptimizeOffline.Packages = (Resolve-FullPath -Path $OptimizeOffline.Directory -Child Packages)
$OptimizeOffline.LocalizedDataStrings = (Resolve-FullPath -Path $OptimizeOffline.LocalizedData -Child Optimize-Offline.strings.psd1)
$OptimizeOffline.ConfigurationJSON = (Resolve-FullPath -Path $OptimizeOffline.Directory -Child Configuration.json)
$OptimizeOffline.ManifestDataFile = (Resolve-FullPath -Path $OptimizeOffline.Directory -Child Optimize-Offline.psd1)
-$OptimizeOffline.AppxWhitelist = (Resolve-FullPath -Path $OptimizeOffline.Content -Child AppxWhitelist.json)
$OptimizeOffline.CustomAppAssociations = (Resolve-FullPath -Path $OptimizeOffline.Content -Child CustomAppAssociations.xml)
$OptimizeOffline.DevMode = (Resolve-FullPath -Path $OptimizeOffline.Packages -Child DeveloperMode)
$OptimizeOffline.WindowsStore = (Resolve-FullPath -Path $OptimizeOffline.Packages -Child WindowsStore)
@@ -68,8 +69,59 @@ $OptimizeOffline.Drivers = (Resolve-FullPath -Path $OptimizeOffline.Additional -
$OptimizeOffline.InstallDrivers = (Resolve-FullPath -Path $OptimizeOffline.Drivers -Child Install)
$OptimizeOffline.BootDrivers = (Resolve-FullPath -Path $OptimizeOffline.Drivers -Child Boot)
$OptimizeOffline.RecoveryDrivers = (Resolve-FullPath -Path $OptimizeOffline.Drivers -Child Recovery)
+$OptimizeOffline.SelectiveRegistry = (Resolve-FullPath -Path $OptimizeOffline.Additional -Child SelectiveRegistry)
#endregion Module Path Declarations
+
+#region List paths
+$OptimizeOffline.Lists = @{}
+$OptimizeOffline.Lists.Path = (Resolve-FullPath -Path $OptimizeOffline.Content -Child Lists)
+
+$OptimizeOffline.Lists.WindowsAppsPath = (Resolve-FullPath -Path $OptimizeOffline.Lists.Path -Child WindowsApps)
+$OptimizeOffline.Lists.WindowsAppsList = (Resolve-FullPath -Path $OptimizeOffline.Lists.WindowsAppsPath -Child WindowsAppsList.json)
+$OptimizeOffline.Lists.WindowsAppsTemplate = (Resolve-FullPath -Path $OptimizeOffline.Lists.WindowsAppsPath -Child WindowsAppsTemplate.json)
+
+$OptimizeOffline.Lists.SystemAppsPath = (Resolve-FullPath -Path $OptimizeOffline.Lists.Path -Child SystemApps)
+$OptimizeOffline.Lists.SystemAppsList = (Resolve-FullPath -Path $OptimizeOffline.Lists.SystemAppsPath -Child SystemAppsList.json)
+$OptimizeOffline.Lists.SystemAppsTemplate = (Resolve-FullPath -Path $OptimizeOffline.Lists.SystemAppsPath -Child SystemAppsTemplate.json)
+
+$OptimizeOffline.Lists.CapabilitiesPath = (Resolve-FullPath -Path $OptimizeOffline.Lists.Path -Child Capabilities)
+$OptimizeOffline.Lists.CapabilitiesList = (Resolve-FullPath -Path $OptimizeOffline.Lists.CapabilitiesPath -Child CapabilitiesList.json)
+$OptimizeOffline.Lists.CapabilitiesTemplate = (Resolve-FullPath -Path $OptimizeOffline.Lists.CapabilitiesPath -Child CapabilitiesTemplate.json)
+
+$OptimizeOffline.Lists.PackagesPath = (Resolve-FullPath -Path $OptimizeOffline.Lists.Path -Child Packages)
+$OptimizeOffline.Lists.PackagesList = (Resolve-FullPath -Path $OptimizeOffline.Lists.PackagesPath -Child PackagesList.json)
+$OptimizeOffline.Lists.PackagesTemplate = (Resolve-FullPath -Path $OptimizeOffline.Lists.PackagesPath -Child PackagesTemplate.json)
+
+$OptimizeOffline.Lists.FeaturesToEnablePath = (Resolve-FullPath -Path $OptimizeOffline.Lists.Path -Child FeaturesToEnable)
+$OptimizeOffline.Lists.FeaturesToEnableList = (Resolve-FullPath -Path $OptimizeOffline.Lists.FeaturesToEnablePath -Child FeaturesToEnableList.json)
+$OptimizeOffline.Lists.FeaturesToEnableTemplate = (Resolve-FullPath -Path $OptimizeOffline.Lists.FeaturesToEnablePath -Child FeaturesToEnableTemplate.json)
+
+$OptimizeOffline.Lists.FeaturesToDisablePath = (Resolve-FullPath -Path $OptimizeOffline.Lists.Path -Child FeaturesToDisable)
+$OptimizeOffline.Lists.FeaturesToDisableList = (Resolve-FullPath -Path $OptimizeOffline.Lists.FeaturesToDisablePath -Child FeaturesToDisableList.json)
+$OptimizeOffline.Lists.FeaturesToDisableTemplate = (Resolve-FullPath -Path $OptimizeOffline.Lists.FeaturesToDisablePath -Child FeaturesToDisableTemplate.json)
+
+$OptimizeOffline.Lists.ServicesPath = (Resolve-FullPath -Path $OptimizeOffline.Lists.Path -Child Services)
+$OptimizeOffline.Lists.ServicesList = (Resolve-FullPath -Path $OptimizeOffline.Lists.ServicesPath -Child ServicesList.json)
+$OptimizeOffline.Lists.ServicesAdvanced = (Resolve-FullPath -Path $OptimizeOffline.Lists.ServicesPath -Child ServicesAdvanced.json)
+$OptimizeOffline.Lists.ServicesTemplate = (Resolve-FullPath -Path $OptimizeOffline.Lists.ServicesPath -Child ServicesTemplate.json)
+#endregion List paths
+
+## startregion GUI paths
+$OptimizeOffline.GUI = @{
+ Main = (Resolve-FullPath -Path $OptimizeOffline.Resources -Child GUI)
+}
+$OptimizeOffline.GUI.RemovalTemplates = @{
+ Main = (Resolve-FullPath -Path $OptimizeOffline.GUI.Main -Child RemovalTemplates)
+}
+$OptimizeOffline.GUI.RemovalTemplates.WindowsApps = (Resolve-FullPath -Path $OptimizeOffline.GUI.RemovalTemplates.Main -Child WindowsAppsTemplate.json)
+$OptimizeOffline.GUI.RemovalTemplates.SystemApps = (Resolve-FullPath -Path $OptimizeOffline.GUI.RemovalTemplates.Main -Child SystemAppsTemplate.json)
+$OptimizeOffline.GUI.RemovalTemplates.Packages = (Resolve-FullPath -Path $OptimizeOffline.GUI.RemovalTemplates.Main -Child PackagesTemplate.json)
+$OptimizeOffline.GUI.RemovalTemplates.Capabilities = (Resolve-FullPath -Path $OptimizeOffline.GUI.RemovalTemplates.Main -Child CapabilitiesTemplate.json)
+$OptimizeOffline.GUI.RemovalTemplates.Features = (Resolve-FullPath -Path $OptimizeOffline.GUI.RemovalTemplates.Main -Child FeaturesTemplate.json)
+$OptimizeOffline.GUI.RemovalTemplates.Services = (Resolve-FullPath -Path $OptimizeOffline.GUI.RemovalTemplates.Main -Child ServicesTemplate.json)
+## endregion GUI paths
+
#region Data Declarations
Try { $ManifestData = Import-PowerShellDataFile -Path $OptimizeOffline.ManifestDataFile -ErrorAction Stop }
Catch { Write-Warning ('Failed to import the manifest data file: "{0}"' -f (Resolve-FullPath -Path $OptimizeOffline.ManifestDataFile -Split Leaf)); Break }
@@ -78,6 +130,16 @@ Try { Import-LocalizedData -BaseDirectory $OptimizeOffline.Directory -FileName O
Catch { Write-Warning ('Failed to import the localized data file: "{0}"' -f (Resolve-FullPath -Path $OptimizeOffline.LocalizedDataStrings -Split Leaf)); Break }
#endregion Data Declarations
+#region translations
+$OptimizeOffline.ServicesStartLabels = @(
+ $OptimizeData.ServiceStartBoot,
+ $OptimizeData.ServiceStartSystem,
+ $OptimizeData.ServiceStartAutomatic,
+ $OptimizeData.ServiceStartManual,
+ $OptimizeData.ServiceStartDisabled
+)
+#endregion translations
+
#region Variable Declarations
$LocalScope = [PSCustomObject]::New()
$OptimizeOfflineParams = [PSCustomObject]::New()
@@ -96,11 +158,18 @@ $ModuleLog = (Resolve-FullPath -Path $LogFolder -Child Optimize-Offline.log)
$ErrorLog = (Resolve-FullPath -Path $LogFolder -Child OptimizeErrors.log)
$RegistryLog = (Resolve-FullPath -Path $LogFolder -Child RegistrySettings.log)
$DISMLog = (Resolve-FullPath -Path $LogFolder -Child DISM.log)
-$DISM = If (Get-DeploymentTool) { Resolve-FullPath -Path $(Get-DeploymentTool) -Child dism.exe } Else { Resolve-FullPath -Path $Env:SystemRoot -Child 'System32\dism.exe' }
-$OSCDIMG = If (Get-DeploymentTool -OSCDIMG) { Resolve-FullPath -Path $(Get-DeploymentTool -OSCDIMG) -Child oscdimg.exe } Else { $null }
+$OSCDIMG = If (Get-DeploymentTool -OSCDIMG) {
+ Resolve-FullPath -Path $(Get-DeploymentTool -OSCDIMG) -Child oscdimg.exe
+} Elseif (Test-Path -Path $(Resolve-FullPath -Path $OptimizeOffline.Directory -Child oscdimg.exe)) {
+ Resolve-FullPath -Path $OptimizeOffline.Directory -Child oscdimg.exe
+} Else {
+ $null
+}
+$DISM = If (Get-DISMPath) { Resolve-FullPath -Path $(Get-DISMPath) -Child dism.exe } Else { Resolve-FullPath -Path $Env:SystemRoot -Child 'System32\dism.exe' }
$REG = (Resolve-FullPath -Path $Env:SystemRoot -Child 'System32\reg.exe')
$REGEDIT = (Resolve-FullPath -Path $Env:SystemRoot -Child regedit.exe)
$EXPAND = (Resolve-FullPath -Path $Env:SystemRoot -Child 'System32\expand.exe')
+$AllowedRemovalOptions = @('All', 'Select', 'List', 'Whitelist', 'BlackList', 'Advanced')
#endregion Variable Declarations
#region Resource Alias Creation
@@ -115,7 +184,7 @@ New-Alias -Name GetPath -Value Resolve-FullPath
$ExportResourceParams = @{
Function = $PublicFunctions.Basename
- Variable = 'OptimizeOffline', 'ManifestData', 'OptimizeData', 'LocalScope', 'OptimizeParams', 'DynamicParams', 'ConfigParams', 'OptimizeErrors', 'TempDirectory', 'LogFolder', 'WorkFolder', 'ScratchFolder', 'ImageFolder', 'InstallMount', 'BootMount', 'RecoveryMount', 'ModuleLog', 'ErrorLog', 'RegistryLog', 'DISMLog', 'DISM', 'OSCDIMG', 'REG', 'REGEDIT', 'EXPAND'
+ Variable = 'OptimizeOffline', 'ManifestData', 'OptimizeData', 'LocalScope', 'OptimizeParams', 'DynamicParams', 'ConfigParams', 'OptimizeErrors', 'TempDirectory', 'LogFolder', 'WorkFolder', 'ScratchFolder', 'ImageFolder', 'InstallMount', 'BootMount', 'RecoveryMount', 'ModuleLog', 'ErrorLog', 'RegistryLog', 'DISMLog', 'DISM', 'OSCDIMG', 'REG', 'REGEDIT', 'EXPAND', 'AllowedRemovalOptions'
Alias = '*'
}
Export-ModuleMember @ExportResourceParams
diff --git a/Src/Private/Get-DISMPath.ps1 b/Src/Private/Get-DISMPath.ps1
new file mode 100644
index 0000000..6826b96
--- /dev/null
+++ b/Src/Private/Get-DISMPath.ps1
@@ -0,0 +1,9 @@
+Function Get-DISMPath
+{
+ [CmdletBinding()]
+ [OutputType([IO.DirectoryInfo])]
+ Param ()
+
+ [IO.DirectoryInfo]$DISMPath = @("HKLM:\SOFTWARE\WOW6432Node\Microsoft\Windows Kits\Installed Roots", "HKLM:\SOFTWARE\Microsoft\Windows Kits\Installed Roots") | ForEach-Object -Process { Get-ItemProperty -Path $PSItem -ErrorAction Ignore } | Select-Object -Unique -ExpandProperty KitsRoot10 -ErrorAction Ignore | Join-Path -ChildPath "Assessment and Deployment Kit\Deployment Tools\$Env:PROCESSOR_ARCHITECTURE\DISM" -ErrorAction Ignore
+ If ($DISMPath.Exists) { $DISMPath.FullName }
+}
\ No newline at end of file
diff --git a/Src/Public/DIR2ISO.ps1 b/Src/Public/DIR2ISO.ps1
new file mode 100644
index 0000000..226f33c
--- /dev/null
+++ b/Src/Public/DIR2ISO.ps1
@@ -0,0 +1,55 @@
+function :DIR2ISO ($dir, $iso, $prompt = $true, $VolumeName = 'DVD_ROM') {
+ if (!(test-path -Path $dir -pathtype Container)) {
+ return $false
+ }
+ $dir2iso = @"
+using System; using System.IO; using System.Runtime.Interop`Services; using System.Runtime.Interop`Services.ComTypes;
+public class dir2iso {public int AveYo=2021; [Dll`Import("shlwapi",CharSet=CharSet.Unicode,PreserveSig=false)]
+internal static extern void SHCreateStreamOnFileEx(string f,uint m,uint d,bool b,IStream r,out IStream s);
+public static void Create(string file, ref object obj, int bs, int tb) { IStream dir=(IStream)obj, iso;
+try {SHCreateStreamOnFileEx(file,0x1001,0x80,true,null,out iso);} catch(Exception e) {Console.WriteLine(e.Message); return;}
+int d=tb>1024 ? 1024 : 1, pad=tb%d, block=bs*d, total=(tb-pad)/d, c=total>100 ? total/100 : total, i=1, MB=(bs/1024)*tb/1024;
+Console.Write("{0,3}% {1}MB {2} :DIR2ISO",0,MB,file); if (pad > 0) dir.CopyTo(iso, pad * block, Int`Ptr.Zero, Int`Ptr.Zero);
+while (total-- > 0) {dir.CopyTo(iso, block, Int`Ptr.Zero, Int`Ptr.Zero); if (total % c == 0) {Console.Write("\r{0,3}%",i++);}}
+iso.Commit(0); Console.WriteLine("\r{0,3}% {1}MB {2} :DIR2ISO", 100, MB, file); } }
+"@; & {
+ $cs = new-object CodeDom.Compiler.CompilerParameters
+ $cs.GenerateInMemory = 1 #,# no`warnings
+ $compile = (new-object Microsoft.CSharp.CSharpCodeProvider).CompileAssemblyFromSource($cs, $dir2iso)
+ $BOOT = @()
+ $bootable = 0
+ $mbr_efi = @(0, 0xEF)
+ $images = @('boot\etfsboot.com', "efi\microsoft\boot\efisys$(If (-not $prompt) {"_noprompt"}).bin")
+
+ 0, 1 | % {
+ $bootimage = join-path $dir -child $images[$_]
+ if (test-path -Path $bootimage -pathtype Leaf) {
+ $bin = new-object -ComObject ADODB.Stream
+ $bin.Open()
+ $bin.Type = 1
+ $bin.LoadFromFile($bootimage)
+ $opt = new-object -ComObject IMAPI2FS.BootOptions
+ $opt.AssignBootImage($bin.psobject.BaseObject)
+ $opt.Manufacturer = 'Microsoft'
+ $opt.PlatformId = $mbr_efi[$_]
+ $opt.Emulation = 0
+ $bootable = 1
+ $BOOT += $opt.psobject.BaseObject
+ }
+ }
+
+ $fsi = new-object -ComObject IMAPI2FS.MsftFileSystemImage
+ $fsi.FileSystemsToCreate = 4
+ $fsi.FreeMediaBlocks = 0
+ if ($bootable) {
+ $fsi.BootImageOptionsArray = $BOOT
+ }
+ $CONTENT = $fsi.Root
+ $CONTENT.AddTree($dir, $false)
+ $fsi.VolumeName = $VolumeName
+ $obj = $fsi.CreateResultImage()
+ [dir2iso]::Create($iso, [ref]$obj.ImageStream, $obj.BlockSize, $obj.TotalBlocks)
+ }
+ [GC]::Collect()
+ return $true
+} $:DIR2ISO: #,# export directory as (bootable) udf iso - lean and mean snippet by AveYo, 2021
\ No newline at end of file
diff --git a/Src/Public/Get-AppxPackages.ps1 b/Src/Public/Get-AppxPackages.ps1
new file mode 100644
index 0000000..e1e00fc
--- /dev/null
+++ b/Src/Public/Get-AppxPackages.ps1
@@ -0,0 +1,33 @@
+Function Get-AppxPackages {
+
+ [CmdletBinding()]
+
+ Param (
+ [Parameter(Mandatory = $true,
+ HelpMessage = 'full path to the root directory of the offline Windows image that you will service.')]
+ [String]$Path,
+ [Parameter(Mandatory = $false,
+ HelpMessage = 'Specifies a temporary directory that will be used when extracting files for use during servicing. The directory must exist locally. If not specified, the \Windows\%Temp% directory will be used')]
+ [String]$ScratchDirectory,
+ [Parameter(Mandatory = $false,
+ HelpMessage = 'the full path and file name to log to. If not set, the default is %WINDIR%\Logs\Dism\dism.log')]
+ [String]$LogPath
+ )
+
+ If($Global:InstallInfo.InstallationType.ToLower().Contains('server core')) {
+ return @{}
+ }
+
+ $AppxPackages = Get-AppxProvisionedPackage -Path $Path -ScratchDirectory $ScratchDirectory -LogPath $LogPath -LogLevel 1 | Select-Object -Property DisplayName, PackageName | Sort-Object -Property DisplayName
+
+ If ($Global:InstallInfo.Build -ge '19041')
+ {
+ $AppxPackages = $AppxPackages | ForEach-Object -Process {
+ $DisplayName = $PSItem.DisplayName; $PackageName = $PSItem.PackageName
+ If ($DisplayName -eq 'Microsoft.549981C3F5F10') { $DisplayName = 'CortanaApp.View.App' }
+ [PSCustomObject]@{ DisplayName = $DisplayName; PackageName = $PackageName }
+ }
+ }
+
+ return $AppxPackages
+}
\ No newline at end of file
diff --git a/Src/Public/Get-CapabilityPackages.ps1 b/Src/Public/Get-CapabilityPackages.ps1
new file mode 100644
index 0000000..df240af
--- /dev/null
+++ b/Src/Public/Get-CapabilityPackages.ps1
@@ -0,0 +1,21 @@
+Function Get-CapabilityPackages {
+
+ [CmdletBinding()]
+
+ Param (
+ [Parameter(Mandatory = $true,
+ HelpMessage = 'full path to the root directory of the offline Windows image that you will service.')]
+ [String]$Path,
+ [Parameter(Mandatory = $false,
+ HelpMessage = 'Specifies a temporary directory that will be used when extracting files for use during servicing. The directory must exist locally. If not specified, the \Windows\%Temp% directory will be used')]
+ [String]$ScratchDirectory,
+ [Parameter(Mandatory = $false,
+ HelpMessage = 'the full path and file name to log to. If not set, the default is %WINDIR%\Logs\Dism\dism.log')]
+ [String]$LogPath
+ )
+
+ $WindowsCapabilities = Get-WindowsCapability -Path $Path -ScratchDirectory $ScratchDirectory -LogPath $LogPath -LogLevel 1 | Where-Object { $PSItem.Name -notlike "*Language.Basic*" -and $PSItem.Name -notlike "*TextToSpeech*" -and $PSItem.State -eq 'Installed' } | Select-Object -Property Name, State | Sort-Object -Property Name
+
+ return $WindowsCapabilities
+
+}
\ No newline at end of file
diff --git a/Src/Public/Get-ImageData.ps1 b/Src/Public/Get-ImageData.ps1
index 2dbf5bc..7fcafe8 100644
--- a/Src/Public/Get-ImageData.ps1
+++ b/Src/Public/Get-ImageData.ps1
@@ -69,6 +69,18 @@ Function Get-ImageData
$ImageData.Build = $CurrentVersion.CurrentBuildNumber
If ($CurrentVersion.DisplayVersion -eq '21H1') { $ImageData.CodeName = $CurrentVersion.DisplayVersion }
}
+ ElseIf ($ImageData.Build -eq '19041' -and $CurrentVersion.CurrentBuildNumber -eq '19044')
+ {
+ $ImageData.Version = $ImageData.Version.Replace($ImageData.Build, $CurrentVersion.CurrentBuildNumber)
+ $ImageData.Build = $CurrentVersion.CurrentBuildNumber
+ If ($CurrentVersion.DisplayVersion -eq '21H2') { $ImageData.CodeName = $CurrentVersion.DisplayVersion }
+ }
+ ElseIf ($ImageData.Build -eq '19041' -and $CurrentVersion.CurrentBuildNumber -eq '19045')
+ {
+ $ImageData.Version = $ImageData.Version.Replace($ImageData.Build, $CurrentVersion.CurrentBuildNumber)
+ $ImageData.Build = $CurrentVersion.CurrentBuildNumber
+ If ($CurrentVersion.DisplayVersion -eq '22H2') { $ImageData.CodeName = $CurrentVersion.DisplayVersion }
+ }
Else
{
If ($ImageData.Build -eq '19041') { $ImageData.CodeName = '20H1' }
diff --git a/Src/Public/Get-ImageServices.ps1 b/Src/Public/Get-ImageServices.ps1
new file mode 100644
index 0000000..c9b93db
--- /dev/null
+++ b/Src/Public/Get-ImageServices.ps1
@@ -0,0 +1,29 @@
+Function Get-ImageServices {
+ $ServicesStartLabels = @(
+ "Boot",
+ "System",
+ "Automatic",
+ "Manual",
+ "Disabled"
+ )
+ $RegPath = "HKLM:\WIM_HKLM_SYSTEM\ControlSet001\Services"
+ $Services = [System.Collections.ArrayList]@();
+ Get-ChildItem -Path $RegPath | Where-Object{$_.ValueCount -gt 0} | ForEach-Object -Process {
+
+ $ServiceDetails = Get-Service -Name $PSItem.PSChildName -ErrorAction Ignore
+
+ $FolderKeys = Get-ItemProperty -Path "$RegPath\$($PSItem.PSChildName)"
+
+ If($null -ne $FolderKeys.Start -and $null -eq $FolderKeys.Owners -and $FolderKeys.Start -ne 4 -and $FolderKeys.Start -gt 1){
+ $O = New-Object PSObject -Property @{
+ name = [String]$PSItem.PSChildName
+ description = $(If ($null -ne $ServiceDetails -and $null -ne $ServiceDetails.DisplayName) {$ServiceDetails.DisplayName} Else {""})
+ start = $FolderKeys.Start
+ startLabel = $ServicesStartLabels[$FolderKeys.Start]
+ }
+ [void]$Services.Add($O)
+ }
+ }
+
+ return $Services
+}
\ No newline at end of file
diff --git a/Src/Public/Get-OfflineHives.ps1 b/Src/Public/Get-OfflineHives.ps1
index 04ccca9..4fef915 100644
--- a/Src/Public/Get-OfflineHives.ps1
+++ b/Src/Public/Get-OfflineHives.ps1
@@ -11,8 +11,22 @@ Function Get-OfflineHives
Begin
{
- $Hive = [Ordered]@{ SOFTWARE = (GetPath -Path $InstallMount -Child 'Windows\System32\Config\SOFTWARE'); SYSTEM = (GetPath -Path $InstallMount -Child 'Windows\System32\Config\SYSTEM'); DEFAULT = (GetPath -Path $InstallMount -Child 'Windows\System32\Config\DEFAULT'); NTUSER = (GetPath -Path $InstallMount -Child 'Users\Default\NTUSER.DAT') }
- $HiveMountPoint = [Ordered]@{ SOFTWARE = 'WIM_HKLM_SOFTWARE'; SYSTEM = 'WIM_HKLM_SYSTEM'; DEFAULT = 'WIM_HKU_DEFAULT'; NTUSER = 'WIM_HKCU' }
+ $Hive = [Ordered]@{
+ SOFTWARE = (GetPath -Path $InstallMount -Child 'Windows\System32\Config\SOFTWARE');
+ SYSTEM = (GetPath -Path $InstallMount -Child 'Windows\System32\Config\SYSTEM');
+ DEFAULT = (GetPath -Path $InstallMount -Child 'Windows\System32\Config\DEFAULT');
+ NTUSER = (GetPath -Path $InstallMount -Child 'Users\Default\NTUSER.DAT');
+ }
+ $HiveMountPoint = [Ordered]@{
+ SOFTWARE = 'WIM_HKLM_SOFTWARE';
+ SYSTEM = 'WIM_HKLM_SYSTEM';
+ DEFAULT = 'WIM_HKU_DEFAULT';
+ NTUSER = 'WIM_HKCU';
+ SYSTEM_BOOT = 'BOOT_HKLM_SYSTEM';
+ }
+ If(Test-Path -Path (GetPath -Path $BootMount -Child 'Windows\System32\Config\SYSTEM')) {
+ $Hive.SYSTEM_BOOT = (GetPath -Path $BootMount -Child 'Windows\System32\Config\SYSTEM')
+ }
$HKLM = 0x80000002
'SeBackupPrivilege', 'SeRestorePrivilege' | Grant-Privilege
}
@@ -30,6 +44,9 @@ Function Get-OfflineHives
[Void]$RegLoad::RegLoadKey($HKLM, $HiveMountPoint.SYSTEM, $Hive.SYSTEM)
[Void]$RegLoad::RegLoadKey($HKLM, $HiveMountPoint.DEFAULT, $Hive.DEFAULT)
[Void]$RegLoad::RegLoadKey($HKLM, $HiveMountPoint.NTUSER, $Hive.NTUSER)
+ If($Hive.SYSTEM_BOOT) {
+ [Void]$RegLoad::RegLoadKey($HKLM, $HiveMountPoint.SYSTEM_BOOT, $Hive.SYSTEM_BOOT)
+ }
}
Break
}
@@ -40,7 +57,7 @@ Function Get-OfflineHives
$RegUnload = Import-Win32API -Unload
[GC]::Collect()
[GC]::WaitForPendingFinalizers()
- $Retries = 5
+ $Retries = $HiveMountPoint.Values.Count + 1
While ($Retries -gt 0 -and $HivesMounted)
{
$HiveMountPoint.Values.ForEach{ [Void]$RegUnload::RegUnLoadKey($HKLM, $PSItem) }
diff --git a/Src/Public/Get-OptionalDisabledFeatures.ps1 b/Src/Public/Get-OptionalDisabledFeatures.ps1
new file mode 100644
index 0000000..19faf96
--- /dev/null
+++ b/Src/Public/Get-OptionalDisabledFeatures.ps1
@@ -0,0 +1,18 @@
+Function Get-OptionalDisabledFeatures {
+
+ [CmdletBinding()]
+
+ Param (
+ [Parameter(Mandatory = $true,
+ HelpMessage = 'full path to the root directory of the offline Windows image that you will service.')]
+ [String]$Path,
+ [Parameter(Mandatory = $false,
+ HelpMessage = 'Specifies a temporary directory that will be used when extracting files for use during servicing. The directory must exist locally. If not specified, the \Windows\%Temp% directory will be used')]
+ [String]$ScratchDirectory,
+ [Parameter(Mandatory = $false,
+ HelpMessage = 'the full path and file name to log to. If not set, the default is %WINDIR%\Logs\Dism\dism.log')]
+ [String]$LogPath
+ )
+
+ return Get-WindowsOptionalFeature -Path $Path -ScratchDirectory $ScratchDirectory -LogPath $LogPath -LogLevel 1 | Select-Object -Property FeatureName, State | Sort-Object -Property FeatureName | Where-Object { $PSItem.FeatureName -notlike "SMB1Protocol*" -and $PSItem.FeatureName -ne "Windows-Defender-Default-Definitions" -and $PSItem.FeatureName -notlike "MicrosoftWindowsPowerShellV2*" -and $PSItem.State -eq "Disabled" }
+}
\ No newline at end of file
diff --git a/Src/Public/Get-OptionalEnabledFeatures.ps1 b/Src/Public/Get-OptionalEnabledFeatures.ps1
new file mode 100644
index 0000000..aa8f675
--- /dev/null
+++ b/Src/Public/Get-OptionalEnabledFeatures.ps1
@@ -0,0 +1,18 @@
+Function Get-OptionalEnabledFeatures {
+
+ [CmdletBinding()]
+
+ Param (
+ [Parameter(Mandatory = $true,
+ HelpMessage = 'full path to the root directory of the offline Windows image that you will service.')]
+ [String]$Path,
+ [Parameter(Mandatory = $false,
+ HelpMessage = 'Specifies a temporary directory that will be used when extracting files for use during servicing. The directory must exist locally. If not specified, the \Windows\%Temp% directory will be used')]
+ [String]$ScratchDirectory,
+ [Parameter(Mandatory = $false,
+ HelpMessage = 'the full path and file name to log to. If not set, the default is %WINDIR%\Logs\Dism\dism.log')]
+ [String]$LogPath
+ )
+
+ return Get-WindowsOptionalFeature -Path $Path -ScratchDirectory $ScratchDirectory -LogPath $LogPath -LogLevel 1 | Select-Object -Property FeatureName, State | Sort-Object -Property FeatureName | Where-Object -Property State -EQ Enabled
+}
\ No newline at end of file
diff --git a/Src/Public/Get-OtherWindowsPackages.ps1 b/Src/Public/Get-OtherWindowsPackages.ps1
new file mode 100644
index 0000000..18076e7
--- /dev/null
+++ b/Src/Public/Get-OtherWindowsPackages.ps1
@@ -0,0 +1,19 @@
+Function Get-OtherWindowsPackages {
+
+ [CmdletBinding()]
+
+ Param (
+ [Parameter(Mandatory = $true,
+ HelpMessage = 'full path to the root directory of the offline Windows image that you will service.')]
+ [String]$Path,
+ [Parameter(Mandatory = $false,
+ HelpMessage = 'Specifies a temporary directory that will be used when extracting files for use during servicing. The directory must exist locally. If not specified, the \Windows\%Temp% directory will be used')]
+ [String]$ScratchDirectory,
+ [Parameter(Mandatory = $false,
+ HelpMessage = 'the full path and file name to log to. If not set, the default is %WINDIR%\Logs\Dism\dism.log')]
+ [String]$LogPath
+ )
+
+
+ return Get-WindowsPackage -Path $Path -ScratchDirectory $ScratchDirectory -LogPath $LogPath -LogLevel 1 | Where-Object { $PSItem.ReleaseType -eq 'OnDemandPack' -or $PSItem.ReleaseType -eq 'LanguagePack' -or $PSItem.ReleaseType -eq 'FeaturePack' -and $PSItem.PackageName -notlike "*20H2Enablement*" -and $PSItem.PackageName -notlike "*LanguageFeatures-Basic*" -and $PSItem.PackageName -notlike "*LanguageFeatures-TextToSpeech*" -and $PSItem.PackageState -eq 'Installed' } | Select-Object -Property PackageName, ReleaseType | Sort-Object -Property PackageName
+}
\ No newline at end of file
diff --git a/Src/Public/Get-PathSize.ps1 b/Src/Public/Get-PathSize.ps1
new file mode 100644
index 0000000..82cace1
--- /dev/null
+++ b/Src/Public/Get-PathSize.ps1
@@ -0,0 +1,12 @@
+Function Get-PathSize {
+ Param
+ (
+ [Parameter(Mandatory = $true)]
+ [String]$Path
+ )
+ $size = 0
+ Get-ChildItem $Path -Recurse -File | ForEach-Object {
+ $size += $_.Length
+ }
+ return $size
+}
\ No newline at end of file
diff --git a/Src/Public/Get-SystemPackages.ps1 b/Src/Public/Get-SystemPackages.ps1
new file mode 100644
index 0000000..5b6db1b
--- /dev/null
+++ b/Src/Public/Get-SystemPackages.ps1
@@ -0,0 +1,23 @@
+Function Get-SystemPackages {
+
+ $RegKeyPath = "HKLM:\WIM_HKLM_SOFTWARE\Microsoft\Windows\CurrentVersion\Appx\AppxAllUserStore\InboxApplications"
+
+ RegHives -Load
+
+ If (!(Test-Path -Path $RegKeyPath)) {
+ return @()
+ }
+
+ $InboxAppsPackages = Get-ChildItem -Path $RegKeyPath -Name | ForEach-Object -Process {
+ $DisplayName = $PSItem.Split('_')[0]; $PackageName = $PSItem
+ If ($DisplayName -like '1527c705-839a-4832-9118-54d4Bd6a0c89') { $DisplayName = 'Microsoft.Windows.FilePicker' }
+ If ($DisplayName -like 'c5e2524a-ea46-4f67-841f-6a9465d9d515') { $DisplayName = 'Microsoft.Windows.FileExplorer' }
+ If ($DisplayName -like 'E2A4F912-2574-4A75-9BB0-0D023378592B') { $DisplayName = 'Microsoft.Windows.AppResolverUX' }
+ If ($DisplayName -like 'F46D4000-FD22-4DB4-AC8E-4E1DDDE828FE') { $DisplayName = 'Microsoft.Windows.AddSuggestedFoldersToLibarayDialog' }
+ [PSCustomObject]@{ DisplayName = $DisplayName; PackageName = $PackageName }
+ } | Sort-Object -Property DisplayName
+
+ RegHives -Unload
+
+ return $InboxAppsPackages
+}
\ No newline at end of file
diff --git a/Src/Public/Import-Registry.ps1 b/Src/Public/Import-Registry.ps1
new file mode 100644
index 0000000..9ca0614
--- /dev/null
+++ b/Src/Public/Import-Registry.ps1
@@ -0,0 +1,81 @@
+Function Import-Registry
+{
+ [CmdletBinding()]
+ Param (
+ [String]$Path,
+ [Parameter(Mandatory=$false)]
+ [switch]$RegistryLoaded = $false
+ )
+
+ $REGContentHandler = {
+ param(
+ [string]$Content
+ )
+ $Content = $Content -replace 'HKEY_CLASSES_ROOT', 'HKEY_LOCAL_MACHINE\WIM_HKLM_SOFTWARE\Classes'
+ $Content = $Content -replace 'HKEY_LOCAL_MACHINE\\SOFTWARE', 'HKEY_LOCAL_MACHINE\WIM_HKLM_SOFTWARE'
+ $Content = $Content -replace 'HKEY_LOCAL_MACHINE\\SYSTEM', 'HKEY_LOCAL_MACHINE\WIM_HKLM_SYSTEM'
+ $Content = $Content -replace 'HKEY_CURRENT_USER', 'HKEY_LOCAL_MACHINE\WIM_HKCU'
+ $Content = $Content -replace 'HKEY_USERS\\.DEFAULT', 'HKEY_LOCAL_MACHINE\WIM_HKU_DEFAULT'
+ $Content = $Content -replace 'HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet', 'HKEY_LOCAL_MACHINE\WIM_HKLM_SYSTEM\ControlSet001'
+ return $Content
+ }
+
+ If(!$RegistryLoaded) {
+ RegHives -Load
+ }
+
+
+ If ((Get-Item $Path) -is [System.IO.DirectoryInfo]){
+ Get-ChildItem -Path $Path -Filter *.Offline | Purge
+ Get-ChildItem -Path $Path -Filter *.reg | ForEach-Object -Process {
+ $REGContent = Get-Content -Path $PSItem.FullName -Raw
+ $REGContent = $REGContentHandler.Invoke($REGContent)
+ $REGContent | Set-Content -Path $PSItem.FullName.Replace($PSItem.Extension, '.Offline') -Encoding Unicode -Force
+ }
+ If (Get-ChildItem -Path $Path -Filter *.Offline)
+ {
+ Get-ChildItem -Path $Path -Filter *.Offline | ForEach-Object -Process {
+ Try
+ {
+ Log ($OptimizeData.ImportingRegistryTemplate -f $PSItem.Name.Replace($PSItem.Extension, '.reg'))
+ $RET = StartExe $REGEDIT -Arguments ('/S "{0}"' -f $PSItem.FullName)
+ If ($RET -ne 0) { Throw }
+ }
+ Catch
+ {
+ Log ($OptimizeData.FailedImportingRegistryTemplate -f $PSItem.Name.Replace($PSItem.Extension, '.reg')) -Type Error
+ }
+ Finally
+ {
+ Purge $PSItem.FullName; Start-Sleep 2
+ }
+ }
+ }
+ } Else {
+ $RegFile = Get-Item $Path
+ $REGContent = Get-Content -Path $RegFile.FullName -Raw
+ $REGContent = $REGContentHandler.Invoke($REGContent)
+ $REGContent | Set-Content -Path $RegFile.FullName.Replace($RegFile.Extension, '.Offline') -Encoding Unicode -Force
+
+ $ProcessedItem = Get-Item $RegFile.FullName.Replace($RegFile.Extension, '.Offline')
+ Try
+ {
+ Log ($OptimizeData.ImportingRegistryTemplate -f $ProcessedItem.Name.Replace($ProcessedItem.Extension, '.reg'))
+ $RET = StartExe $REGEDIT -Arguments ('/S "{0}"' -f $ProcessedItem.FullName)
+ If ($RET -ne 0) { Throw }
+ }
+ Catch
+ {
+ Log ($OptimizeData.FailedImportingRegistryTemplate -f $ProcessedItem.Name.Replace($ProcessedItem.Extension, '.reg')) -Type Error
+ }
+ Finally
+ {
+ Purge $ProcessedItem.FullName; Start-Sleep 2
+ }
+ }
+
+ If(!$RegistryLoaded) {
+ RegHives -Unload
+ }
+
+}
\ No newline at end of file
diff --git a/Src/Public/Invoke-Cleanup.ps1 b/Src/Public/Invoke-Cleanup.ps1
index 674a9ec..0f35e8c 100644
--- a/Src/Public/Invoke-Cleanup.ps1
+++ b/Src/Public/Invoke-Cleanup.ps1
@@ -15,5 +15,5 @@ Function Invoke-Cleanup
}
@((GetPath -Path $MountPath -Child "Windows\WinSxS\Temp\PendingDeletes\*"), (GetPath -Path $MountPath -Child "Windows\WinSxS\Temp\TransformerRollbackData\*"), (GetPath -Path $MountPath -Child "Windows\WinSxS\ManifestCache\*.bin")) | Purge -Force -ErrorAction Ignore
- @((GetPath -Path $MountPath -Child PerfLogs), (GetPath -Path $MountPath -Child "Windows\INF\*.log"), (GetPath -Path $MountPath -Child "Windows\CbsTemp\*"), (GetPath -Path $MountPath -Child PerfLogs), ("$MountPath\" + '$Recycle.Bin')) | Purge -ErrorAction Ignore
+ @((GetPath -Path $MountPath -Child PerfLogs), (GetPath -Path $MountPath -Child "Windows\INF\*.log"), (GetPath -Path $MountPath -Child "Windows\CbsTemp\*"), ("$MountPath\" + '$Recycle.Bin')) | Purge -ErrorAction Ignore
}
\ No newline at end of file
diff --git a/Src/Public/New-ISOMedia.ps1 b/Src/Public/New-ISOMedia.ps1
index e486efe..0476930 100644
--- a/Src/Public/New-ISOMedia.ps1
+++ b/Src/Public/New-ISOMedia.ps1
@@ -7,11 +7,11 @@ Function New-ISOMedia
[ValidateSet('Prompt', 'No-Prompt')]
[String]$BootType
)
-
- Begin
- {
+ Begin {
$ISOMedia = Import-DataFile -ISOMedia -ErrorAction:$ErrorActionPreference
$InstallInfo = Import-DataFile Install -ErrorAction:$ErrorActionPreference
+ $ISOFile = GetPath -Path $WorkFolder -Child ($($InstallInfo.Edition).Replace(' ', '') + "_$($InstallInfo.Build).iso")
+
$BootFile = Switch ($BootType)
{
'Prompt' { 'efisys.bin'; Break }
@@ -19,88 +19,82 @@ Function New-ISOMedia
}
If ($PSVersionTable.PSVersion.Major -gt 5 -and !(Test-Path -Path (GetPath -Path $ISOMedia.FullName -Child 'boot\etfsboot.com'))) { Log "Missing the required etfsboot.com bootfile for ISO creation." -Type Error; Start-Sleep 3; Break }
If (!(Test-Path -Path (GetPath -Path $ISOMedia.FullName -Child "efi\Microsoft\boot\$($BootFile)"))) { Log ('Missing the required {0} bootfile for ISO creation.' -f $BootFile) -Type Error; Start-Sleep 3; Break }
- If ($PSVersionTable.PSVersion.Major -lt 6)
+ If (!('ISOWriter' -as [Type]))
{
- $CompilerParams = New-Object -TypeName CodeDom.Compiler.CompilerParameters -Property @{ CompilerOptions = '/unsafe'; WarningLevel = 4; TreatWarningsAsErrors = $true } -ErrorAction:$ErrorActionPreference
- If (!('ISOWriter' -as [Type]))
- {
- Add-Type @'
+ Add-Type -TypeDefinition @'
using System;
using System.IO;
+using System.Runtime.InteropServices;
using System.Runtime.InteropServices.ComTypes;
public class ISOWriter
{
- public unsafe static void Create(string Path, object Stream, int BlockSize, int TotalBlocks)
+ [DllImport ("shlwapi.dll", CharSet = CharSet.Unicode, ExactSpelling = true, PreserveSig = false, EntryPoint = "SHCreateStreamOnFileEx")]
+ internal static extern void SHCreateStreamOnFileEx (String FileName, UInt32 Mode, UInt32 Attributes, Boolean Create, IStream StreamNull, out IStream Stream);
+
+ public static void Create (String FilePath, ref Object ImageStream, Int32 BlockSize, Int32 TotalBlocks)
{
- int BytesRead = 0;
- byte[] Buffer = new byte[BlockSize];
- int* Pointer = &BytesRead;
- var OpenFile = System.IO.File.OpenWrite(Path);
- var IStream = Stream as System.Runtime.InteropServices.ComTypes.IStream;
- if (OpenFile != null)
+ IStream ResultStream = (IStream) ImageStream, ImageFile;
+ SHCreateStreamOnFileEx (FilePath, 0x1001, 0x80, true, null, out ImageFile);
+ Int32 Data = TotalBlocks > 1024 ? 1024 : 1;
+ Int32 Pointer = TotalBlocks % Data;
+ Int32 SizeBytes = BlockSize * Data;
+ Int32 Buffer = (TotalBlocks - Pointer) / Data;
+ if (Pointer > 0)
+ ResultStream.CopyTo (ImageFile, Pointer * SizeBytes, IntPtr.Zero, IntPtr.Zero);
+ while (Buffer-- > 0)
{
- while (TotalBlocks-- > 0)
- {
- IStream.Read(Buffer, BlockSize, (IntPtr)Pointer);
- OpenFile.Write(Buffer, 0, BytesRead);
- }
- OpenFile.Flush();
- OpenFile.Close();
+ ResultStream.CopyTo (ImageFile, SizeBytes, IntPtr.Zero, IntPtr.Zero);
}
+ ImageFile.Commit (0);
}
}
-'@ -CompilerParameters $CompilerParams
+'@
+ }
+ $BootOptionsDetail = @(
+ @{
+ File = (Get-ChildItem -Path "$($ISOMedia.FullName)\boot\etfsboot.com" | Select-Object -ExpandProperty FullName)
+ PlatformId = 0
+ },
+ @{
+ File = (Get-ChildItem -Path "$($ISOMedia.FullName)\efi\Microsoft\boot" -Filter $BootFile | Select-Object -ExpandProperty FullName)
+ PlatformId = 0xEF
}
- $FileSystem = @{ UDF = 4 }; $PlatformId = @{ EFI = 0xEF }
+ )
+ $BootOptions = @()
+ Foreach($BootOptionDetail in $BootOptionsDetail)
+ {
($BootStream = New-Object -ComObject ADODB.Stream -Property @{ Type = 1 } -ErrorAction:$ErrorActionPreference).Open()
- $BootStream.LoadFromFile((Get-ChildItem -Path "$($ISOMedia.FullName)\efi\Microsoft\boot" -Filter $BootFile | Select-Object -ExpandProperty FullName))
- ($BootOptions = New-Object -ComObject IMAPI2FS.BootOptions -Property @{ PlatformId = $PlatformId.EFI } -ErrorAction:$ErrorActionPreference).AssignBootImage($BootStream)
- ($FSImage = New-Object -ComObject IMAPI2FS.MsftFileSystemImage -Property @{ FileSystemsToCreate = $FileSystem.UDF; VolumeName = $InstallInfo.Name; WorkingDirectory = $WorkFolder } -ErrorAction:$ErrorActionPreference).ChooseImageDefaultsForMediaType(13)
+ $BootStream.LoadFromFile($BootOptionDetail.File)
+ $BootOption = New-Object -ComObject IMAPI2FS.BootOptions -Property @{ PlatformId = $BootOptionDetail.PlatformId; Manufacturer = 'Microsoft'; Emulation = 0 } -ErrorAction:$ErrorActionPreference
+ $BootOption.AssignBootImage($BootStream.psobject.BaseObject)
+ $BootOptions += $BootOption.psobject.BaseObject
}
+ $FileSystem = @{ UDF = 4 };
+ $FSImage = New-Object -ComObject IMAPI2FS.MsftFileSystemImage -Property @{ FileSystemsToCreate = $FileSystem.UDF; UDFRevision = 0x102; FreeMediaBlocks = 0; VolumeName = $InstallInfo.Name; WorkingDirectory = $WorkFolder } -ErrorAction:$ErrorActionPreference
}
Process
{
- If ($PSVersionTable.PSVersion.Major -lt 6)
- {
- ForEach ($Item In Get-ChildItem -Path $ISOMedia.FullName -Force)
- {
- If ($Item -isnot [IO.FileInfo] -and $Item -isnot [IO.DirectoryInfo]) { $Item = Get-Item -Path $Item -ErrorAction:$ErrorActionPreference }
- If ($Item) { $FSImage.Root.AddTree($Item.FullName, $true) }
- }
- }
+ $FSImage.Root.AddTree($ISOMedia.FullName, $false)
}
End
{
- If ($PSVersionTable.PSVersion.Major -lt 6)
+ $FSImage.BootImageOptionsArray = $BootOptions
+ $WriteISO = $FSImage.CreateResultImage()
+ $ISOFile = New-Item -Path $WorkFolder -Name ($($InstallInfo.Edition).Replace(' ', '') + "_$($InstallInfo.Build).iso") -ItemType File -Force -ErrorAction:$ErrorActionPreference
+ If ($ISOFile.Exists)
{
- $FSImage.BootImageOptions = $BootOptions
- $WriteISO = $FSImage.CreateResultImage()
- $ISOFile = New-Item -Path $WorkFolder -Name ($($InstallInfo.Edition).Replace(' ', '') + "_$($InstallInfo.Build).iso") -ItemType File -Force -ErrorAction:$ErrorActionPreference
- If ($ISOFile.Exists)
- {
- [ISOWriter]::Create($ISOFile.FullName, $WriteISO.ImageStream, $WriteISO.BlockSize, $WriteISO.TotalBlocks)
- $ISOFile.Refresh()
- If (($WriteISO.BlockSize * $WriteISO.TotalBlocks) -eq $ISOFile.Length) { $ISOFile.FullName }
- }
- While ([Runtime.Interopservices.Marshal]::ReleaseComObject($BootStream) -gt 0) { }
- While ([Runtime.Interopservices.Marshal]::ReleaseComObject($BootOptions) -gt 0) { }
- While ([Runtime.Interopservices.Marshal]::ReleaseComObject($FSImage) -gt 0) { }
- While ([Runtime.Interopservices.Marshal]::ReleaseComObject($WriteISO) -gt 0) { }
- [GC]::Collect()
- [GC]::WaitForPendingFinalizers()
+ [ISOWriter]::Create($ISOFile.FullName, [ref]$WriteISO.ImageStream, $WriteISO.BlockSize, $WriteISO.TotalBlocks)
+ $ISOFile.Refresh()
+ If (($WriteISO.BlockSize * $WriteISO.TotalBlocks) -eq $ISOFile.Length) { $ISOFile.FullName }
}
- Else
- {
- If ($OSCDIMG -and (Test-Path -Path $OSCDIMG))
- {
- If (!(Test-Path -Path (GetPath -Path $ISOMedia.FullName -Child 'boot\etfsboot.com'))) { Log "Missing the required etfsboot.com bootfile for ISO creation." -Type Error }
- $ISOFile = GetPath -Path $WorkFolder -Child ($($InstallInfo.Edition).Replace(' ', '') + "_$($InstallInfo.Build).iso")
- $BootData = ('2#p0,e,b"{0}"#pEF,e,b"{1}"' -f (Get-ChildItem -Path "$($ISOMedia.FullName)\boot" -Filter etfsboot.com | Select-Object -ExpandProperty FullName), (Get-ChildItem -Path "$($ISOMedia.FullName)\efi\Microsoft\boot" -Filter $BootFile | Select-Object -ExpandProperty FullName))
- $OSCDIMGArgs = @('-bootdata:{0}', '-u2', '-udfver102', '-l"{1}"', '"{2}"', '"{3}"' -f $BootData, $InstallInfo.Name, $ISOMedia.FullName, $ISOFile)
- $RET = StartExe $OSCDIMG -Arguments $OSCDIMGArgs
- If ($RET -eq 0) { $ISOFile }
- }
+ While ([Runtime.Interopservices.Marshal]::ReleaseComObject($BootStream) -gt 0) { }
+ Foreach($BootOption in $BootOptions){
+ While ([Runtime.Interopservices.Marshal]::ReleaseComObject($BootOption) -gt 0) { }
}
+ While ([Runtime.Interopservices.Marshal]::ReleaseComObject($FSImage) -gt 0) { }
+ While ([Runtime.Interopservices.Marshal]::ReleaseComObject($WriteISO) -gt 0) { }
+ [GC]::Collect()
+ [GC]::WaitForPendingFinalizers()
}
-}
\ No newline at end of file
+}
diff --git a/Src/Public/Set-RegistryProperties.ps1 b/Src/Public/Set-RegistryProperties.ps1
index d3ecdd6..e5dcd35 100644
--- a/Src/Public/Set-RegistryProperties.ps1
+++ b/Src/Public/Set-RegistryProperties.ps1
@@ -50,6 +50,7 @@ Function Set-RegistryProperties
RegKey -Path "HKLM:\WIM_HKLM_SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\DataCollection" -Name "AllowTelemetry" -Value $TelemetryLevel -Type DWord
RegKey -Path "HKLM:\WIM_HKLM_SOFTWARE\Policies\Microsoft\Windows\DataCollection" -Name "AllowTelemetry" -Value $TelemetryLevel -Type DWord
RegKey -Path "HKLM:\WIM_HKLM_SOFTWARE\Policies\Microsoft\Windows\DataCollection" -Name "DoNotShowFeedbackNotifications" -Value 1 -Type DWord
+ RegKey -Path "HKLM:\WIM_HKLM_SOFTWARE\Policies\Microsoft\Windows\DataCollection" -Name "LimitEnhancedDiagnosticDataWindowsAnalytics" -Value 0 -Type DWord
RegKey -Path "HKLM:\WIM_HKCU\Software\Policies\Microsoft\Windows\CloudContent" -Name "DisableTailoredExperiencesWithDiagnosticData" -Value 1 -Type DWord
RegKey -Path "HKLM:\WIM_HKLM_SOFTWARE\Policies\Microsoft\Windows\AppCompat" -Name "AITEnable" -Value 0 -Type DWord
RegKey -Path "HKLM:\WIM_HKLM_SOFTWARE\Policies\Microsoft\Windows\AppCompat" -Name "DisableInventory" -Value 1 -Type DWord
@@ -60,14 +61,16 @@ Function Set-RegistryProperties
RegKey -Path "HKLM:\WIM_HKCU\Software\Policies\Microsoft\Messenger\Client" -Name "CEIP" -Value 2 -Type DWord
RegKey -Path "HKLM:\WIM_HKLM_SOFTWARE\Policies\Microsoft\AppV\CEIP" -Name "CEIPEnable" -Value 0 -Type DWord
RegKey -Path "HKLM:\WIM_HKLM_SOFTWARE\Policies\Microsoft\SQMClient\Windows" -Name "CEIPEnable" -Value 0 -Type DWord
- RegKey -Path "HKLM:\WIM_HKLM_SOFTWARE\Policies\Microsoft\Internet Explorer\SQM" -Name "DisableCustomerImprovementProgram" -Value 0 -Type DWord
+ RegKey -Path "HKLM:\WIM_HKLM_SOFTWARE\Policies\Microsoft\Internet Explorer\SQM" -Name "DisableCustomerImprovementProgram" -Value 1 -Type DWord
RegKey -Path "HKLM:\WIM_HKLM_SOFTWARE\Policies\Microsoft\Windows\TabletPC" -Name "PreventHandwritingDataSharing" -Value 1 -Type DWord
RegKey -Path "HKLM:\WIM_HKLM_SOFTWARE\Policies\Microsoft\Windows NT\CurrentVersion\Software Protection Platform" -Name "NoGenTicket" -Value 1 -Type DWord
RegKey -Path "HKLM:\WIM_HKLM_SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\TextInput" -Name "AllowLinguisticDataCollection" -Value 0 -Type DWord
RegKey -Path "HKLM:\WIM_HKCU\Software\Microsoft\Windows\CurrentVersion\Privacy" -Name "TailoredExperiencesWithDiagnosticDataEnabled" -Value 0 -Type DWord
RegKey -Path "HKLM:\WIM_HKLM_SOFTWARE\Microsoft\PolicyManager\default\System\AllowExperimentation" -Name "value" -Value 0 -Type DWord
RegKey -Path "HKLM:\WIM_HKCU\Control Panel\International\User Profile" -Name "HttpAcceptLanguageOptOut" -Value 1 -Type DWord
- RegKey -Path "HKLM:\WIM_HKLM_SOFTWARE\Policies\Microsoft\Windows\DeliveryOptimization" -Name "DODownloadMode" -Value 100 -Type DWord
+ If($DynamicParams.DisableDeliveryOptimization){
+ RegKey -Path "HKLM:\WIM_HKLM_SOFTWARE\Policies\Microsoft\Windows\DeliveryOptimization" -Name "DODownloadMode" -Value 100 -Type DWord
+ }
RegKey -Path "HKLM:\WIM_HKLM_SOFTWARE\Policies\Microsoft\WindowsInkWorkspace" -Name "AllowWindowsInkWorkspace" -Value 0 -Type DWord
RegKey -Path "HKLM:\WIM_HKLM_SOFTWARE\Policies\Microsoft\WindowsInkWorkspace" -Name "AllowSuggestedAppsInWindowsInkWorkspace" -Value 0 -Type DWord
RegKey -Path "HKLM:\WIM_HKCU\Software\Microsoft\Input\TIPC" -Name "Enabled" -Value 0 -Type DWord
@@ -75,7 +78,7 @@ Function Set-RegistryProperties
RegKey -Path "HKLM:\WIM_HKCU\Software\Microsoft\Windows\CurrentVersion\AdvertisingInfo" -Name "Enabled" -Value 0 -Type DWord
RegKey -Path "HKLM:\WIM_HKLM_SOFTWARE\Microsoft\Windows\Windows Error Reporting" -Name "Disabled" -Value 1 -Type DWord
- If (!$DynamicParams.LTSC -and !$DynamicParams.MicrosoftEdge -and !$DynamicParams.MicrosoftEdgeChromium)
+ If (!$DynamicParams.LTSC -and !$DynamicParams.MicrosoftEdge -and !$DynamicParams.MicrosoftEdgeChromium -and $InstallInfo.Build -le '19044')
{
RegKey -Path "HKLM:\WIM_HKLM_SOFTWARE\Policies\Microsoft\MicrosoftEdge\BooksLibrary" -Name "EnableExtendedBooksTelemetry" -Value 0 -Type DWord
RegKey -Path "HKLM:\WIM_HKLM_SOFTWARE\WOW6432Node\Policies\Microsoft\MicrosoftEdge\BooksLibrary" -Name "EnableExtendedBooksTelemetry" -Value 0 -Type DWord
@@ -90,7 +93,7 @@ Function Set-RegistryProperties
RegKey -Path "HKLM:\WIM_HKLM_SOFTWARE\Policies\Microsoft\Windows\System" -Name "PublishUserActivities" -Value 0 -Type DWord
RegKey -Path "HKLM:\WIM_HKLM_SOFTWARE\Policies\Microsoft\Windows\System" -Name "UploadUserActivities" -Value 0 -Type DWord
- If (!$DynamicParams.LTSC -and !$DynamicParams.MicrosoftEdge -and !$DynamicParams.MicrosoftEdgeChromium)
+ If (!$DynamicParams.LTSC -and !$DynamicParams.MicrosoftEdge -and !$DynamicParams.MicrosoftEdgeChromium -and $InstallInfo.Build -le '19044')
{
RegKey -Path "HKLM:\WIM_HKLM_SOFTWARE\Policies\Microsoft\MicrosoftEdge\Main" -Name "DoNotTrack" -Value 1 -Type DWord
RegKey -Path "HKLM:\WIM_HKLM_SOFTWARE\WOW6432Node\Policies\Microsoft\MicrosoftEdge\Main" -Name "DoNotTrack" -Value 1 -Type DWord
@@ -165,38 +168,51 @@ Function Set-RegistryProperties
RegKey -Path "HKLM:\WIM_HKCU\Software\Microsoft\Windows\CurrentVersion\UserProfileEngagement" -Name "ScoobeSystemSettingEnabled" -Value 0 -Type DWord
}
- $RegistryData.EnableSearchIcon | Out-File -FilePath $RegistryLog -Encoding UTF8 -Append -Force
- RegKey -Path "HKLM:\WIM_HKCU\Software\Microsoft\Windows\CurrentVersion\Search" -Name "SearchboxTaskbarMode" -Value 1 -Type DWord
+ If ($InstallInfo.Build -le '19044'){
+ $RegistryData.EnableSearchIcon | Out-File -FilePath $RegistryLog -Encoding UTF8 -Append -Force
+ RegKey -Path "HKLM:\WIM_HKCU\Software\Microsoft\Windows\CurrentVersion\Search" -Name "SearchboxTaskbarMode" -Value $(If ($DynamicParams.RemovedWindowsSearchPackage) {0} Else {1}) -Type DWord
+ }
$RegistryData.EnableDriveLetterBeforeDriveName | Out-File -FilePath $RegistryLog -Encoding UTF8 -Append -Force
RegKey -Path "HKLM:\WIM_HKLM_SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer" -Name "ShowDriveLettersFirst" -Value 4 -Type DWord
- $RegistryData.EnableOLEDTaskbar | Out-File -FilePath $RegistryLog -Encoding UTF8 -Append -Force
- RegKey -Path "HKLM:\WIM_HKLM_SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\Advanced" -Name "UseOLEDTaskbarTransparency" -Value 1 -Type DWord
- RegKey -Path "HKLM:\WIM_HKLM_SOFTWARE\Microsoft\Windows\Dwm" -Name "ForceEffectMode" -Value 1 -Type DWord
- RegKey -Path "HKLM:\WIM_HKCU\Software\Microsoft\Windows\CurrentVersion\Themes\Personalize" -Name "EnableTransparency" -Value 1 -Type DWord
+ If ($InstallInfo.Build -le '19044'){
+ $RegistryData.EnableOLEDTaskbar | Out-File -FilePath $RegistryLog -Encoding UTF8 -Append -Force
+ RegKey -Path "HKLM:\WIM_HKLM_SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\Advanced" -Name "UseOLEDTaskbarTransparency" -Value 1 -Type DWord
+ RegKey -Path "HKLM:\WIM_HKLM_SOFTWARE\Microsoft\Windows\Dwm" -Name "ForceEffectMode" -Value 1 -Type DWord
+ RegKey -Path "HKLM:\WIM_HKCU\Software\Microsoft\Windows\CurrentVersion\Themes\Personalize" -Name "EnableTransparency" -Value 1 -Type DWord
+ }
$RegistryData.EnableLaunchToThisPC | Out-File -FilePath $RegistryLog -Encoding UTF8 -Append -Force
RegKey -Path "HKLM:\WIM_HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced" -Name "LaunchTo" -Value 1 -Type DWord
+ RegKey -Path "HKLM:\WIM_HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer" -Name "ShowSyncProviderNotifications" -Value 0 -Type DWord
+ If ($InstallInfo.Build -ge '22500'){
+ RegKey -Path "HKLM:\WIM_HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer" -Name "ShowCloudFilesInQuickAccess" -Value 0 -Type DWord
+ }
RegKey -Path "HKLM:\WIM_HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer" -Name "ShowRecent" -Value 0 -Type DWord
RegKey -Path "HKLM:\WIM_HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer" -Name "ShowFrequent" -Value 0 -Type DWord
$RegistryData.DisableJPEGQualityReduction | Out-File -FilePath $RegistryLog -Encoding UTF8 -Append -Force
- RegKey -Path "HKLM:\WIM_HKCU\Control Panel\Desktop" -Name "JPEGImportQuality" -Value 100 -Type DWord
+ RegKey -Path "HKLM:\WIM_HKCU\Control Panel\Desktop" -Name "JPEGImportQuality" -Value 90 -Type DWord
- If ($InstallInfo.Build -ge '18362')
+ If ($InstallInfo.Build -ge '18362' -and $InstallInfo.Build -le '19044')
{
$RegistryData.DisableAcrylicBlur | Out-File -FilePath $RegistryLog -Encoding UTF8 -Append -Force
RegKey -Path "HKLM:\WIM_HKLM_SOFTWARE\Policies\Microsoft\Windows\System" -Name "DisableAcrylicBackgroundOnLogon" -Value 1 -Type DWord
}
+ If ($InstallInfo.Build -ge '22000') {
+ $RegistryData.EnablePrintScreenKeyForSnipping | Out-File -FilePath $RegistryLog -Encoding UTF8 -Append -Force
+ RegKey -Path "HKLM:\WIM_HKCU\Control Panel\Keyboard" -Name "PrintScreenKeyForSnippingEnabled" -Value 1 -Type DWord
+ }
+
$RegistryData.DisableShortcutText | Out-File -FilePath $RegistryLog -Encoding UTF8 -Append -Force
RegKey -Path "HKLM:\WIM_HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer" -Name "link" -Value (0, 0, 0, 0) -Type Binary
$RegistryData.EnableCMDWinXMenu | Out-File -FilePath $RegistryLog -Encoding UTF8 -Append -Force
RegKey -Path "HKLM:\WIM_HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced" -Name "DontUsePowerShellOnWinX" -Value 1 -Type DWord
- If (!$DynamicParams.LTSC -and !$DynamicParams.MicrosoftEdge -and !$DynamicParams.MicrosoftEdgeChromium)
+ If (!$DynamicParams.LTSC -and !$DynamicParams.MicrosoftEdge -and !$DynamicParams.MicrosoftEdgeChromium -and $InstallInfo.Build -le '19044')
{
$RegistryData.DisableEdgeShortcutPrelaunch | Out-File -FilePath $RegistryLog -Encoding UTF8 -Append -Force
RegKey -Path "HKLM:\WIM_HKLM_SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer" -Name "DisableEdgeDesktopShortcutCreation" -Value 1 -Type DWord
@@ -207,11 +223,26 @@ Function Set-RegistryProperties
RegKey -Path "HKLM:\WIM_HKLM_SOFTWARE\Policies\Microsoft\MicrosoftEdge\TabPreloader" -Name "PreventTabPreloading" -Value 1 -Type DWord
RegKey -Path "HKLM:\WIM_HKLM_SOFTWARE\WOW6432Node\Policies\Microsoft\MicrosoftEdge\TabPreloader" -Name "PreventTabPreloading" -Value 1 -Type DWord
}
+
+ If ((($InstallInfo.Build -eq '19041' -and (Get-ItemPropertyValue -Path "HKLM:\WIM_HKLM_SOFTWARE\Microsoft\Windows NT\CurrentVersion" -Name UBR -ErrorAction Ignore) -ge 1023) -or $InstallInfo.Build -gt '19041') -and !$DynamicParams.MicrosoftEdgeChromium)
+ {
- $RegistryData.DisablePinnedIcons | Out-File -FilePath $RegistryLog -Encoding UTF8 -Append -Force
- RegKey -Path "HKLM:\WIM_HKCU\Software\Policies\Microsoft\Windows\Explorer" -Name "NoPinningStoreToTaskbar" -Value 1 -Type DWord
- RegKey -Path "HKLM:\WIM_HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\Taskband\AuxilliaryPins" -Name "MailPin" -Value 2 -Type DWord
- RegKey -Path "HKLM:\WIM_HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced\People" -Name "PeopleBand" -Value 0 -Type DWord
+ $RegistryData.EnableCombineSmallIcons | Out-File -FilePath $RegistryLog -Encoding UTF8 -Append -Force
+ RegKey -Path "HKLM:\WIM_HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced" -Name "TaskbarGlomLevel" -Value 0 -Type DWord
+ RegKey -Path "HKLM:\WIM_HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced" -Name "TaskbarSmallIcons" -Value 1 -Type DWord
+
+ $RegistryData.EnableClassicPersonalizationPanel | Out-File -FilePath $RegistryLog -Encoding UTF8 -Append -Force
+ RegKey -Path "HKLM:\WIM_HKLM_SOFTWARE\Classes\CLSID\{580722FF-16A7-44C1-BF74-7E1ACD00F4F9}" -Name "(default)" -Value "Personalization (Classic)" -Type String
+ RegKey -Path "HKLM:\WIM_HKLM_SOFTWARE\Classes\CLSID\{580722FF-16A7-44C1-BF74-7E1ACD00F4F9}" -Name "InfoTip" -Value '@%SystemRoot%\\System32\\themecpl.dll,-2#immutable1' -Type ExpandString
+ RegKey -Path "HKLM:\WIM_HKLM_SOFTWARE\Classes\CLSID\{580722FF-16A7-44C1-BF74-7E1ACD00F4F9}" -Name "System.ApplicationName" -Value "Microsoft.Personalization" -Type String
+ RegKey -Path "HKLM:\WIM_HKLM_SOFTWARE\Classes\CLSID\{580722FF-16A7-44C1-BF74-7E1ACD00F4F9}" -Name "System.ControlPanel.Category" -Value 1 -Type DWord
+ RegKey -Path "HKLM:\WIM_HKLM_SOFTWARE\Classes\CLSID\{580722FF-16A7-44C1-BF74-7E1ACD00F4F9}" -Name "System.Software.TasksFileUrl" -Value "Internal" -Type String
+ RegKey -Path "HKLM:\WIM_HKLM_SOFTWARE\Classes\CLSID\{580722FF-16A7-44C1-BF74-7E1ACD00F4F9}\DefaultIcon" -Name "(default)" -Value "%SystemRoot%\\System32\\themecpl.dll,-1" -Type String
+ RegKey -Path "HKLM:\WIM_HKLM_SOFTWARE\Classes\CLSID\{580722FF-16A7-44C1-BF74-7E1ACD00F4F9}\shell\Open\Command" -Name "(default)" -Value "explorer.exe shell:::{ED834ED6-4B5A-4bfe-8F11-A626DCB6A921}" -Type String
+ RegKey -Path "HKLM:\WIM_HKLM_SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\ControlPanel\NameSpace\{580722FF-16A7-44C1-BF74-7E1ACD00F4F9}" -Name "(default)" -Value "Personalization" -Type String
+ RegKey -Path "HKLM:\WIM_HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\ControlPanel" -Name "StartupPage" -Value 1 -Type DWord
+ RegKey -Path "HKLM:\WIM_HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\ControlPanel" -Name "AllItemsIconView" -Value 1 -Type DWord
+ }
$RegistryData.ReduceStartMenuDelay | Out-File -FilePath $RegistryLog -Encoding UTF8 -Append -Force
RegKey -Path "HKLM:\WIM_HKCU\Control Panel\Desktop" -Name "MenuShowDelay" -Value 50 -Type String
@@ -224,17 +255,6 @@ Function Set-RegistryProperties
RegKey -Path "HKLM:\WIM_HKLM_SOFTWARE\Policies\Microsoft\Windows\Explorer" -Name "NoUseStoreOpenWith" -Value 1 -Type DWord
RegKey -Path "HKLM:\WIM_HKLM_SOFTWARE\Policies\Microsoft\Windows\Explorer" -Name "NoNewAppAlert" -Value 1 -Type DWord
- $RegistryData.EnableClassicPersonalizationPanel | Out-File -FilePath $RegistryLog -Encoding UTF8 -Append -Force
- RegKey -Path "HKLM:\WIM_HKLM_SOFTWARE\Classes\CLSID\{580722FF-16A7-44C1-BF74-7E1ACD00F4F9}" -Name "(default)" -Value "Personalization (Classic)" -Type String
- RegKey -Path "HKLM:\WIM_HKLM_SOFTWARE\Classes\CLSID\{580722FF-16A7-44C1-BF74-7E1ACD00F4F9}" -Name "InfoTip" -Value '@%SystemRoot%\\System32\\themecpl.dll,-2#immutable1' -Type ExpandString
- RegKey -Path "HKLM:\WIM_HKLM_SOFTWARE\Classes\CLSID\{580722FF-16A7-44C1-BF74-7E1ACD00F4F9}" -Name "System.ApplicationName" -Value "Microsoft.Personalization" -Type String
- RegKey -Path "HKLM:\WIM_HKLM_SOFTWARE\Classes\CLSID\{580722FF-16A7-44C1-BF74-7E1ACD00F4F9}" -Name "System.ControlPanel.Category" -Value 1 -Type DWord
- RegKey -Path "HKLM:\WIM_HKLM_SOFTWARE\Classes\CLSID\{580722FF-16A7-44C1-BF74-7E1ACD00F4F9}" -Name "System.Software.TasksFileUrl" -Value "Internal" -Type String
- RegKey -Path "HKLM:\WIM_HKLM_SOFTWARE\Classes\CLSID\{580722FF-16A7-44C1-BF74-7E1ACD00F4F9}\DefaultIcon" -Name "(default)" -Value "%SystemRoot%\\System32\\themecpl.dll,-1" -Type String
- RegKey -Path "HKLM:\WIM_HKLM_SOFTWARE\Classes\CLSID\{580722FF-16A7-44C1-BF74-7E1ACD00F4F9}\shell\Open\Command" -Name "(default)" -Value "explorer.exe shell:::{ED834ED6-4B5A-4bfe-8F11-A626DCB6A921}" -Type String
- RegKey -Path "HKLM:\WIM_HKLM_SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\ControlPanel\NameSpace\{580722FF-16A7-44C1-BF74-7E1ACD00F4F9}" -Name "(default)" -Value "Personalization" -Type String
- RegKey -Path "HKLM:\WIM_HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\ControlPanel" -Name "StartupPage" -Value 1 -Type DWord
- RegKey -Path "HKLM:\WIM_HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\ControlPanel" -Name "AllItemsIconView" -Value 1 -Type DWord
If ($InstallInfo.Build -ge '17763' -and $InstallInfo.Build -lt '19041')
{
@@ -260,22 +280,7 @@ Function Set-RegistryProperties
@('.3ds', '.3mf', '.dae', '.dxf', '.obj', '.ply', '.stl', '.wrl') | ForEach-Object -Process { Purge -Path "HKLM:\WIM_HKLM_SOFTWARE\Classes\SystemFileAssociations\$($PSItem)\shell\3D Print" }
$RegistryData.RestoreWindowsPhotoViewer | Out-File -FilePath $RegistryLog -Encoding UTF8 -Append -Force
- @('.Bmp', '.Cr2', '.Dib', '.Gif', '.JFIF', '.Jpe', '.Jpeg', '.Jpg', '.Jxr', '.Png', '.Tif', '.Tiff', '.Wdp') | ForEach-Object -Process {
- If ($PSItem -in @('.JFIF', '.Jpeg', '.Gif', '.Png', '.Wdp'))
- {
- RegKey -Path "HKLM:\WIM_HKLM_SOFTWARE\Classes\PhotoViewer.FileAssoc$($PSItem)" -Name "EditFlags" -Value 65536 -Type DWord
- RegKey -Path "HKLM:\WIM_HKLM_SOFTWARE\Classes\PhotoViewer.FileAssoc$($PSItem)" -Name "ImageOptionFlags" -Value 1 -Type DWord
- RegKey -Path "HKLM:\WIM_HKLM_SOFTWARE\Classes\PhotoViewer.FileAssoc$($PSItem)" -Name "FriendlyTypeName" -Value '@%ProgramFiles%\Windows Photo Viewer\PhotoViewer.dll,-3055' -Type ExpandString
- RegKey -Path "HKLM:\WIM_HKLM_SOFTWARE\Classes\PhotoViewer.FileAssoc$($PSItem)\DefaultIcon" -Name "(default)" -Value "%SystemRoot%\System32\imageres.dll,-72" -Type String
- RegKey -Path "HKLM:\WIM_HKLM_SOFTWARE\Classes\PhotoViewer.FileAssoc$($PSItem)\shell\open" -Name "MuiVerb" -Value '@%ProgramFiles%\Windows Photo Viewer\photoviewer.dll,-3043' -Type ExpandString
- RegKey -Path "HKLM:\WIM_HKLM_SOFTWARE\Classes\PhotoViewer.FileAssoc$($PSItem)\shell\open\command" -Name "(default)" -Value '%SystemRoot%\System32\rundll32.exe "%ProgramFiles%\Windows Photo Viewer\PhotoViewer.dll", ImageView_Fullscreen %1' -Type ExpandString
- RegKey -Path "HKLM:\WIM_HKLM_SOFTWARE\Classes\PhotoViewer.FileAssoc$($PSItem)\shell\open\DropTarget" -Name "Clsid" -Value "{FFE2A43C-56B9-4bf5-9A79-CC6D4285608A}" -Type String
- }
- If ($PSItem -in @('.Cr2', '.Tif')) { RegKey -Path "HKLM:\WIM_HKLM_SOFTWARE\Microsoft\Windows Photo Viewer\Capabilities\FileAssociations" -Name $PSItem.ToLower() -Value "PhotoViewer.FileAssoc.Tiff" -Type String }
- ElseIf ($PSItem -in @('.Dib', '.Bmp')) { RegKey -Path "HKLM:\WIM_HKLM_SOFTWARE\Microsoft\Windows Photo Viewer\Capabilities\FileAssociations" -Name $PSItem.ToLower() -Value "PhotoViewer.FileAssoc.Bitmap" -Type String }
- ElseIf ($PSItem -in @('.Jpg', '.Jpe', '.Jpeg')) { RegKey -Path "HKLM:\WIM_HKLM_SOFTWARE\Microsoft\Windows Photo Viewer\Capabilities\FileAssociations" -Name $PSItem.ToLower() -Value "PhotoViewer.FileAssoc.Jpeg" -Type String }
- Else { RegKey -Path "HKLM:\WIM_HKLM_SOFTWARE\Microsoft\Windows Photo Viewer\Capabilities\FileAssociations" -Name $PSItem.ToLower() -Value "PhotoViewer.FileAssoc$($PSItem)" -Type String }
- }
+ Import-Registry -Path (Get-ChildItem -Path $OptimizeOffline.SelectiveRegistry -Filter WindowsPhotoViewer.reg).FullName -RegistryLoaded:$true
$RegistryData.RemoveUserFoldersExplorer | Out-File -FilePath $RegistryLog -Encoding UTF8 -Append -Force
@("HKLM:\WIM_HKLM_SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\MyComputer\NameSpace\{0DB7E03F-FC29-4DC6-9020-FF41B59E513A}", "HKLM:\WIM_HKLM_SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Explorer\MyComputer\NameSpace\{0DB7E03F-FC29-4DC6-9020-FF41B59E513A}",
@@ -318,9 +323,9 @@ Function Set-RegistryProperties
"HKLM:\WIM_HKLM_SOFTWARE\Classes\AllFilesystemObjects\shellex\PropertySheetHandlers\{596AB062-B4D2-4215-9F74-E9109B0A8153}", "HKLM:\WIM_HKLM_SOFTWARE\Classes\CLSID\{450D8FBA-AD25-11D0-98A8-0800361B1103}\shellex\PropertySheetHandlers\{596AB062-B4D2-4215-9F74-E9109B0A8153}",
"HKLM:\WIM_HKLM_SOFTWARE\Classes\Directory\shellex\PropertySheetHandlers\{596AB062-B4D2-4215-9F74-E9109B0A8153}", "HKLM:\WIM_HKLM_SOFTWARE\Classes\Drive\shellex\PropertySheetHandlers\{596AB062-B4D2-4215-9F74-E9109B0A8153}") | Purge
- $RegistryData.EnableRebootRecoveryMyPC | Out-File -FilePath $RegistryLog -Encoding UTF8 -Append -Force
+ <# $RegistryData.EnableRebootRecoveryMyPC | Out-File -FilePath $RegistryLog -Encoding UTF8 -Append -Force
RegKey -Path "HKLM:\WIM_HKLM_SOFTWARE\Classes\CLSID\{20D04FE0-3AEA-1069-A2D8-08002B30309D}\shell\Reboot to Recovery" -Name "Icon" -Value "%SystemRoot%\System32\imageres.dll,-110" -Type String -Force
- RegKey -Path "HKLM:\WIM_HKLM_SOFTWARE\Classes\CLSID\{20D04FE0-3AEA-1069-A2D8-08002B30309D}\shell\Reboot to Recovery\command" -Name "(default)" -Value "shutdown.exe /r /o /f /t 00" -Type String -Force
+ RegKey -Path "HKLM:\WIM_HKLM_SOFTWARE\Classes\CLSID\{20D04FE0-3AEA-1069-A2D8-08002B30309D}\shell\Reboot to Recovery\command" -Name "(default)" -Value "shutdown.exe /r /o /f /t 00" -Type String -Force #>
$RegistryData.EnableLongFilePaths | Out-File -FilePath $RegistryLog -Encoding UTF8 -Append -Force
RegKey -Path "HKLM:\WIM_HKLM_SYSTEM\ControlSet001\Control\FileSystem" -Name "LongPathsEnabled" -Value 1 -Type DWord
@@ -328,6 +333,7 @@ Function Set-RegistryProperties
$RegistryData.EnableStrongCrypto | Out-File -FilePath $RegistryLog -Encoding UTF8 -Append -Force
RegKey -Path "HKLM:\WIM_HKLM_SOFTWARE\Microsoft\.NETFramework\v4.0.30319" -Name "SchUseStrongCrypto" -Value 1 -Type DWord
RegKey -Path "HKLM:\WIM_HKLM_SOFTWARE\WOW6432Node\Microsoft\.NETFramework\v4.0.30319" -Name "SchUseStrongCrypto" -Value 1 -Type DWord
+
}
Catch
{
diff --git a/Src/Public/Test-Requirements.ps1 b/Src/Public/Test-Requirements.ps1
index b43bbb4..01bd054 100644
--- a/Src/Public/Test-Requirements.ps1
+++ b/Src/Public/Test-Requirements.ps1
@@ -3,8 +3,8 @@ Function Test-Requirements
If (!([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)) { Write-Warning ('Elevation is required to process optimizations. Please relaunch {0} as an administrator.' -f $OptimizeOffline.BaseName); Break }
If ($PSVersionTable.PSVersion.Major -lt 5) { Write-Warning ('{0} does not support PowerShell version {1}' -f $OptimizeOffline.BaseName, $PSVersionTable.PSVersion.ToString()); Break }
$OSCaption = (Get-CimInstance -ClassName Win32_OperatingSystem | Select-Object -ExpandProperty Caption)
- $HostEnvironment = @('Microsoft Windows 10', 'Microsoft Windows Server 2016', 'Microsoft Windows Server 2019')
- If ($OSCaption -notlike "$($HostEnvironment[0])*" -and $OSCaption -notlike "$($HostEnvironment[1])*" -and $OSCaption -notlike "$($HostEnvironment[2])*") { Write-Warning ('{0} requires one of the following host environments: {1}.' -f $OptimizeOffline.BaseName, ($HostEnvironment -join ', ')); Break }
+ $HostEnvironment = @('Microsoft Windows', 'Microsoft Windows Server')
+ If ($OSCaption -notlike "$($HostEnvironment[0])*" -and $OSCaption -notlike "$($HostEnvironment[1])*") { Write-Warning ('{0} requires one of the following host environments: {1}.' -f $OptimizeOffline.BaseName, ($HostEnvironment -join ', ')); Break }
If ($Env:PROCESSOR_ARCHITECTURE -ne $ManifestData.ProcessorArchitecture) { Write-Warning ('{0} requires an "{1}" processor architecture.' -f $OptimizeOffline.BaseName, $ManifestData.ProcessorArchitecture); Break }
If (Test-Path -Path HKLM:\SYSTEM\CurrentControlSet\Control\MiniNT) { Write-Warning ('{0} cannot be run in a Preinstallation environment.' -f $OptimizeOffline.BaseName); Break }
If ((Get-UICulture).Name -ne $OptimizeOffline.Culture) { Write-Warning ('{0} is designed for the "{1}" regional culture. Not all optimizations will be available for the "{2}" regional culture.' -f $OptimizeOffline.BaseName, $OptimizeOffline.Culture, (Get-UICulture).Name); Start-Sleep 5 }
diff --git a/Src/Public/Write-Log.ps1 b/Src/Public/Write-Log.ps1
index 00a2ddc..6f4d949 100644
--- a/Src/Public/Write-Log.ps1
+++ b/Src/Public/Write-Log.ps1
@@ -23,7 +23,7 @@ Function Write-Log
$LogMutex = New-Object System.Threading.Mutex($false, "LogMutex")
$Header = @"
***************************************************************************************************
-Running Module : $($OptimizeOffline.BaseName) $($ManifestData.ModuleVersion)
+Running Module : $($OptimizeOffline.BaseName) $($ManifestData.ModuleVersion) $($ManifestData.ModuleForkVersion)
Optimize Start : {0}
Identity Name : $([Security.Principal.WindowsIdentity]::GetCurrent().Name.Split('\')[1])
Computer Name : $Env:COMPUTERNAME
diff --git a/Src/Public/Write-USB.ps1 b/Src/Public/Write-USB.ps1
new file mode 100644
index 0000000..8d2abbc
--- /dev/null
+++ b/Src/Public/Write-USB.ps1
@@ -0,0 +1,158 @@
+
+Function Update_bcd
+{
+ param ($usbpartition)
+ & bcdedit /store "$usbpartition\boot\bcd" /set '{default}' bootmenupolicy Legacy | Out-Null
+ & bcdedit /store "$usbpartition\EFI\Microsoft\boot\bcd" /set '{default}' bootmenupolicy Legacy |Out-Null
+ Set-ItemProperty -Path "$usbpartition\boot\bcd" -Name IsReadOnly -Value $true
+ Set-ItemProperty -Path "$usbpartition\EFI\Microsoft\boot\bcd" -Name IsReadOnly -Value $true
+}
+Function Write-USB {
+
+ [CmdletBinding()]
+
+ Param (
+ [Parameter(
+ Mandatory = $true,
+ HelpMessage = 'full path of the source files to be flashed to the usb device'
+ )]
+ [String]$Source,
+ [Parameter(
+ Mandatory = $true,
+ HelpMessage = 'USB device drive object'
+ )]
+ [PSCustomObject]$USBDrive,
+ [Parameter(
+ Mandatory = $false,
+ HelpMessage = 'USB label'
+ )]
+ [String]$Label = "Windows_Install",
+ [Parameter(
+ Mandatory = $false,
+ HelpMessage = "If usb will support legacy bios booting scheme"
+ )]
+ [Switch]$Legacy = $false,
+ [Parameter(
+ Mandatory = $false,
+ HelpMessage = "Will override the main USB partition FS type to this one"
+ )]
+ [ValidateSet("NTFS", "FAT32")]
+ [String]$ForceFS,
+ [Parameter(
+ Mandatory = $false,
+ HelpMessage = "Will override the main USB partition schema to this one"
+ )]
+ [ValidateSet("MBR", "GPT")]
+ [String]$ForcePartitionSchema
+ )
+
+ Try {
+ If ($USBDrive.Count -eq 0 -or $USBDrive.BusType -ne "USB") {
+ Throw "Could not find USB drive"
+ }
+ $TotalSize = (Get-PathSize -Path $Source)
+ $USBSize = $USBDrive.Size
+ If ($USBSize -lt $TotalSize + 100MB) {
+ Throw "USB disk size is smaller than ISO size"
+ }
+ $PartitionSchema = $(If($ForcePartitionSchema) {$ForcePartitionSchema} Else {"MBR"})
+ $FileSystem = $(If ($ForceFS) {$ForceFS} Else {If($Legacy) {"FAT32"} Else {"NTFS"}})
+@"
+select disk $($USBDrive.DiskNumber)
+clean
+convert $PartitionSchema
+rescan
+exit
+"@ | diskpart | Out-Null
+
+ Stop-Service ShellHWDetection -ErrorAction SilentlyContinue | Out-Null
+
+ If(!$Legacy){
+
+ $bootSize = (Get-PathSize -Path "$Source\bootmgr*")
+ $bootSize += (Get-PathSize -Path "$Source\boot")
+ $bootSize += (Get-PathSize -Path "$Source\efi")
+ $bootSize += (Get-PathSize -Path "$Source\sources\boot.wim")
+
+ If($bootSize -eq 0) {
+ Throw "Boot files total size is 0"
+ }
+
+ $bootSize += 100MB
+
+ If($bootSize -gt $USBSize) {
+ Throw "Boot files total size is greater than usb size"
+ }
+
+ $USBUEFIVolume = $USBDrive |
+ New-Partition -Size $bootSize -AssignDriveLetter |
+ Format-Volume -FileSystem FAT32 -NewFileSystemLabel "BOOT"
+
+ Copy-Item -Path "$Source\bootmgr*" -Destination "$($USBUEFIVolume.DriveLetter):\"
+ Copy-Item -Path "$Source\boot" -Destination "$($USBUEFIVolume.DriveLetter):\boot" -Recurse
+ Copy-Item -Path "$Source\efi" -Destination "$($USBUEFIVolume.DriveLetter):\efi" -Recurse
+ If (!(Test-Path -path "$($USBUEFIVolume.DriveLetter):\sources")) {
+ New-Item "$($USBUEFIVolume.DriveLetter):\sources" -Type Directory | Out-Null
+ }
+ Copy-Item -Path "$Source\sources\boot.wim" -Destination "$($USBUEFIVolume.DriveLetter):\sources"
+
+ Update_bcd $($USBUEFIVolume.DriveLetter+":")
+
+ $USBSize -= $bootSize
+
+ }
+ $NewPartitionParams = @{
+ AssignDriveLetter = $true
+ ErrorAction = "Stop"
+ }
+ If($PartitionSchema -eq "MBR") {
+ $NewPartitionParams.IsActive = $true
+ }
+ If ($FileSystem -eq "FAT32" -and $USBSize -gt 32GB) {
+ $NewPartitionParams.Size = 32GB
+ } Else {
+ $NewPartitionParams.UseMaximumSize = $true
+ }
+ $USBVolume = $USBDrive |
+ New-Partition @NewPartitionParams |
+ Format-Volume -FileSystem $FileSystem -ErrorAction Stop -NewFileSystemLabel $Label
+
+ $CopyItemParams = @{
+ Path = "$Source\*"
+ Destination = "$($USBVolume.DriveLetter):"
+ Recurse = $true
+ Force = $true
+ ErrorAction = "Stop"
+ Exclude = @()
+ }
+
+ If (!$Legacy) {
+ $CopyItemParams.Exclude = $CopyItemParams.Exclude + "boot.wim"
+ }
+
+ If ($FileSystem -eq "FAT32" -and (Test-Path -Path "$Source\sources\install.wim") -and (Get-Item -Path "$Source\sources\install.wim").Length -gt 4GB) {
+ [Void](New-Item -Path "$($USBVolume.DriveLetter):\sources" -Type Directory)
+ [Void](Split-WindowsImage -ImagePath "$Source\sources\install.wim" -SplitImagePath "$($USBVolume.DriveLetter):\sources\install.swm" -FileSize 4090 -LogPath $DISMLog -ScratchDirectory $ScratchFolder -LogLevel 1 -ErrorAction Stop)
+ $CopyItemParams.Exclude = $CopyItemParams.Exclude + "install.wim"
+ }
+ Copy-Item @CopyItemParams
+
+ If(!$Legacy){
+ Update_bcd $($USBVolume.DriveLetter+":")
+ } Else {
+ [Void](& "$Source\boot\bootsect.exe" /nt60 "$($USBVolume.DriveLetter):")
+ }
+ } Catch {
+ Throw $Error[0]
+ } Finally {
+ Start-Service ShellHWDetection -ErrorAction SilentlyContinue | Out-Null
+ If (!$Legacy -and $USBUEFIVolume) {
+@"
+select volume $($USBUEFIVolume.DriveLetter)
+remove letter=$($USBUEFIVolume.DriveLetter)
+rescan
+exit
+"@ | diskpart | Out-Null
+ }
+ }
+}
diff --git a/Src/Public/en-US/Set-RegistryProperties.strings.psd1 b/Src/Public/en-US/Set-RegistryProperties.strings.psd1
index e42e28e..c5aba28 100644
--- a/Src/Public/en-US/Set-RegistryProperties.strings.psd1
+++ b/Src/Public/en-US/Set-RegistryProperties.strings.psd1
@@ -25,6 +25,7 @@ DisableAcrylicBlur = Disabling the Sign-in Screen Acrylic Blur.
DisableShortcutText = Disabling the Trailing Text for Shortcuts.
EnableCMDWinXMenu = Enabling Command Prompt on the Win+X Quick Link Menu.
DisableEdgeShortcutPrelaunch = Disabling Microsoft Edge Desktop Shortcut Creation and Pre-Launching.
+DisableTaskbarInterestsNews = Disabling Interests and News on Taskbar.
DisablePinnedIcons = Disabling Pinned Windows Store, Windows Mail and People Icons.
ReduceStartMenuDelay = Reducing Start Menu Delay.
EnableCombineSmallIcons = Enabling TaskBar Icon Combining with Small Icons.
@@ -44,4 +45,5 @@ RemoveRestorePreviousVersions = Removing Restore Previous Versions from th
EnableRebootRecoveryMyPC = Adding Reboot to Recovery to This PC.
EnableLongFilePaths = Enabling Long File Paths.
EnableStrongCrypto = Enabling Strong Cryptography for .NET Applications.
+EnablePrintScreenKeyForSnipping = Enable Printscreen key to open snipping app
'@
\ No newline at end of file
diff --git a/Start-GUI.bat b/Start-GUI.bat
new file mode 100644
index 0000000..f088d1b
--- /dev/null
+++ b/Start-GUI.bat
@@ -0,0 +1,34 @@
+@echo off
+
+:: BatchGotAdmin
+:-------------------------------------
+REM --> Check for permissions
+ IF "%PROCESSOR_ARCHITECTURE%" EQU "amd64" (
+>nul 2>&1 "%SYSTEMROOT%\SysWOW64\cacls.exe" "%SYSTEMROOT%\SysWOW64\config\system"
+) ELSE (
+>nul 2>&1 "%SYSTEMROOT%\system32\cacls.exe" "%SYSTEMROOT%\system32\config\system"
+)
+
+REM --> If error flag set, we do not have admin.
+if '%errorlevel%' NEQ '0' (
+ echo Requesting administrative privileges...
+ goto UACPrompt
+) else ( goto gotAdmin )
+
+:UACPrompt
+ echo Set UAC = CreateObject^("Shell.Application"^) > "%temp%\getadmin.vbs"
+ set params= %*
+ echo UAC.ShellExecute "cmd.exe", "/c ""%~s0"" %params:"=""%", "", "runas", 1 >> "%temp%\getadmin.vbs"
+
+ "%temp%\getadmin.vbs"
+ del "%temp%\getadmin.vbs"
+ exit /B
+
+:gotAdmin
+ pushd "%CD%"
+ CD /D "%~dp0"
+
+
+start /wait powershell -ExecutionPolicy Bypass -WindowStyle Hidden -File "%~dp0Src\GUI\Start.ps1"
+call "Remove_Failure_no_prompts.cmd"
+pause
\ No newline at end of file
diff --git a/Start-Optimize-BAU-TI.ps1 b/Start-Optimize-BAU-TI.ps1
new file mode 100644
index 0000000..754ea32
--- /dev/null
+++ b/Start-Optimize-BAU-TI.ps1
@@ -0,0 +1,130 @@
+<#
+ .SYNOPSIS
+ Start-Optimize is a configuration call script for the Optimize-Offline module.
+
+ .DESCRIPTION
+ Start-Optimize automatically imports the configuration JSON file into the Optimize-Offline module.
+
+ .EXAMPLE
+ .\Start-Optimize.ps1
+
+ This command will import all values set in the configuration JSON file into the Optimize-Offline module and begin the optimization process.
+
+ .NOTES
+ Start-Optimize requires that the configuration JSON file is present in the root path of the Optimize-Offline module.
+#>
+[CmdletBinding()]
+Param (
+ [Parameter(Mandatory = $false)] [switch]$populateLists,
+ [Parameter(Mandatory = $false)] [switch]$populateTemplates
+)
+
+$Global:Error.Clear()
+
+# Ensure we are running with full administrative permissions via RunAsTI function.
+function RunAsTI ($cmd) { $id='RunAsTI'; $sid=((whoami /user)-split' ')[-1]; $code=@'
+$ti=(whoami /groups)-like"*1-16-16384*"; $DM=[AppDomain]::CurrentDomain."DefineDynamicAss`embly"(1,1)."DefineDynamicMod`ule"(1)
+$D=@(); 0..5|% {$D+=$DM."DefineT`ype"("M$_",1179913,[ValueType])}; $I=[int32];$P=$I.module.gettype("System.Int`Ptr"); $U=[uintptr]
+$D+=$U; 4..6|% {$D+=$D[$_]."MakeB`yRefType"()};$M=$I.module.gettype("System.Runtime.Interop`Services.Mar`shal");$Z=[uintptr]::size
+$S=[string]; $F="kernel","advapi","advapi",($S,$S,$I,$I,$I,$I,$I,$S,$D[7],$D[8]),($U,$S,$I,$I,$D[9]),($U,$S,$I,$I,[byte[]],$I)
+0..2|% {$9=$D[0]."DefinePInvokeMeth`od"(("CreateProcess","RegOpenKeyEx","RegSetValueEx")[$_],$F[$_]+'32',8214,1,$S,$F[$_+3],1,4)}
+$DF=0,($P,$I,$P),($I,$I,$I,$I,$P,$D[1]),($I,$S,$S,$S,$I,$I,$I,$I,$I,$I,$I,$I,[int16],[int16],$P,$P,$P,$P),($D[3],$P),($P,$P,$I,$I)
+1..5|% {$k=$_;$n=1;$AveYo=1; $DF[$_]|% {$9=$D[$k]."DefineFie`ld"('f'+$n++,$_,6)}}; $T=@(); 0..5|% {$T+=$D[$_]."CreateT`ype"()}
+0..5|% {nv "A$_" ([Activator]::CreateInstance($T[$_])) -force}; function F ($1,$2) {$T[0]."GetMeth`od"($1).invoke(0,$2)};
+if (!$ti) { $g=0; "TrustedInstaller","lsass"|% {if (!$g) {net1 start $_ 2>&1 >$null; $g=@(get-process -name $_ -ea 0|% {$_})[0]}}
+ function M($1,$2,$3){$M."GetMeth`od"($1,[type[]]$2).invoke(0,$3)}; $H=@(); $Z,(4*$Z+16)|% {$H+=M "AllocHG`lobal" $I $_};
+ M "WriteInt`Ptr" ($P,$P) ($H[0],$g.Handle); $A1.f1=131072;$A1.f2=$Z;$A1.f3=$H[0];$A2.f1=1;$A2.f2=1;$A2.f3=1;$A2.f4=1;$A2.f6=$A1
+ $A3.f1=10*$Z+32;$A4.f1=$A3;$A4.f2=$H[1]; M "StructureTo`Ptr" ($D[2],$P,[boolean]) (($A2 -as $D[2]),$A4.f2,$false); $w=0x0E080600
+ $out=@($null,"powershell -win 1 -nop -c iex `$env:A",0,0,0,$w,0,$null,($A4 -as $T[4]),($A5 -as $T[5])); F "CreateProcess" $out
+} else { $env:A=''; $PRIV=[uri].module.gettype("System.Diagnostics.Process")."GetMeth`ods"(42) |? {$_.Name -eq "SetPrivilege"}
+ "SeSecurityPrivilege","SeTakeOwnershipPrivilege","SeBackupPrivilege","SeRestorePrivilege" |% {$PRIV.Invoke(0, @("$_",2))}
+ $HKU=[uintptr][uint32]2147483651; $LNK=$HKU; $reg=@($HKU,"S-1-5-18",8,2,($LNK -as $D[9])); F "RegOpenKeyEx" $reg; $LNK=$reg[4]
+ function SYM($1,$2){$b=[Text.Encoding]::Unicode.GetBytes("\Registry\User\$1");@($2,"SymbolicLinkValue",0,6,[byte[]]$b,$b.Length)}
+ if (!$cmd) {$cmd='cmd'}; $r="start `"$id`" /high /w"; F "RegSetValueEx" (SYM $(($key-split'\\')[1]) $LNK)
+ start cmd -args ("/q/x/d/r title $id && $r",$cmd) -wait -win 1; F "RegSetValueEx" (SYM ".Default" $LNK)
+} # lean and mean snippet by AveYo, 2018-2021
+'@; $key="Registry::HKEY_USERS\$sid\Volatile Environment"; $a1="`$id='$id';`$key='$key';";$a2="`$cmd='$($cmd-replace"'","''")';`n"
+sp $key $id $($a1,$a2,$code) -type 7 -force; $arg="$a1 `$env:A=(gi `$key).getvalue(`$id)-join'';rp `$key `$id -force; iex `$env:A"
+start powershell -args "-win 1 -nop -c $arg" -verb runas }
+
+$arguments = @()
+foreach ($param in $PSBoundParameters.GetEnumerator()) {
+ $arguments += "-"+[string]$param.Key+$(If ($param.Value -notin @("True", "False")) {"="+$param.Value} Else {""})
+}
+if ((whoami)-ne"nt authority\system") {RunAsTI "powershell -c . ""$($MyInvocation.MyCommand.Path)"" $arguments; pause"; return}
+
+# Ensure the configuration JSON file exists.
+If (!(Test-Path -Path (Join-Path -Path $PSScriptRoot -ChildPath Configuration.json))) {
+ Write-Warning ('The required configuration JSON file does not exist: "{0}"' -f (Join-Path -Path $PSScriptRoot -ChildPath Configuration.json))
+ Start-Sleep 3
+ Exit
+}
+
+# If the configuration JSON or ordered collection list variables still exists from a previous session, remove them.
+If ((Test-Path -Path Variable:\ContentJSON) -or (Test-Path -Path Variable:\ConfigParams)) {
+ Remove-Variable -Name ContentJSON, ConfigParams -ErrorAction Ignore
+}
+
+# Use a Try/Catch/Finally block in case the configuration JSON file URL formatting is invalid so we can catch it, correct its formatting and continue.
+Try {
+ $ContentJSON = Get-Content -Path (Join-Path -Path $PSScriptRoot -ChildPath Configuration.json) -Raw | ConvertFrom-Json
+}
+Catch [ArgumentException] {
+ $ContentJSON = (Get-Content -Path (Join-Path -Path $PSScriptRoot -ChildPath Configuration.json) -Raw).Replace('\', '\\') | Set-Content -Path (Join-Path -Path $Env:TEMP -ChildPath Configuration.json) -Encoding UTF8 -Force -PassThru
+ $ContentJSON = $ContentJSON | ConvertFrom-Json
+ Move-Item -Path (Join-Path -Path $Env:TEMP -ChildPath Configuration.json) -Destination $PSScriptRoot -Force
+ $Global:Error.Remove($Error[-1])
+}
+Finally {
+ $ContentJSON.PSObject.Properties.Remove('_Info')
+}
+
+# Convert the JSON object into a nested ordered collection list. We use the PSObject.Properties method to retain the JSON object order.
+$ConfigParams = [Ordered]@{
+ populateLists = $populateLists
+ populateTemplates = $populateTemplates
+}
+ForEach ($Name In $ContentJSON.PSObject.Properties.Name) {
+ $Value = $ContentJSON.PSObject.Properties.Item($Name).Value
+ If ($Value -is [PSCustomObject]) {
+ $ConfigParams.$Name = [Ordered]@{ }
+ ForEach ($Property in $Value.PSObject.Properties) {
+ $ConfigParams.$Name[$Property.Name] = $Property.Value
+ }
+ }
+ Else {
+ $ConfigParams.$Name = $Value
+ }
+}
+
+# Import the Optimize-Offline module and call it by passing the JSON configuration.
+If ($PSVersionTable.PSVersion.Major -gt 5) {
+ Try {
+ Import-Module Dism -SkipEditionCheck -Force -WarningAction Ignore -ErrorAction Stop
+ }
+ Catch {
+ Write-Warning 'Failed to import the required Dism module.'
+ Start-Sleep 3
+ Exit
+ }
+ Try {
+ Import-Module (Join-Path -Path $PSScriptRoot -ChildPath Optimize-Offline.psm1) -SkipEditionCheck -Force -WarningAction Ignore -ErrorAction Stop
+ }
+ Catch {
+ Write-Warning ('Failed to import the Optimize-Offline module: "{0}"' -f (Join-Path -Path $PSScriptRoot -ChildPath Optimize-Offline.psm1))
+ Start-Sleep 3
+ Exit
+ }
+}
+Else {
+ Try {
+ Import-Module (Join-Path -Path $PSScriptRoot -ChildPath Optimize-Offline.psm1) -Force -WarningAction Ignore -ErrorAction Stop
+ }
+ Catch {
+ Write-Warning ('Failed to import the Optimize-Offline module: "{0}"' -f (Join-Path -Path $PSScriptRoot -ChildPath Optimize-Offline.psm1))
+ Start-Sleep 3
+ Exit
+ }
+}
+
+Optimize-Offline @ConfigParams
diff --git a/Start-Optimize.bat b/Start-Optimize.bat
new file mode 100644
index 0000000..c92beb3
--- /dev/null
+++ b/Start-Optimize.bat
@@ -0,0 +1,34 @@
+@echo off
+
+:: BatchGotAdmin
+:-------------------------------------
+REM --> Check for permissions
+ IF "%PROCESSOR_ARCHITECTURE%" EQU "amd64" (
+>nul 2>&1 "%SYSTEMROOT%\SysWOW64\cacls.exe" "%SYSTEMROOT%\SysWOW64\config\system"
+) ELSE (
+>nul 2>&1 "%SYSTEMROOT%\system32\cacls.exe" "%SYSTEMROOT%\system32\config\system"
+)
+
+REM --> If error flag set, we do not have admin.
+if '%errorlevel%' NEQ '0' (
+ echo Requesting administrative privileges...
+ goto UACPrompt
+) else ( goto gotAdmin )
+
+:UACPrompt
+ echo Set UAC = CreateObject^("Shell.Application"^) > "%temp%\getadmin.vbs"
+ set params= %*
+ echo UAC.ShellExecute "cmd.exe", "/c ""%~s0"" %params:"=""%", "", "runas", 1 >> "%temp%\getadmin.vbs"
+
+ "%temp%\getadmin.vbs"
+ del "%temp%\getadmin.vbs"
+ exit /B
+
+:gotAdmin
+ pushd "%CD%"
+ CD /D "%~dp0"
+
+
+
+powershell -ExecutionPolicy Bypass -File "%~dp0Start-helper.ps1"
+pause
\ No newline at end of file
diff --git a/Start-Optimize.ps1 b/Start-Optimize.ps1
index f3d84e8..df94a8d 100644
--- a/Start-Optimize.ps1
+++ b/Start-Optimize.ps1
@@ -1,5 +1,4 @@
-#Requires -RunAsAdministrator
-<#
+<#
.SYNOPSIS
Start-Optimize is a configuration call script for the Optimize-Offline module.
@@ -15,104 +14,126 @@
Start-Optimize requires that the configuration JSON file is present in the root path of the Optimize-Offline module.
#>
[CmdletBinding()]
-Param ()
+Param (
+ [Parameter(Mandatory = $false)] [switch]$populateLists,
+ [Parameter(Mandatory = $false)] [switch]$populateTemplates,
+ [Parameter(Mandatory = $false)] [switch]$GUI,
+ [Parameter(Mandatory = $false)] [int]$FlashUSBDriveNumber = -1
+)
$Global:Error.Clear()
# Ensure we are running with administrative permissions.
-If (!([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator))
-{
- Write-Warning "Elevation is required to process optimizations. Please relaunch Start-Optimize as an administrator."
- Start-Sleep 3
- Exit
+If (!([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)) {
+ $arguments = @(" Set-ExecutionPolicy Bypass -Scope Process -Force; & '" + $MyInvocation.MyCommand.Definition + "'")
+ foreach ($param in $PSBoundParameters.GetEnumerator()) {
+ $arguments += "-"+[string]$param.Key+$(If ($null -ne $param.Value -and $param.Value -ne "" -and $param.Value -notin @("True", "False")) {" '"+$param.Value+"'"} Else {""})
+ }
+ If(!$GUI){
+ $arguments += " ; pause"
+ }
+ Start-Process powershell -Verb RunAs -ArgumentList $arguments
+ Stop-Process -Id $PID
+}
+
+$configration_selected = "Configuration.json"
+
+If (Test-Path -Path (Join-Path -Path $PSScriptRoot -ChildPath "Configuration_custom.json")) {
+ $configration_selected = "Configuration_custom.json"
}
# Ensure the configuration JSON file exists.
-If (!(Test-Path -Path (Join-Path -Path $PSScriptRoot -ChildPath Configuration.json)))
-{
- Write-Warning ('The required configuration JSON file does not exist: "{0}"' -f (Join-Path -Path $PSScriptRoot -ChildPath Configuration.json))
+If (!(Test-Path -Path (Join-Path -Path $PSScriptRoot -ChildPath $configration_selected))) {
+ Write-Warning ('The required configuration JSON file does not exist: "{0}"' -f (Join-Path -Path $PSScriptRoot -ChildPath $configration_selected))
Start-Sleep 3
Exit
}
# If the configuration JSON or ordered collection list variables still exists from a previous session, remove them.
-If ((Test-Path -Path Variable:\ContentJSON) -or (Test-Path -Path Variable:\ConfigParams))
-{
+If ((Test-Path -Path Variable:\ContentJSON) -or (Test-Path -Path Variable:\ConfigParams)) {
Remove-Variable -Name ContentJSON, ConfigParams -ErrorAction Ignore
}
# Use a Try/Catch/Finally block in case the configuration JSON file URL formatting is invalid so we can catch it, correct its formatting and continue.
-Try
-{
- $ContentJSON = Get-Content -Path (Join-Path -Path $PSScriptRoot -ChildPath Configuration.json) -Raw | ConvertFrom-Json
+Try {
+ $ContentJSON = Get-Content -Path (Join-Path -Path $PSScriptRoot -ChildPath $configration_selected) -Raw | ConvertFrom-Json
}
-Catch [ArgumentException]
-{
- $ContentJSON = (Get-Content -Path (Join-Path -Path $PSScriptRoot -ChildPath Configuration.json) -Raw).Replace('\', '\\') | Set-Content -Path (Join-Path -Path $Env:TEMP -ChildPath Configuration.json) -Encoding UTF8 -Force -PassThru
+Catch [ArgumentException] {
+ $ContentJSON = (Get-Content -Path (Join-Path -Path $PSScriptRoot -ChildPath $configration_selected) -Raw).Replace('\', '\\') | Set-Content -Path (Join-Path -Path $Env:TEMP -ChildPath $configration_selected) -Encoding UTF8 -Force -PassThru
$ContentJSON = $ContentJSON | ConvertFrom-Json
- Move-Item -Path (Join-Path -Path $Env:TEMP -ChildPath Configuration.json) -Destination $PSScriptRoot -Force
+ Move-Item -Path (Join-Path -Path $Env:TEMP -ChildPath $configration_selected) -Destination $PSScriptRoot -Force
$Global:Error.Remove($Error[-1])
}
-Finally
-{
+Finally {
$ContentJSON.PSObject.Properties.Remove('_Info')
}
# Convert the JSON object into a nested ordered collection list. We use the PSObject.Properties method to retain the JSON object order.
$ConfigParams = [Ordered]@{ }
-ForEach ($Name In $ContentJSON.PSObject.Properties.Name)
-{
+ForEach ($Name In $ContentJSON.PSObject.Properties.Name) {
$Value = $ContentJSON.PSObject.Properties.Item($Name).Value
- If ($Value -is [PSCustomObject])
- {
+ If ($Value -is [PSCustomObject]) {
$ConfigParams.$Name = [Ordered]@{ }
- ForEach ($Property in $Value.PSObject.Properties)
- {
+ ForEach ($Property in $Value.PSObject.Properties) {
$ConfigParams.$Name[$Property.Name] = $Property.Value
}
}
- Else
- {
+ Else {
$ConfigParams.$Name = $Value
}
}
+$ConfigParams.populateLists = $populateLists
+$ConfigParams.populateTemplates = $populateTemplates
+
+If ($FlashUSBDriveNumber -ge 0){
+ $ConfigParams.FlashUSBDriveNumber = $FlashUSBDriveNumber
+}
# Import the Optimize-Offline module and call it by passing the JSON configuration.
-If ($PSVersionTable.PSVersion.Major -gt 5)
-{
- Try
- {
+If ($PSVersionTable.PSVersion.Major -gt 5) {
+ Try {
Import-Module Dism -SkipEditionCheck -Force -WarningAction Ignore -ErrorAction Stop
}
- Catch
- {
+ Catch {
Write-Warning 'Failed to import the required Dism module.'
Start-Sleep 3
Exit
}
- Try
- {
+ Try {
Import-Module (Join-Path -Path $PSScriptRoot -ChildPath Optimize-Offline.psm1) -SkipEditionCheck -Force -WarningAction Ignore -ErrorAction Stop
}
- Catch
- {
+ Catch {
Write-Warning ('Failed to import the Optimize-Offline module: "{0}"' -f (Join-Path -Path $PSScriptRoot -ChildPath Optimize-Offline.psm1))
Start-Sleep 3
Exit
}
}
-Else
-{
- Try
- {
+Else {
+ Try {
Import-Module (Join-Path -Path $PSScriptRoot -ChildPath Optimize-Offline.psm1) -Force -WarningAction Ignore -ErrorAction Stop
}
- Catch
- {
+ Catch {
Write-Warning ('Failed to import the Optimize-Offline module: "{0}"' -f (Join-Path -Path $PSScriptRoot -ChildPath Optimize-Offline.psm1))
Start-Sleep 3
Exit
}
}
-Optimize-Offline @ConfigParams
\ No newline at end of file
+If ($GUI){
+ Try{
+ Optimize-Offline @ConfigParams
+ } Catch {
+ $formatstring = "{0} : {1}`n{2}`n" +
+ " + CategoryInfo : {3}`n" +
+ " + FullyQualifiedErrorId : {4}`n"
+ $fields = $_.InvocationInfo.MyCommand.Name,
+ $_.ErrorDetails.Message,
+ $_.InvocationInfo.PositionMessage,
+ $_.CategoryInfo.ToString(),
+ $_.FullyQualifiedErrorId
+ Write-Host -Foreground Red ($formatstring -f $fields)
+ Exit
+ }
+} Else {
+ Optimize-Offline @ConfigParams
+}
diff --git a/Start-helper.ps1 b/Start-helper.ps1
new file mode 100644
index 0000000..bf2ce6e
--- /dev/null
+++ b/Start-helper.ps1
@@ -0,0 +1,5 @@
+$scriptPath = '.\Start-Optimize.ps1'
+$process = Start-Process -FilePath "powershell.exe" -ArgumentList ("-NoExit", "-ExecutionPolicy Bypass", "-File `"$scriptPath`"") -PassThru
+$process | Wait-Process
+
+& .\Remove_Failure_no_prompts.cmd
\ No newline at end of file
diff --git a/docs/Optimize-Offline-help.md b/docs/Optimize-Offline-help.md
index d55e2fd..0871ac0 100644
--- a/docs/Optimize-Offline-help.md
+++ b/docs/Optimize-Offline-help.md
@@ -14,7 +14,7 @@ Offline optimization framework for Windows 10 image versions 1803-to-2004 with 6
```
Optimize-Offline [-SourcePath] [[-WindowsApps] ] [-SystemApps] [-Capabilities] [-Packages]
- [-Features] [-DeveloperMode] [-WindowsStore] [-MicrosoftEdge] [-Win32Calc] [-Dedup] [[-DaRT] ]
+ [-Features] [-DeveloperMode] [-WindowsStore] [-MicrosoftEdge] [-Win32Calc] [-DormantDefender] [-Dedup] [[-DaRT] ]
[-Registry] [[-Additional] ] [-ComponentCleanup] [[-ISO] ] []
```
@@ -38,7 +38,7 @@ This command automatically starts optimizing an image by importing the configura
### EXAMPLE 2
```
-Optimize-Offline -SourcePath "D:\Images\Windows 10 1903\18362.1.190318-1202.19H1_RELEASE_CLIENTMULTI_X64FRE_EN-US.iso" -WindowsApps "Select" -SystemApps -Capabilities -Packages -Features -Win32Calc -Dedup -DaRT "Setup" -Registry -Additional @{ Setup = $true; RegistryTemplates = $true; LayoutModification = $true; Drivers = $true } -ISO "No-Prompt"
+Optimize-Offline -SourcePath "D:\Images\Windows 10 1903\18362.1.190318-1202.19H1_RELEASE_CLIENTMULTI_X64FRE_EN-US.iso" -WindowsApps "Select" -SystemApps -Capabilities -Packages -Features -Win32Calc -DormantDefender -Dedup -DaRT "Setup" -Registry -Additional @{ Setup = $true; RegistryTemplates = $true; LayoutModification = $true; Drivers = $true } -ISO "No-Prompt"
```
This command starts optimizing an image by manually passing parameters to the module.
@@ -202,6 +202,21 @@ Accept pipeline input: False
Accept wildcard characters: False
```
+### -DormantDefender
+Disable Windows defender while retaining the option to reactivate it.
+
+```yaml
+Type: SwitchParameter
+Parameter Sets: (All)
+Aliases:
+
+Required: False
+Position: Named
+Default value: False
+Accept pipeline input: False
+Accept wildcard characters: False
+```
+
### -Dedup
Integrates the Windows Server Data Deduplication Feature into the image.
diff --git a/en-US/Optimize-Offline-help.xml b/en-US/Optimize-Offline-help.xml
index a59d38a..87abace 100644
--- a/en-US/Optimize-Offline-help.xml
+++ b/en-US/Optimize-Offline-help.xml
@@ -168,6 +168,17 @@
False
+
+ DormantDefender
+
+ Disable Windows defender while retaining the option to reactivate it.
+
+
+ SwitchParameter
+
+
+ False
+
Dedup
@@ -326,6 +337,18 @@
False
+
+ DormantDefender
+
+ Disable Windows defender while retaining the option to reactivate it.
+
+ SwitchParameter
+
+ SwitchParameter
+
+
+ False
+
Dedup
@@ -453,7 +476,7 @@
-------------------------- EXAMPLE 2 --------------------------
- Optimize-Offline -SourcePath "D:\Images\Windows 10 1903\18362.1.190318-1202.19H1_RELEASE_CLIENTMULTI_X64FRE_EN-US.iso" -WindowsApps "Select" -SystemApps -Capabilities -Packages -Features -Win32Calc -Dedup -DaRT "Setup" -Registry -Additional @{ Setup = $true; RegistryTemplates = $true; Drivers = $true } -ISO "No-Prompt"
+ Optimize-Offline -SourcePath "D:\Images\Windows 10 1903\18362.1.190318-1202.19H1_RELEASE_CLIENTMULTI_X64FRE_EN-US.iso" -WindowsApps "Select" -SystemApps -Capabilities -Packages -Features -Win32Calc -DormantDefender -Dedup -DaRT "Setup" -Registry -Additional @{ Setup = $true; RegistryTemplates = $true; Drivers = $true } -ISO "No-Prompt"
This command starts optimizing an image by manually passing parameters to the cmdlet.
@@ -474,4 +497,4 @@
-
\ No newline at end of file
+
diff --git a/en-US/Optimize-Offline.strings.psd1 b/en-US/Optimize-Offline.strings.psd1
index 498ba2e..8d65fce 100644
--- a/en-US/Optimize-Offline.strings.psd1
+++ b/en-US/Optimize-Offline.strings.psd1
@@ -5,7 +5,7 @@ InvalidWindowsInstallMedia = "{0}" does not contain valid Windows I
ExportingMedia = Exporting media from "{0}"
CopyingImage = Copying {0} from "{1}"
FailedToReturnInstallImage = Failed to return the Install Image from "{0}"
-SelectWindowsEdition = Select the Windows 10 Edition to Optimize.
+SelectWindowsEdition = Select the Windows Edition to Optimize.
FailedToRetrieveImageMetadata = Failed to retrieve the necessary image metadata from the {0}
UnsupportedImageVersion = Unsupported Image Version: [{0}]
UnsupportedImageArch = Unsupported Image Architecture: [{0}]
@@ -24,9 +24,9 @@ SystemAppsWarning = Do NOT remove any System Application i
RemovingSystemApp = Removing System App: {0}
FailedRemovingSystemApp = Failed to Remove System App: {0}
FailedRemovingSystemApps = Failed to Remove System Apps.
-RemovedPackageCleanup = Disabling Services, Drivers and Integration Content for Removed Apps.
-RemovingBiometricCapability = Removing Windows Biometric Capability Packages.
-FailedRemovingBiometricCapability = Failed to Remove Windows Biometric Capability Packages.
+DisableDefender = Disabling Defender Start-up and Feature Packages.
+RemovingBiometricCapability = Removing Windows Biometric Capability: {0}
+FailedRemovingBiometricCapability = Failed to Remove Windows Biometric Capabilities.
DisablingDefenderOptionalFeature = Disabling Optional Feature: Windows-Defender-Default-Definitions
FailedDisablingDefenderOptionalFeature = Failed to Disable Optional Feature: Windows-Defender-Default-Definitions
ImportingCustomAppAssociations = Importing Custom App Associations.
@@ -79,7 +79,7 @@ InjectingDriverPackages = Injecting Driver Packages into {0}
FailedInjectingDriverPackages = Failed to Inject Driver Packages into {0}
EnablingNetFx3 = Enabling Optional Feature: NetFx3
FailedEnablingNetFx3 = Failed to Enable Optional Feature: NetFx3
-ComponentStoreCleanup = Performing a Clean-up of the {0} Component Store.
+ComponentStoreCleanup = Performing a Clean-up of the {0} Component Store. This may take some time to complete.
FailedComponentStoreCleanup = Failed to perform a Clean-up of the {0} Component Store.
ComponentStorePendingInstallations = Cannot perform a clean-up of the Component Store while there are pending installations.
CleanupStartMenu = Cleaning-up the Start Menu Layout.
@@ -101,4 +101,28 @@ FailedCreatingISO = Failed to Create a {0} Bootable Window
FinalizingOptimizations = Finalizing Optimizations.
OptimizationsCompleted = {0} completed in [{1}] minutes with [{2}] errors.
TerminatingOptimizations = Discarding any Images and Terminating Optimizations.
-'@
\ No newline at end of file
+Populating = populating
+SelectiveRegistryWindowsUpgrade = Disabling Windows Upgrade
+SelectiveRegistryWindowsUpdateMS = Disabling Windows update contacting Microsoft servers
+SelectiveRegistryDriverUpdate = Disabling automatic driver update
+SelectiveRegistryDormantOneDrive = Enabling dormant OneDrive fix
+SelectiveRegistryDisable3rdPartyApps = Disabling 3rd party apps
+SelectiveRegistryW11ClassicContextMenu = Setting W11 classic context menu
+SelectiveRegistryExplorerUIRibbon = Enabling explorer classic UI ribbon
+SelectiveRegistryRemoveTaskbarPinnedIcons = Removing taskbar pinned icons
+SelectiveRegistryDisableVirtualizationSecurity = Disabling virtualization security
+SelectiveRegistryAmoledBlackTheme = Adding AMOLED pitch-black theme
+SelectiveRegistryClassicSearchExplorer = Setting classic search explorer
+SelectiveRegistryDisableTeamsApp = Disabling Microsoft Teams autostart entry
+SelectiveRegistryRunAsTiContextMenu = Adding Powershell as trusted installer context menu entry
+ServiceStartBoot = Boot
+ServiceStartSystem = System
+ServiceStartAutomatic = Automatic
+ServiceStartManual = Manual
+ServiceStartDisabled = Disabled
+ServiceModifying = Modifying windows service
+ServicesModifying = Modifying windows services
+DeliveryOptimizationBypass = Setting delivery optimization to bypass mode
+ServicesRemovalFailed = Failed removing windows services
+ChooseServicesTitle = Choose services to remove
+'@
diff --git a/populateLists.bat b/populateLists.bat
new file mode 100644
index 0000000..5610a78
--- /dev/null
+++ b/populateLists.bat
@@ -0,0 +1 @@
+powershell -ExecutionPolicy Bypass -File "%~dp0Start-Optimize.ps1" "-populateLists"
\ No newline at end of file
diff --git a/populateTemplates.bat b/populateTemplates.bat
new file mode 100644
index 0000000..edc1e4a
--- /dev/null
+++ b/populateTemplates.bat
@@ -0,0 +1 @@
+powershell -ExecutionPolicy Bypass -File "%~dp0Start-Optimize.ps1" "-populateTemplates"
\ No newline at end of file