mirror of
https://github.com/ntdevlabs/tiny11builder.git
synced 2025-09-16 14:18:01 +02:00
September 2025 release
Features Added removal of Copilot, the new Outlook client, and Microsoft Teams packages. Added registry keys to proactively disable Copilot and prevent app re-installations. Improvements Switched to Dism.exe with /Compress:recovery for significantly smaller final ISO file sizes. Reworked scheduled task removal to be simpler and more reliable.
This commit is contained in:
177
tiny11maker.ps1
177
tiny11maker.ps1
@@ -1,6 +1,3 @@
|
||||
# Enable debugging
|
||||
#Set-PSDebug -Trace 1
|
||||
|
||||
param (
|
||||
[ValidatePattern('^[c-zC-Z]$')]
|
||||
[string]$ScratchDisk
|
||||
@@ -41,15 +38,11 @@ if (! $myWindowsPrincipal.IsInRole($adminRole))
|
||||
[System.Diagnostics.Process]::Start($newProcess);
|
||||
exit
|
||||
}
|
||||
|
||||
|
||||
|
||||
# Start the transcript and prepare the window
|
||||
Start-Transcript -Path "$ScratchDisk\tiny11.log"
|
||||
|
||||
$Host.UI.RawUI.WindowTitle = "Tiny11 image creator"
|
||||
Clear-Host
|
||||
Write-Host "Welcome to the tiny11 image creator! Release: 05-06-24"
|
||||
Write-Host "Welcome to the tiny11 image creator! Release: 09-04-25"
|
||||
|
||||
$hostArchitecture = $Env:PROCESSOR_ARCHITECTURE
|
||||
New-Item -ItemType Directory -Force -Path "$ScratchDisk\tiny11\sources" | Out-Null
|
||||
@@ -95,7 +88,7 @@ $wimFilePath = "$ScratchDisk\tiny11\sources\install.wim"
|
||||
try {
|
||||
Set-ItemProperty -Path $wimFilePath -Name IsReadOnly -Value $false -ErrorAction Stop
|
||||
} catch {
|
||||
# This block will catch the error and suppress it.
|
||||
|
||||
}
|
||||
New-Item -ItemType Directory -Force -Path "$ScratchDisk\scratchdir" > $null
|
||||
Mount-WindowsImage -ImagePath $ScratchDisk\tiny11\sources\install.wim -Index $index -Path $ScratchDisk\scratchdir
|
||||
@@ -137,7 +130,7 @@ $packages = & 'dism' '/English' "/image:$($ScratchDisk)\scratchdir" '/Get-Provis
|
||||
$matches[1]
|
||||
}
|
||||
}
|
||||
$packagePrefixes = 'Clipchamp.Clipchamp_', 'Microsoft.BingNews_', 'Microsoft.BingWeather_', 'Microsoft.GamingApp_', 'Microsoft.GetHelp_', 'Microsoft.Getstarted_', 'Microsoft.MicrosoftOfficeHub_', 'Microsoft.MicrosoftSolitaireCollection_', 'Microsoft.People_', 'Microsoft.PowerAutomateDesktop_', 'Microsoft.Todos_', 'Microsoft.WindowsAlarms_', 'microsoft.windowscommunicationsapps_', 'Microsoft.WindowsFeedbackHub_', 'Microsoft.WindowsMaps_', 'Microsoft.WindowsSoundRecorder_', 'Microsoft.Xbox.TCUI_', 'Microsoft.XboxGamingOverlay_', 'Microsoft.XboxGameOverlay_', 'Microsoft.XboxSpeechToTextOverlay_', 'Microsoft.YourPhone_', 'Microsoft.ZuneMusic_', 'Microsoft.ZuneVideo_', 'MicrosoftCorporationII.MicrosoftFamily_', 'MicrosoftCorporationII.QuickAssist_', 'MicrosoftTeams_', 'Microsoft.549981C3F5F10_'
|
||||
$packagePrefixes = 'Clipchamp.Clipchamp_', 'Microsoft.BingNews_', 'Microsoft.BingWeather_', 'Microsoft.GamingApp_', 'Microsoft.GetHelp_', 'Microsoft.Getstarted_', 'Microsoft.MicrosoftOfficeHub_', 'Microsoft.MicrosoftSolitaireCollection_', 'Microsoft.People_', 'Microsoft.PowerAutomateDesktop_', 'Microsoft.Todos_', 'Microsoft.WindowsAlarms_', 'microsoft.windowscommunicationsapps_', 'Microsoft.WindowsFeedbackHub_', 'Microsoft.WindowsMaps_', 'Microsoft.WindowsSoundRecorder_', 'Microsoft.Xbox.TCUI_', 'Microsoft.XboxGamingOverlay_', 'Microsoft.XboxGameOverlay_', 'Microsoft.XboxSpeechToTextOverlay_', 'Microsoft.YourPhone_', 'Microsoft.ZuneMusic_', 'Microsoft.ZuneVideo_', 'MicrosoftCorporationII.MicrosoftFamily_', 'MicrosoftCorporationII.QuickAssist_', 'MicrosoftTeams_', 'Microsoft.549981C3F5F10_', 'Microsoft.Windows.Copilot', 'MSTeams_', 'Microsoft.OutlookForWindows_', 'Microsoft.Windows.Teams_', 'Microsoft.Copilot_'
|
||||
|
||||
$packagesToRemove = $packages | Where-Object {
|
||||
$packageName = $_
|
||||
@@ -152,29 +145,6 @@ Write-Host "Removing Edge:"
|
||||
Remove-Item -Path "$ScratchDisk\scratchdir\Program Files (x86)\Microsoft\Edge" -Recurse -Force | Out-Null
|
||||
Remove-Item -Path "$ScratchDisk\scratchdir\Program Files (x86)\Microsoft\EdgeUpdate" -Recurse -Force | Out-Null
|
||||
Remove-Item -Path "$ScratchDisk\scratchdir\Program Files (x86)\Microsoft\EdgeCore" -Recurse -Force | Out-Null
|
||||
if ($architecture -eq 'amd64') {
|
||||
$folderPath = Get-ChildItem -Path "$ScratchDisk\scratchdir\Windows\WinSxS" -Filter "amd64_microsoft-edge-webview_31bf3856ad364e35*" -Directory | Select-Object -ExpandProperty FullName
|
||||
|
||||
if ($folderPath) {
|
||||
& 'takeown' '/f' $folderPath '/r' | Out-Null
|
||||
& icacls $folderPath "/grant" "$($adminGroup.Value):(F)" '/T' '/C' | Out-Null
|
||||
Remove-Item -Path $folderPath -Recurse -Force | Out-Null
|
||||
} else {
|
||||
Write-Host "Folder not found."
|
||||
}
|
||||
} elseif ($architecture -eq 'arm64') {
|
||||
$folderPath = Get-ChildItem -Path "$ScratchDisk\scratchdir\Windows\WinSxS" -Filter "arm64_microsoft-edge-webview_31bf3856ad364e35*" -Directory | Select-Object -ExpandProperty FullName | Out-Null
|
||||
|
||||
if ($folderPath) {
|
||||
& 'takeown' '/f' $folderPath '/r'| Out-Null
|
||||
& icacls $folderPath "/grant" "$($adminGroup.Value):(F)" '/T' '/C' | Out-Null
|
||||
Remove-Item -Path $folderPath -Recurse -Force | Out-Null
|
||||
} else {
|
||||
Write-Host "Folder not found."
|
||||
}
|
||||
} else {
|
||||
Write-Host "Unknown architecture: $architecture"
|
||||
}
|
||||
& '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
|
||||
@@ -258,128 +228,44 @@ Write-Host "Disabling Telemetry:"
|
||||
& 'reg' 'add' 'HKLM\zNTUSER\Software\Microsoft\Personalization\Settings' '/v' 'AcceptedPrivacyPolicy' '/t' 'REG_DWORD' '/d' '0' '/f' | Out-Null
|
||||
& 'reg' 'add' 'HKLM\zSOFTWARE\Policies\Microsoft\Windows\DataCollection' '/v' 'AllowTelemetry' '/t' 'REG_DWORD' '/d' '0' '/f' | Out-Null
|
||||
& 'reg' 'add' 'HKLM\zSYSTEM\ControlSet001\Services\dmwappushservice' '/v' 'Start' '/t' 'REG_DWORD' '/d' '4' '/f' | Out-Null
|
||||
## Prevents installation or DevHome and Outlook
|
||||
Write-Host "Prevents installation or DevHome and Outlook:"
|
||||
& 'reg' 'add' 'HKLM\zSOFTWARE\Microsoft\Windows\CurrentVersion\WindowsUpdate\Orchestrator\UScheduler\OutlookUpdate' '/v' 'workCompleted' '/t' 'REG_DWORD' '/d' '1' '/f' | Out-Null
|
||||
& 'reg' 'add' 'HKLM\zSOFTWARE\Microsoft\Windows\CurrentVersion\WindowsUpdate\Orchestrator\UScheduler\DevHomeUpdate' '/v' 'workCompleted' '/t' 'REG_DWORD' '/d' '1' '/f' | Out-Null
|
||||
& 'reg' 'delete' 'HKLM\zSOFTWARE\Microsoft\WindowsUpdate\Orchestrator\UScheduler_Oobe\OutlookUpdate' '/f' | Out-Null
|
||||
& 'reg' 'delete' 'HKLM\zSOFTWARE\Microsoft\WindowsUpdate\Orchestrator\UScheduler_Oobe\DevHomeUpdate' '/f' | Out-Null
|
||||
Write-Host "Disabling Copilot"
|
||||
& 'reg' 'add' 'HKLM\zSOFTWARE\Policies\Microsoft\Windows\WindowsCopilot' '/v' 'TurnOffWindowsCopilot' '/t' 'REG_DWORD' '/d' '1' '/f' | Out-Null
|
||||
& 'reg' 'add' 'HKLM\zSOFTWARE\Policies\Microsoft\Edge' '/v' 'HubsSidebarEnabled' '/t' 'REG_DWORD' '/d' '0' '/f' | Out-Null
|
||||
& 'reg' 'add' 'HKLM\zSOFTWARE\Policies\Microsoft\Windows\Explorer' '/v' 'DisableSearchBoxSuggestions' '/t' 'REG_DWORD' '/d' '1' '/f' | Out-Null
|
||||
Write-Host "Prevents installation of Teams:"
|
||||
& 'reg' 'add' 'HKLM\zSOFTWARE\Policies\Microsoft\Teams' '/v' 'DisableInstallation' '/t' 'REG_DWORD' '/d' '1' '/f' | Out-Null
|
||||
Write-Host "Prevent installation of New Outlook":
|
||||
& 'reg' 'add' 'HKLM\zSOFTWARE\Policies\Microsoft\Windows\Windows Mail' '/v' 'PreventRun' '/t' 'REG_DWORD' '/d' '1' '/f' | Out-Null
|
||||
$tasksPath = "C:\scratchdir\Windows\System32\Tasks"
|
||||
|
||||
## this function allows PowerShell to take ownership of the Scheduled Tasks registry key from TrustedInstaller. Based on Jose Espitia's script.
|
||||
function Enable-Privilege {
|
||||
param(
|
||||
[ValidateSet(
|
||||
"SeAssignPrimaryTokenPrivilege", "SeAuditPrivilege", "SeBackupPrivilege",
|
||||
"SeChangeNotifyPrivilege", "SeCreateGlobalPrivilege", "SeCreatePagefilePrivilege",
|
||||
"SeCreatePermanentPrivilege", "SeCreateSymbolicLinkPrivilege", "SeCreateTokenPrivilege",
|
||||
"SeDebugPrivilege", "SeEnableDelegationPrivilege", "SeImpersonatePrivilege", "SeIncreaseBasePriorityPrivilege",
|
||||
"SeIncreaseQuotaPrivilege", "SeIncreaseWorkingSetPrivilege", "SeLoadDriverPrivilege",
|
||||
"SeLockMemoryPrivilege", "SeMachineAccountPrivilege", "SeManageVolumePrivilege",
|
||||
"SeProfileSingleProcessPrivilege", "SeRelabelPrivilege", "SeRemoteShutdownPrivilege",
|
||||
"SeRestorePrivilege", "SeSecurityPrivilege", "SeShutdownPrivilege", "SeSyncAgentPrivilege",
|
||||
"SeSystemEnvironmentPrivilege", "SeSystemProfilePrivilege", "SeSystemtimePrivilege",
|
||||
"SeTakeOwnershipPrivilege", "SeTcbPrivilege", "SeTimeZonePrivilege", "SeTrustedCredManAccessPrivilege",
|
||||
"SeUndockPrivilege", "SeUnsolicitedInputPrivilege")]
|
||||
$Privilege,
|
||||
## The process on which to adjust the privilege. Defaults to the current process.
|
||||
$ProcessId = $pid,
|
||||
## Switch to disable the privilege, rather than enable it.
|
||||
[Switch] $Disable
|
||||
)
|
||||
$definition = @'
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
public class AdjPriv
|
||||
{
|
||||
[DllImport("advapi32.dll", ExactSpelling = true, SetLastError = true)]
|
||||
internal static extern bool AdjustTokenPrivileges(IntPtr htok, bool disall,
|
||||
ref TokPriv1Luid newst, int len, IntPtr prev, IntPtr relen);
|
||||
|
||||
[DllImport("advapi32.dll", ExactSpelling = true, SetLastError = true)]
|
||||
internal static extern bool OpenProcessToken(IntPtr h, int acc, ref IntPtr phtok);
|
||||
[DllImport("advapi32.dll", SetLastError = true)]
|
||||
internal static extern bool LookupPrivilegeValue(string host, string name, ref long pluid);
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||
internal struct TokPriv1Luid
|
||||
{
|
||||
public int Count;
|
||||
public long Luid;
|
||||
public int Attr;
|
||||
}
|
||||
|
||||
internal const int SE_PRIVILEGE_ENABLED = 0x00000002;
|
||||
internal const int SE_PRIVILEGE_DISABLED = 0x00000000;
|
||||
internal const int TOKEN_QUERY = 0x00000008;
|
||||
internal const int TOKEN_ADJUST_PRIVILEGES = 0x00000020;
|
||||
public static bool EnablePrivilege(long processHandle, string privilege, bool disable)
|
||||
{
|
||||
bool retVal;
|
||||
TokPriv1Luid tp;
|
||||
IntPtr hproc = new IntPtr(processHandle);
|
||||
IntPtr htok = IntPtr.Zero;
|
||||
retVal = OpenProcessToken(hproc, TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, ref htok);
|
||||
tp.Count = 1;
|
||||
tp.Luid = 0;
|
||||
if(disable)
|
||||
{
|
||||
tp.Attr = SE_PRIVILEGE_DISABLED;
|
||||
}
|
||||
else
|
||||
{
|
||||
tp.Attr = SE_PRIVILEGE_ENABLED;
|
||||
}
|
||||
retVal = LookupPrivilegeValue(null, privilege, ref tp.Luid);
|
||||
retVal = AdjustTokenPrivileges(htok, false, ref tp, 0, IntPtr.Zero, IntPtr.Zero);
|
||||
return retVal;
|
||||
}
|
||||
}
|
||||
'@
|
||||
Write-Host "Deleting scheduled task definition files..."
|
||||
|
||||
$processHandle = (Get-Process -id $ProcessId).Handle
|
||||
$type = Add-Type $definition -PassThru
|
||||
$type[0]::EnablePrivilege($processHandle, $Privilege, $Disable)
|
||||
}
|
||||
# Application Compatibility Appraiser
|
||||
Remove-Item -Path "$tasksPath\Microsoft\Windows\Application Experience\Microsoft Compatibility Appraiser" -Force -ErrorAction SilentlyContinue
|
||||
|
||||
Enable-Privilege SeTakeOwnershipPrivilege
|
||||
# Customer Experience Improvement Program (removes the entire folder and all tasks within it)
|
||||
Remove-Item -Path "$tasksPath\Microsoft\Windows\Customer Experience Improvement Program" -Recurse -Force -ErrorAction SilentlyContinue
|
||||
|
||||
$regKey = [Microsoft.Win32.Registry]::LocalMachine.OpenSubKey("zSOFTWARE\Microsoft\Windows NT\CurrentVersion\Schedule\TaskCache\Tasks",[Microsoft.Win32.RegistryKeyPermissionCheck]::ReadWriteSubTree,[System.Security.AccessControl.RegistryRights]::TakeOwnership)
|
||||
$regACL = $regKey.GetAccessControl()
|
||||
$regACL.SetOwner($adminGroup)
|
||||
$regKey.SetAccessControl($regACL)
|
||||
$regKey.Close()
|
||||
Write-Host "Owner changed to Administrators."
|
||||
$regKey = [Microsoft.Win32.Registry]::LocalMachine.OpenSubKey("zSOFTWARE\Microsoft\Windows NT\CurrentVersion\Schedule\TaskCache\Tasks",[Microsoft.Win32.RegistryKeyPermissionCheck]::ReadWriteSubTree,[System.Security.AccessControl.RegistryRights]::ChangePermissions)
|
||||
$regACL = $regKey.GetAccessControl()
|
||||
$regRule = New-Object System.Security.AccessControl.RegistryAccessRule ($adminGroup,"FullControl","ContainerInherit","None","Allow")
|
||||
$regACL.SetAccessRule($regRule)
|
||||
$regKey.SetAccessControl($regACL)
|
||||
Write-Host "Permissions modified for Administrators group."
|
||||
Write-Host "Registry key permissions successfully updated."
|
||||
$regKey.Close()
|
||||
# Program Data Updater
|
||||
Remove-Item -Path "$tasksPath\Microsoft\Windows\Application Experience\ProgramDataUpdater" -Force -ErrorAction SilentlyContinue
|
||||
|
||||
Write-Host 'Deleting Application Compatibility Appraiser'
|
||||
reg delete "HKEY_LOCAL_MACHINE\zSOFTWARE\Microsoft\Windows NT\CurrentVersion\Schedule\TaskCache\Tasks\{0600DD45-FAF2-4131-A006-0B17509B9F78}" /f | Out-Null
|
||||
Write-Host 'Deleting Customer Experience Improvement Program'
|
||||
reg delete "HKEY_LOCAL_MACHINE\zSOFTWARE\Microsoft\Windows NT\CurrentVersion\Schedule\TaskCache\Tasks\{4738DE7A-BCC1-4E2D-B1B0-CADB044BFA81}" /f | Out-Null
|
||||
reg delete "HKEY_LOCAL_MACHINE\zSOFTWARE\Microsoft\Windows NT\CurrentVersion\Schedule\TaskCache\Tasks\{6FAC31FA-4A85-4E64-BFD5-2154FF4594B3}" /f | Out-Null
|
||||
reg delete "HKEY_LOCAL_MACHINE\zSOFTWARE\Microsoft\Windows NT\CurrentVersion\Schedule\TaskCache\Tasks\{FC931F16-B50A-472E-B061-B6F79A71EF59}" /f | Out-Null
|
||||
Write-Host 'Deleting Program Data Updater'
|
||||
reg delete "HKEY_LOCAL_MACHINE\zSOFTWARE\Microsoft\Windows NT\CurrentVersion\Schedule\TaskCache\Tasks\{0671EB05-7D95-4153-A32B-1426B9FE61DB}" /f | Out-Null
|
||||
Write-Host 'Deleting autochk proxy'
|
||||
reg delete "HKEY_LOCAL_MACHINE\zSOFTWARE\Microsoft\Windows NT\CurrentVersion\Schedule\TaskCache\Tasks\{87BF85F4-2CE1-4160-96EA-52F554AA28A2}" /f | Out-Null
|
||||
reg delete "HKEY_LOCAL_MACHINE\zSOFTWARE\Microsoft\Windows NT\CurrentVersion\Schedule\TaskCache\Tasks\{8A9C643C-3D74-4099-B6BD-9C6D170898B1}" /f | Out-Null
|
||||
Write-Host 'Deleting QueueReporting'
|
||||
reg delete "HKEY_LOCAL_MACHINE\zSOFTWARE\Microsoft\Windows NT\CurrentVersion\Schedule\TaskCache\Tasks\{E3176A65-4E44-4ED3-AA73-3283660ACB9C}" /f | Out-Null
|
||||
Write-Host "Tweaking complete!"
|
||||
# Chkdsk Proxy
|
||||
Remove-Item -Path "$tasksPath\Microsoft\Windows\Chkdsk\Proxy" -Force -ErrorAction SilentlyContinue
|
||||
|
||||
# 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..."
|
||||
$regKey.Close()
|
||||
reg unload HKLM\zCOMPONENTS | Out-Null
|
||||
reg unload HKLM\zDRIVERS | Out-Null
|
||||
reg unload HKLM\zDEFAULT | Out-Null
|
||||
reg unload HKLM\zNTUSER | Out-Null
|
||||
reg unload HKLM\zSCHEMA | Out-Null
|
||||
reg unload HKLM\zSOFTWARE
|
||||
reg unload HKLM\zSOFTWARE | Out-Null
|
||||
reg unload HKLM\zSYSTEM | Out-Null
|
||||
Write-Host "Cleaning up image..."
|
||||
Repair-WindowsImage -Path $ScratchDisk\scratchdir -StartComponentCleanup -ResetBase
|
||||
@@ -388,8 +274,7 @@ Write-Host ' '
|
||||
Write-Host "Unmounting image..."
|
||||
Dismount-WindowsImage -Path $ScratchDisk\scratchdir -Save
|
||||
Write-Host "Exporting image..."
|
||||
# Compressiontype Recovery is not supported with PShell https://learn.microsoft.com/en-us/powershell/module/dism/export-windowsimage?view=windowsserver2022-ps#-compressiontype
|
||||
Export-WindowsImage -SourceImagePath $ScratchDisk\tiny11\sources\install.wim -SourceIndex $index -DestinationImagePath $ScratchDisk\tiny11\sources\install2.wim -CompressionType Fast
|
||||
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-Host "Windows image completed. Continuing with boot.wim."
|
||||
@@ -420,14 +305,10 @@ Write-Host "Bypassing system requirements(on the setup image):"
|
||||
& 'reg' 'add' 'HKLM\zSYSTEM\Setup\MoSetup' '/v' 'AllowUpgradesWithUnsupportedTPMOrCPU' '/t' 'REG_DWORD' '/d' '1' '/f' | Out-Null
|
||||
Write-Host "Tweaking complete!"
|
||||
Write-Host "Unmounting Registry..."
|
||||
$regKey.Close()
|
||||
reg unload HKLM\zCOMPONENTS | Out-Null
|
||||
reg unload HKLM\zDRIVERS | Out-Null
|
||||
reg unload HKLM\zDEFAULT | Out-Null
|
||||
reg unload HKLM\zNTUSER | Out-Null
|
||||
reg unload HKLM\zSCHEMA | Out-Null
|
||||
$regKey.Close()
|
||||
reg unload HKLM\zSOFTWARE
|
||||
reg unload HKLM\zSOFTWARE | Out-Null
|
||||
reg unload HKLM\zSYSTEM | Out-Null
|
||||
Write-Host "Unmounting image..."
|
||||
Dismount-WindowsImage -Path $ScratchDisk\scratchdir -Save
|
||||
|
Reference in New Issue
Block a user