diff --git a/tiny11maker.ps1 b/tiny11maker.ps1 index c24757f..6705d9b 100644 --- a/tiny11maker.ps1 +++ b/tiny11maker.ps1 @@ -13,24 +13,29 @@ .PARAMETER SCRATCH Drive letter of the desired scratch disk (eg: D) +.PARAMETER Custom + Optional argument used to enable custom debloating selections. + .EXAMPLE + .\tiny11maker.ps1 .\tiny11maker.ps1 E D .\tiny11maker.ps1 -ISO E -SCRATCH D .\tiny11maker.ps1 -SCRATCH D -ISO E - .\tiny11maker.ps1 + .\tiny11maker.ps1 -SCRATCH D -ISO E -Custom *If you ordinal parameters the first one must be the mounted iso. The second is the scratch drive. prefer the use of full named parameter (eg: "-ISO") as you can put in the order you want. .NOTES Auteur: ntdevlabs - Date: 09-07-25 + Date: 09-28-25 #> #---------[ Parameters ]---------# param ( [ValidatePattern('^[c-zC-Z]$')][string]$ISO, - [ValidatePattern('^[c-zC-Z]$')][string]$SCRATCH + [ValidatePattern('^[c-zC-Z]$')][string]$SCRATCH, + [switch]$Custom ) if (-not $SCRATCH) { @@ -145,12 +150,14 @@ Remove-Item "$ScratchDisk\tiny11\sources\install.esd" > $null 2>&1 Write-Output "Copy complete!" Start-Sleep -Seconds 2 Clear-Host + Write-Output "Getting image information:" $ImagesIndex = (Get-WindowsImage -ImagePath $ScratchDisk\tiny11\sources\install.wim).ImageIndex while ($ImagesIndex -notcontains $index) { Get-WindowsImage -ImagePath $ScratchDisk\tiny11\sources\install.wim $index = Read-Host "Please enter the image index" } + Write-Output "Mounting Windows image. This may take a while." $wimFilePath = "$ScratchDisk\tiny11\sources\install.wim" & takeown "/F" $wimFilePath @@ -166,7 +173,6 @@ Mount-WindowsImage -ImagePath $ScratchDisk\tiny11\sources\install.wim -Index $in $imageIntl = & dism /English /Get-Intl "/Image:$($ScratchDisk)\scratchdir" $languageLine = $imageIntl -split '\n' | Where-Object { $_ -match 'Default system UI language : ([a-zA-Z]{2}-[a-zA-Z]{2})' } - if ($languageLine) { $languageCode = $Matches[1] Write-Output "Default system UI language code: $languageCode" @@ -176,7 +182,6 @@ if ($languageLine) { $imageInfo = & 'dism' '/English' '/Get-WimInfo' "/wimFile:$($ScratchDisk)\tiny11\sources\install.wim" "/index:$index" $lines = $imageInfo -split '\r?\n' - foreach ($line in $lines) { if ($line -like '*Architecture : *') { $architecture = $line -replace 'Architecture : ','' @@ -188,13 +193,11 @@ foreach ($line in $lines) { break } } - if (-not $architecture) { Write-Output "Architecture information not found." } Write-Output "Mounting complete! Performing removal of applications..." - $packages = & 'dism' '/English' "/image:$($ScratchDisk)\scratchdir" '/Get-ProvisionedAppxPackages' | ForEach-Object { if ($_ -match 'PackageName : (.*)') { @@ -256,11 +259,44 @@ $packagePrefixes = 'AppUp.IntelManagementandSecurityStatus', 'Microsoft.WindowsTerminal', 'Microsoft.549981C3F5F10' -$packagesToRemove = $packages | Where-Object { - $packageName = $_ - $packagePrefixes -contains ($packagePrefixes | Where-Object { $packageName -like "*$_*" }) +if ($Custom) { + $Confirmation = "" + $selectedPrefixes = @() + + while ($Confirmation -ne 'Yes') { + Write-Output "List of applications to remove:" + for ($i=0; $i -lt $packages.Count; $i++) { + Write-Output "$($i+1). $($packages[$i])" + } + $userInput = Read-Host "Selected numbers (eg: 1,3,5)" + $selectedPrefixes = $userInput -split "," | ForEach-Object { + $select_index = $_.Trim() + if ($select_index -match '^\d+$' -and $select_index -ge 1 -and $select_index -le $packages.Count) { + $packages[$select_index-1] + } + } + Write-Output "Chosen package prefixes: $selectedPrefixes" + $Confirmation = Read-Host "Type 'Yes' to confirm your selection and proceed with the removal, or press Enter to reselect" + } + + $packagesToRemove = @() + foreach ($prefix in $selectedPrefixes) { + $matches = $packages | Where-Object { $_ -like "$prefix*" } + $packagesToRemove += $matches + } + $packagesToRemove = $packagesToRemove | Sort-Object -Unique +} else { + + $packagesToRemove = @() + foreach ($prefix in $packagePrefixes) { + $matches = $packages | Where-Object { $_ -like "$prefix*" } + $packagesToRemove += $matches + } + $packagesToRemove = $packagesToRemove | Sort-Object -Unique } + foreach ($package in $packagesToRemove) { + Write-Host "Removing $package" & 'dism' '/English' "/image:$($ScratchDisk)\scratchdir" '/Remove-ProvisionedAppxPackage' "/PackageName:$package" } @@ -271,19 +307,23 @@ Remove-Item -Path "$ScratchDisk\scratchdir\Program Files (x86)\Microsoft\EdgeCor & 'takeown' '/f' "$ScratchDisk\scratchdir\Windows\System32\Microsoft-Edge-Webview" '/r' | Out-Null & 'icacls' "$ScratchDisk\scratchdir\Windows\System32\Microsoft-Edge-Webview" '/grant' "$($adminGroup.Value):(F)" '/T' '/C' | Out-Null Remove-Item -Path "$ScratchDisk\scratchdir\Windows\System32\Microsoft-Edge-Webview" -Recurse -Force | Out-Null + Write-Output "Removing OneDrive:" & 'takeown' '/f' "$ScratchDisk\scratchdir\Windows\System32\OneDriveSetup.exe" | Out-Null & 'icacls' "$ScratchDisk\scratchdir\Windows\System32\OneDriveSetup.exe" '/grant' "$($adminGroup.Value):(F)" '/T' '/C' | Out-Null Remove-Item -Path "$ScratchDisk\scratchdir\Windows\System32\OneDriveSetup.exe" -Force | Out-Null Write-Output "Removal complete!" + Start-Sleep -Seconds 2 Clear-Host + Write-Output "Loading registry..." reg load HKLM\zCOMPONENTS $ScratchDisk\scratchdir\Windows\System32\config\COMPONENTS | Out-Null reg load HKLM\zDEFAULT $ScratchDisk\scratchdir\Windows\System32\config\default | Out-Null reg load HKLM\zNTUSER $ScratchDisk\scratchdir\Users\Default\ntuser.dat | Out-Null reg load HKLM\zSOFTWARE $ScratchDisk\scratchdir\Windows\System32\config\SOFTWARE | Out-Null reg load HKLM\zSYSTEM $ScratchDisk\scratchdir\Windows\System32\config\SYSTEM | Out-Null + Write-Output "Bypassing system requirements(on the system image):" Set-RegistryValue 'HKLM\zDEFAULT\Control Panel\UnsupportedHardwareNotificationCache' 'SV1' 'REG_DWORD' '0' Set-RegistryValue 'HKLM\zDEFAULT\Control Panel\UnsupportedHardwareNotificationCache' 'SV2' 'REG_DWORD' '0' @@ -295,6 +335,7 @@ Set-RegistryValue 'HKLM\zSYSTEM\Setup\LabConfig' 'BypassSecureBootCheck' 'REG_DW Set-RegistryValue 'HKLM\zSYSTEM\Setup\LabConfig' 'BypassStorageCheck' 'REG_DWORD' '1' Set-RegistryValue 'HKLM\zSYSTEM\Setup\LabConfig' 'BypassTPMCheck' 'REG_DWORD' '1' Set-RegistryValue 'HKLM\zSYSTEM\Setup\MoSetup' 'AllowUpgradesWithUnsupportedTPMOrCPU' 'REG_DWORD' '1' + Write-Output "Disabling Sponsored Apps:" Set-RegistryValue 'HKLM\zNTUSER\SOFTWARE\Microsoft\Windows\CurrentVersion\ContentDeliveryManager' 'OemPreInstalledAppsEnabled' 'REG_DWORD' '0' Set-RegistryValue 'HKLM\zNTUSER\SOFTWARE\Microsoft\Windows\CurrentVersion\ContentDeliveryManager' 'PreInstalledAppsEnabled' 'REG_DWORD' '0' @@ -319,22 +360,28 @@ Remove-RegistryValue 'HKLM\zNTUSER\Software\Microsoft\Windows\CurrentVersion\Con Remove-RegistryValue 'HKLM\zNTUSER\Software\Microsoft\Windows\CurrentVersion\ContentDeliveryManager\SuggestedApps' Set-RegistryValue 'HKLM\zSOFTWARE\Policies\Microsoft\Windows\CloudContent' 'DisableConsumerAccountStateContent' 'REG_DWORD' '1' Set-RegistryValue 'HKLM\zSOFTWARE\Policies\Microsoft\Windows\CloudContent' 'DisableCloudOptimizedContent' 'REG_DWORD' '1' + Write-Output "Enabling Local Accounts on OOBE:" Set-RegistryValue 'HKLM\zSOFTWARE\Microsoft\Windows\CurrentVersion\OOBE' 'BypassNRO' 'REG_DWORD' '1' Copy-Item -Path "$PSScriptRoot\autounattend.xml" -Destination "$ScratchDisk\scratchdir\Windows\System32\Sysprep\autounattend.xml" -Force | Out-Null Write-Output "Disabling Reserved Storage:" Set-RegistryValue 'HKLM\zSOFTWARE\Microsoft\Windows\CurrentVersion\ReserveManager' 'ShippedWithReserves' 'REG_DWORD' '0' + Write-Output "Disabling BitLocker Device Encryption" Set-RegistryValue 'HKLM\zSYSTEM\ControlSet001\Control\BitLocker' 'PreventDeviceEncryption' 'REG_DWORD' '1' + Write-Output "Disabling Chat icon:" Set-RegistryValue 'HKLM\zSOFTWARE\Policies\Microsoft\Windows\Windows Chat' 'ChatIcon' 'REG_DWORD' '3' Set-RegistryValue 'HKLM\zNTUSER\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\Advanced' 'TaskbarMn' 'REG_DWORD' '0' + Write-Output "Removing Edge related registries" Remove-RegistryValue "HKEY_LOCAL_MACHINE\zSOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall\Microsoft Edge" Remove-RegistryValue "HKEY_LOCAL_MACHINE\zSOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall\Microsoft Edge Update" + Write-Output "Disabling OneDrive folder backup" Set-RegistryValue "HKLM\zSOFTWARE\Policies\Microsoft\Windows\OneDrive" "DisableFileSyncNGSC" "REG_DWORD" "1" + Write-Output "Disabling Telemetry:" Set-RegistryValue 'HKLM\zNTUSER\Software\Microsoft\Windows\CurrentVersion\AdvertisingInfo' 'Enabled' 'REG_DWORD' '0' Set-RegistryValue 'HKLM\zNTUSER\Software\Microsoft\Windows\CurrentVersion\Privacy' 'TailoredExperiencesWithDiagnosticDataEnabled' 'REG_DWORD' '0' @@ -346,21 +393,49 @@ Set-RegistryValue 'HKLM\zNTUSER\Software\Microsoft\InputPersonalization\TrainedD Set-RegistryValue 'HKLM\zNTUSER\Software\Microsoft\Personalization\Settings' 'AcceptedPrivacyPolicy' 'REG_DWORD' '0' Set-RegistryValue 'HKLM\zSOFTWARE\Policies\Microsoft\Windows\DataCollection' 'AllowTelemetry' 'REG_DWORD' '0' Set-RegistryValue 'HKLM\zSYSTEM\ControlSet001\Services\dmwappushservice' 'Start' 'REG_DWORD' '4' -## Prevents installation of DevHome and Outlook -Write-Output "Prevents installation of DevHome and Outlook:" -Set-RegistryValue 'HKLM\zSOFTWARE\Microsoft\Windows\CurrentVersion\WindowsUpdate\Orchestrator\UScheduler_Oobe\OutlookUpdate' 'workCompleted' 'REG_DWORD' '1' -Set-RegistryValue 'HKLM\zSOFTWARE\Microsoft\Windows\CurrentVersion\WindowsUpdate\Orchestrator\UScheduler\OutlookUpdate' 'workCompleted' 'REG_DWORD' '1' -Set-RegistryValue 'HKLM\zSOFTWARE\Microsoft\Windows\CurrentVersion\WindowsUpdate\Orchestrator\UScheduler\DevHomeUpdate' 'workCompleted' 'REG_DWORD' '1' -Remove-RegistryValue 'HKLM\zSOFTWARE\Microsoft\WindowsUpdate\Orchestrator\UScheduler_Oobe\OutlookUpdate' -Remove-RegistryValue 'HKLM\zSOFTWARE\Microsoft\WindowsUpdate\Orchestrator\UScheduler_Oobe\DevHomeUpdate' -Write-Output "Disabling Copilot" -Set-RegistryValue 'HKLM\zSOFTWARE\Policies\Microsoft\Windows\WindowsCopilot' 'TurnOffWindowsCopilot' 'REG_DWORD' '1' -Set-RegistryValue 'HKLM\zSOFTWARE\Policies\Microsoft\Edge' 'HubsSidebarEnabled' 'REG_DWORD' '0' -Set-RegistryValue 'HKLM\zSOFTWARE\Policies\Microsoft\Windows\Explorer' 'DisableSearchBoxSuggestions' 'REG_DWORD' '1' -Write-Output "Prevents installation of Teams:" -Set-RegistryValue 'HKLM\zSOFTWARE\Policies\Microsoft\Teams' 'DisableInstallation' 'REG_DWORD' '1' -Write-Output "Prevent installation of New Outlook": -Set-RegistryValue 'HKLM\zSOFTWARE\Policies\Microsoft\Windows\Windows Mail' 'PreventRun' 'REG_DWORD' '1' + +if (-not $PSBoundParameters.ContainsKey('Custom') -or -not $Custom) { + Write-Output "Prevents installation of DevHome and Outlook:" + Set-RegistryValue 'HKLM\zSOFTWARE\Microsoft\Windows\CurrentVersion\WindowsUpdate\Orchestrator\UScheduler_Oobe\OutlookUpdate' 'workCompleted' 'REG_DWORD' '1' + Set-RegistryValue 'HKLM\zSOFTWARE\Microsoft\Windows\CurrentVersion\WindowsUpdate\Orchestrator\UScheduler\OutlookUpdate' 'workCompleted' 'REG_DWORD' '1' + Remove-RegistryValue 'HKLM\zSOFTWARE\Microsoft\WindowsUpdate\Orchestrator\UScheduler_Oobe\OutlookUpdate' + Set-RegistryValue 'HKLM\zSOFTWARE\Microsoft\Windows\CurrentVersion\WindowsUpdate\Orchestrator\UScheduler\DevHomeUpdate' 'workCompleted' 'REG_DWORD' '1' + Remove-RegistryValue 'HKLM\zSOFTWARE\Microsoft\WindowsUpdate\Orchestrator\UScheduler_Oobe\DevHomeUpdate' + + Write-Output "Disabling Copilot" + Set-RegistryValue 'HKLM\zSOFTWARE\Policies\Microsoft\Windows\WindowsCopilot' 'TurnOffWindowsCopilot' 'REG_DWORD' '1' + Set-RegistryValue 'HKLM\zSOFTWARE\Policies\Microsoft\Edge' 'HubsSidebarEnabled' 'REG_DWORD' '0' + Set-RegistryValue 'HKLM\zSOFTWARE\Policies\Microsoft\Windows\Explorer' 'DisableSearchBoxSuggestions' 'REG_DWORD' '1' + + Write-Output "Prevents installation of Teams:" + Set-RegistryValue 'HKLM\zSOFTWARE\Policies\Microsoft\Teams' 'DisableInstallation' 'REG_DWORD' '1' + + Write-Output "Prevent installation of New Outlook:" + Set-RegistryValue 'HKLM\zSOFTWARE\Policies\Microsoft\Windows\Windows Mail' 'PreventRun' 'REG_DWORD' '1' + +} else { + if ($packagesToRemove -contains 'Microsoft.Windows.DevHome') { + Write-Output "Prevents installation of DevHome:" + Set-RegistryValue 'HKLM\zSOFTWARE\Microsoft\Windows\CurrentVersion\WindowsUpdate\Orchestrator\UScheduler_Oobe\DevHomeUpdate' 'workCompleted' 'REG_DWORD' '1' + Remove-RegistryValue 'HKLM\zSOFTWARE\Microsoft\WindowsUpdate\Orchestrator\UScheduler_Oobe\DevHomeUpdate' + } + if ($packagesToRemove -contains 'Microsoft.OutlookForWindows') { + Write-Output "Prevent installation of New Outlook:" + Set-RegistryValue 'HKLM\zSOFTWARE\Microsoft\Windows\CurrentVersion\WindowsUpdate\Orchestrator\UScheduler_Oobe\OutlookUpdate' 'workCompleted' 'REG_DWORD' '1' + Set-RegistryValue 'HKLM\zSOFTWARE\Microsoft\Windows\CurrentVersion\WindowsUpdate\Orchestrator\UScheduler\OutlookUpdate' 'workCompleted' 'REG_DWORD' '1' + Remove-RegistryValue 'HKLM\zSOFTWARE\Microsoft\WindowsUpdate\Orchestrator\UScheduler_Oobe\OutlookUpdate' + } + if ($packagesToRemove -contains 'Microsoft.Windows.Copilot') { + Write-Output "Disabling Copilot" + Set-RegistryValue 'HKLM\zSOFTWARE\Policies\Microsoft\Windows\WindowsCopilot' 'TurnOffWindowsCopilot' 'REG_DWORD' '1' + Set-RegistryValue 'HKLM\zSOFTWARE\Policies\Microsoft\Edge' 'HubsSidebarEnabled' 'REG_DWORD' '0' + Set-RegistryValue 'HKLM\zSOFTWARE\Policies\Microsoft\Windows\Explorer' 'DisableSearchBoxSuggestions' 'REG_DWORD' '1' + } + if ($packagesToRemove -contains 'Microsoft.Windows.Teams') { + Write-Output "Prevents installation of Teams:" + Set-RegistryValue 'HKLM\zSOFTWARE\Policies\Microsoft\Teams' 'DisableInstallation' 'REG_DWORD' '1' + } +} Write-Host "Deleting scheduled task definition files..." $tasksPath = "$ScratchDisk\scratchdir\Windows\System32\Tasks" @@ -380,31 +455,38 @@ Remove-Item -Path "$tasksPath\Microsoft\Windows\Chkdsk\Proxy" -Force -ErrorActio # Windows Error Reporting (QueueReporting) Remove-Item -Path "$tasksPath\Microsoft\Windows\Windows Error Reporting\QueueReporting" -Force -ErrorAction SilentlyContinue Write-Host "Task files have been deleted." + Write-Host "Unmounting Registry..." reg unload HKLM\zCOMPONENTS | Out-Null reg unload HKLM\zDEFAULT | Out-Null reg unload HKLM\zNTUSER | Out-Null reg unload HKLM\zSOFTWARE | Out-Null reg unload HKLM\zSYSTEM | Out-Null + Write-Output "Cleaning up image..." dism.exe /Image:$ScratchDisk\scratchdir /Cleanup-Image /StartComponentCleanup /ResetBase Write-Output "Cleanup complete." Write-Output ' ' + Write-Output "Unmounting image..." Dismount-WindowsImage -Path $ScratchDisk\scratchdir -Save + Write-Host "Exporting image..." Dism.exe /Export-Image /SourceImageFile:"$ScratchDisk\tiny11\sources\install.wim" /SourceIndex:$index /DestinationImageFile:"$ScratchDisk\tiny11\sources\install2.wim" /Compress:recovery Remove-Item -Path "$ScratchDisk\tiny11\sources\install.wim" -Force | Out-Null Rename-Item -Path "$ScratchDisk\tiny11\sources\install2.wim" -NewName "install.wim" | Out-Null + Write-Output "Windows image completed. Continuing with boot.wim." Start-Sleep -Seconds 2 Clear-Host + Write-Output "Mounting boot image:" $wimFilePath = "$ScratchDisk\tiny11\sources\boot.wim" & takeown "/F" $wimFilePath | Out-Null & icacls $wimFilePath "/grant" "$($adminGroup.Value):(F)" Set-ItemProperty -Path $wimFilePath -Name IsReadOnly -Value $false Mount-WindowsImage -ImagePath $ScratchDisk\tiny11\sources\boot.wim -Index 2 -Path $ScratchDisk\scratchdir + Write-Output "Loading registry..." reg load HKLM\zCOMPONENTS $ScratchDisk\scratchdir\Windows\System32\config\COMPONENTS reg load HKLM\zDEFAULT $ScratchDisk\scratchdir\Windows\System32\config\default @@ -435,13 +517,14 @@ reg unload HKLM\zSYSTEM | Out-Null Write-Output "Unmounting image..." Dismount-WindowsImage -Path $ScratchDisk\scratchdir -Save Clear-Host + Write-Output "The tiny11 image is now completed. Proceeding with the making of the ISO..." Write-Output "Copying unattended file for bypassing MS account on OOBE..." Copy-Item -Path "$PSScriptRoot\autounattend.xml" -Destination "$ScratchDisk\tiny11\autounattend.xml" -Force | Out-Null + Write-Output "Creating ISO image..." $ADKDepTools = "C:\Program Files (x86)\Windows Kits\10\Assessment and Deployment Kit\Deployment Tools\$hostarchitecture\Oscdimg" $localOSCDIMGPath = "$PSScriptRoot\oscdimg.exe" - if ([System.IO.Directory]::Exists($ADKDepTools)) { Write-Output "Will be using oscdimg.exe from system ADK." $OSCDIMG = "$ADKDepTools\oscdimg.exe" @@ -471,14 +554,18 @@ if ([System.IO.Directory]::Exists($ADKDepTools)) { # Finishing up Write-Output "Creation completed! Press any key to exit the script..." Read-Host "Press Enter to continue" + Write-Output "Performing Cleanup..." Remove-Item -Path "$ScratchDisk\tiny11" -Recurse -Force | Out-Null Remove-Item -Path "$ScratchDisk\scratchdir" -Recurse -Force | Out-Null + Write-Output "Ejecting Iso drive" Get-Volume -DriveLetter $DriveLetter[0] | Get-DiskImage | Dismount-DiskImage Write-Output "Iso drive ejected" + Write-Output "Removing oscdimg.exe..." Remove-Item -Path "$PSScriptRoot\oscdimg.exe" -Force -ErrorAction SilentlyContinue + Write-Output "Removing autounattend.xml..." Remove-Item -Path "$PSScriptRoot\autounattend.xml" -Force -ErrorAction SilentlyContinue @@ -532,4 +619,3 @@ if (Test-Path -Path "$PSScriptRoot\autounattend.xml") { Stop-Transcript exit -