Support for non-English operating systems + bug fixes

- Fixed issues with the script when the operating system language is not English
- Permission issues resolved
This commit is contained in:
Tinnitus97 2025-09-13 23:33:19 +02:00
parent 00e7d8a151
commit f508efac39
2 changed files with 533 additions and 566 deletions

View file

@ -1,17 +1,20 @@
if ((Get-ExecutionPolicy) -eq 'Restricted') {
Write-Host "Your current PowerShell Execution Policy is set to Restricted, which prevents scripts from running. Do you want to change it to RemoteSigned? (yes/no)"
$response = Read-Host
if ($response -eq 'yes') {
Set-ExecutionPolicy RemoteSigned -Scope CurrentUser -Confirm:$false
} else {
Write-Host "The script cannot be run without changing the execution policy. Exiting..."
exit
}
}
<#
.WICHTIGER HINWEIS ZUR SICHERHEITSWARNUNG
Wenn PowerShell eine Sicherheitswarnung anzeigt ("Führen Sie ausschließlich vertrauenswürdige Skripts aus..."),
liegt das daran, dass die Datei aus dem Internet heruntergeladen wurde. Das ist ein Schutzmechanismus von Windows.
UM DIESE WARNUNG DAUERHAFT ZU ENTFERNEN, führen Sie einmalig diesen Befehl in einem PowerShell-Fenster aus:
Unblock-File -Path "PFAD\ZU\DIESER\DATEI\tiny11Coremaker_fixed.ps1"
(Ersetzen Sie "PFAD\ZU\DIESER\DATEI" mit dem tatsächlichen Pfad auf Ihrem Computer.)
Danach wird das Skript ohne Warnung starten.
#>
# --- Automatic Execution Policy Fix ---
# This command temporarily allows the script to run in the current session without manual confirmation.
Set-ExecutionPolicy Bypass -Scope Process -Force
# Check and run the script as admin if required
$adminSID = New-Object System.Security.Principal.SecurityIdentifier("S-1-5-32-544")
$adminGroup = $adminSID.Translate([System.Security.Principal.NTAccount])
$myWindowsID=[System.Security.Principal.WindowsIdentity]::GetCurrent()
$myWindowsPrincipal=new-object System.Security.Principal.WindowsPrincipal($myWindowsID)
$adminRole=[System.Security.Principal.WindowsBuiltInRole]::Administrator
@ -19,11 +22,43 @@ if (! $myWindowsPrincipal.IsInRole($adminRole))
{
Write-Host "Restarting Tiny11 image creator as admin in a new window, you can close this one."
$newProcess = new-object System.Diagnostics.ProcessStartInfo "PowerShell";
$newProcess.Arguments = $myInvocation.MyCommand.Definition;
$newProcess.Arguments = "-File `"$($myInvocation.MyCommand.Definition)`""
$newProcess.Verb = "runas";
[System.Diagnostics.Process]::Start($newProcess);
exit
}
# Get the Administrators group in a language-independent way
$adminGroupSid = New-Object System.Security.Principal.SecurityIdentifier([System.Security.Principal.WellKnownSidType]::BuiltinAdministratorsSid, $null)
$adminGroup = $adminGroupSid.Translate([System.Security.Principal.NTAccount])
# --- Functions ---
function Set-ItemOwnershipAndAccess {
param(
[string]$Path,
[switch]$Recurse
)
if (-not (Test-Path $Path)) {
Write-Warning "Path not found: $Path"
return
}
Write-Host "Taking ownership and setting permissions for: $Path"
try {
$acl = Get-Acl $Path
$acl.SetOwner($adminGroup)
if ($Recurse) {
$rule = New-Object System.Security.AccessControl.FileSystemAccessRule($adminGroup, [System.Security.AccessControl.FileSystemRights]::FullControl, "ContainerInherit, ObjectInherit", "None", "Allow")
} else {
$rule = New-Object System.Security.AccessControl.FileSystemAccessRule($adminGroup, [System.Security.AccessControl.FileSystemRights]::FullControl, "Allow")
}
$acl.AddAccessRule($rule)
Set-Acl -Path $Path -AclObject $acl
Write-Host " - Success."
} catch {
Write-Error "Error processing '$Path': $_"
}
}
Start-Transcript -Path "$PSScriptRoot\tiny11.log"
# Ask the user for input
Write-Host "Welcome to tiny11 core builder! BETA 09-05-25"
@ -31,7 +66,7 @@ Write-Host "This script generates a significantly reduced Windows 11 image. Howe
Write-Host "Do you want to continue? (y/n)"
$input = Read-Host
if ($input -eq 'y') {
if ($input.ToLower() -eq 'y') {
Write-Host "Off we go..."
Start-Sleep -Seconds 3
Clear-Host
@ -69,8 +104,9 @@ Write-Host "Getting image information:"
$index = Read-Host "Please enter the image index"
Write-Host "Mounting Windows image. This may take a while."
$wimFilePath = "$($env:SystemDrive)\tiny11\sources\install.wim"
& takeown "/F" $wimFilePath
& icacls $wimFilePath "/grant" "$($adminGroup.Value):(F)"
Set-ItemOwnershipAndAccess -Path $wimFilePath
try {
Set-ItemProperty -Path $wimFilePath -Name IsReadOnly -Value $false -ErrorAction Stop
} catch {
@ -95,7 +131,6 @@ $lines = $imageInfo -split '\r?\n'
foreach ($line in $lines) {
if ($line -like '*Architecture : *') {
$architecture = $line -replace 'Architecture : ',''
# If the architecture is x64, replace it with amd64
if ($architecture -eq 'x64') {
$architecture = 'amd64'
}
@ -145,175 +180,98 @@ $packagePatterns = @(
"Microsoft-Windows-WordPad-FoD-Package~",
"Microsoft-Windows-TabletPCMath-Package~",
"Microsoft-Windows-StepsRecorder-Package~"
)
# Get all packages
$allPackages = & dism /image:$scratchDir /Get-Packages /Format:Table
$allPackages = $allPackages -split "`n" | Select-Object -Skip 1
foreach ($packagePattern in $packagePatterns) {
# Filter the packages to remove
$packagesToRemove = $allPackages | Where-Object { $_ -like "$packagePattern*" }
foreach ($package in $packagesToRemove) {
# Extract the package identity
$packageIdentity = ($package -split "\s+")[0]
Write-Host "Removing $packageIdentity..."
& dism /image:$scratchDir /Remove-Package /PackageName:$packageIdentity
}
}
Write-Host "Do you want to enable .NET 3.5? This cannot be done after the image has been created! (y/n)"
$input = Read-Host
$inputNet = Read-Host
if ($input -eq 'y') {
if ($inputNet.ToLower() -eq 'y') {
Write-Host "Enabling .NET 3.5..."
& 'dism' "/image:$scratchDir" '/enable-feature' '/featurename:NetFX3' '/All' "/source:$($env:SystemDrive)\tiny11\sources\sxs"
Write-Host ".NET 3.5 has been enabled."
}
elseif ($input -eq 'n') {
else {
Write-Host "You chose not to enable .NET 3.5. Continuing..."
}
else {
Write-Host "Invalid input. Please enter 'y' to enable .NET 3.5 or 'n' to continue without installing .net 3.5."
}
Write-Host "Removing Edge:"
Remove-Item -Path "$mainOSDrive\scratchdir\Program Files (x86)\Microsoft\Edge" -Recurse -Force >null
Remove-Item -Path "$mainOSDrive\scratchdir\Program Files (x86)\Microsoft\EdgeUpdate" -Recurse -Force >null
Remove-Item -Path "$mainOSDrive\scratchdir\Program Files (x86)\Microsoft\EdgeCore" -Recurse -Force >null
if ($architecture -eq 'amd64') {
$folderPath = Get-ChildItem -Path "$mainOSDrive\scratchdir\Windows\WinSxS" -Filter "amd64_microsoft-edge-webview_31bf3856ad364e35*" -Directory | Select-Object -ExpandProperty FullName
if ($folderPath) {
& 'takeown' '/f' $folderPath '/r' >null
& icacls $folderPath "/grant" "$($adminGroup.Value):(F)" '/T' '/C' >null
Remove-Item -Path $folderPath -Recurse -Force >null
} else {
Write-Host "Folder not found."
}
} elseif ($architecture -eq 'arm64') {
$folderPath = Get-ChildItem -Path "$mainOSDrive\scratchdir\Windows\WinSxS" -Filter "arm64_microsoft-edge-webview_31bf3856ad364e35*" -Directory | Select-Object -ExpandProperty FullName >null
$edgeWebViewPathSystem32 = "$mainOSDrive\scratchdir\Windows\System32\Microsoft-Edge-Webview"
if ($folderPath) {
& 'takeown' '/f' $folderPath '/r'>null
& icacls $folderPath "/grant" "$($adminGroup.Value):(F)" '/T' '/C' >null
Remove-Item -Path $folderPath -Recurse -Force >null
} else {
Write-Host "Folder not found."
# FIX: Robustly delete Edge folders from WinSxS and System32
$emptyDirForEdge = Join-Path -Path $scratchDir -ChildPath "empty_edge_delete"
New-Item -Path $emptyDirForEdge -ItemType Directory -Force | Out-Null
$edgeFilter = switch ($architecture) {
'amd64' { "amd64_microsoft-edge-webview_31bf3856ad364e35*" }
'arm64' { "arm64_microsoft-edge-webview_31bf3856ad364e35*" }
default { Write-Host "Unknown architecture: $architecture"; return }
}
$edgeFoldersInWinSxS = Get-ChildItem -Path "$mainOSDrive\scratchdir\Windows\WinSxS" -Filter $edgeFilter -Directory
if ($edgeFoldersInWinSxS) {
foreach ($folder in $edgeFoldersInWinSxS) {
Write-Host "Force-deleting Edge folder: $($folder.FullName)"
Set-ItemOwnershipAndAccess -Path $folder.FullName -Recurse
& robocopy $emptyDirForEdge $folder.FullName /MIR /R:0 /W:0 | Out-Null
Remove-Item -Path $folder.FullName -Recurse -Force
}
} else {
Write-Host "Unknown architecture: $architecture"
Write-Host "Edge WebView folder not found in WinSxS."
}
& 'takeown' '/f' "$mainOSDrive\scratchdir\Windows\System32\Microsoft-Edge-Webview" '/r'
& 'icacls' "$mainOSDrive\scratchdir\Windows\System32\Microsoft-Edge-Webview" '/grant' "$($adminGroup.Value):(F)" '/T' '/C'
Remove-Item -Path "$mainOSDrive\scratchdir\Windows\System32\Microsoft-Edge-Webview" -Recurse -Force
if (Test-Path $edgeWebViewPathSystem32) {
Write-Host "Force-deleting Edge folder: $edgeWebViewPathSystem32"
Set-ItemOwnershipAndAccess -Path $edgeWebViewPathSystem32 -Recurse
& robocopy $emptyDirForEdge $edgeWebViewPathSystem32 /MIR /R:0 /W:0 | Out-Null
Remove-Item -Path $edgeWebViewPathSystem32 -Recurse -Force
}
Remove-Item -Path $emptyDirForEdge -Recurse -Force
Write-Host "Removing WinRE"
& 'takeown' '/f' "$mainOSDrive\scratchdir\Windows\System32\Recovery" '/r'
& 'icacls' "$mainOSDrive\scratchdir\Windows\System32\Recovery" '/grant' 'Administrators:F' '/T' '/C'
Remove-Item -Path "$mainOSDrive\scratchdir\Windows\System32\Recovery\winre.wim" -Recurse -Force
New-Item -Path "$mainOSDrive\scratchdir\Windows\System32\Recovery\winre.wim" -ItemType File -Force
$recoveryPath = "$mainOSDrive\scratchdir\Windows\System32\Recovery"
Set-ItemOwnershipAndAccess -Path $recoveryPath -Recurse
Remove-Item -Path "$recoveryPath\winre.wim" -Recurse -Force
New-Item -Path "$recoveryPath\winre.wim" -ItemType File -Force > $null
Write-Host "Removing OneDrive:"
& 'takeown' '/f' "$mainOSDrive\scratchdir\Windows\System32\OneDriveSetup.exe" >null
& 'icacls' "$mainOSDrive\scratchdir\Windows\System32\OneDriveSetup.exe" '/grant' "$($adminGroup.Value):(F)" '/T' '/C' >null
Remove-Item -Path "$mainOSDrive\scratchdir\Windows\System32\OneDriveSetup.exe" -Force >null
$oneDrivePath = "$mainOSDrive\scratchdir\Windows\System32\OneDriveSetup.exe"
Set-ItemOwnershipAndAccess -Path $oneDrivePath
Remove-Item -Path $oneDrivePath -Force >null
Write-Host "Removal complete!"
Start-Sleep -Seconds 2
Clear-Host
Write-Host "Taking ownership of the WinSxS folder. This might take a while..."
& 'takeown' '/f' "$mainOSDrive\scratchdir\Windows\WinSxS" '/r'
& 'icacls' "$mainOSDrive\scratchdir\Windows\WinSxS" '/grant' "$($adminGroup.Value):(F)" '/T' '/C'
Set-ItemOwnershipAndAccess -Path "$mainOSDrive\scratchdir\Windows\WinSxS" -Recurse
Write-host "Complete!"
Start-Sleep -Seconds 2
Clear-Host
Write-Host "Preparing..."
$folderPath = Join-Path -Path $mainOSDrive -ChildPath "\scratchdir\Windows\WinSxS_edit"
$sourceDirectory = "$mainOSDrive\scratchdir\Windows\WinSxS"
$destinationDirectory = "$mainOSDrive\scratchdir\Windows\WinSxS_edit"
New-Item -Path $folderPath -ItemType Directory
if ($architecture -eq "amd64") {
$dirsToCopy = @(
"x86_microsoft.windows.common-controls_6595b64144ccf1df_*",
"x86_microsoft.windows.gdiplus_6595b64144ccf1df_*",
"x86_microsoft.windows.i..utomation.proxystub_6595b64144ccf1df_*",
"x86_microsoft.windows.isolationautomation_6595b64144ccf1df_*",
"x86_microsoft-windows-s..ngstack-onecorebase_31bf3856ad364e35_*",
"x86_microsoft-windows-s..stack-termsrv-extra_31bf3856ad364e35_*",
"x86_microsoft-windows-servicingstack_31bf3856ad364e35_*",
"x86_microsoft-windows-servicingstack-inetsrv_*",
"x86_microsoft-windows-servicingstack-onecore_*",
"amd64_microsoft.vc80.crt_1fc8b3b9a1e18e3b_*",
"amd64_microsoft.vc90.crt_1fc8b3b9a1e18e3b_*",
"amd64_microsoft.windows.c..-controls.resources_6595b64144ccf1df_*",
"amd64_microsoft.windows.common-controls_6595b64144ccf1df_*",
"amd64_microsoft.windows.gdiplus_6595b64144ccf1df_*",
"amd64_microsoft.windows.i..utomation.proxystub_6595b64144ccf1df_*",
"amd64_microsoft.windows.isolationautomation_6595b64144ccf1df_*",
"amd64_microsoft-windows-s..stack-inetsrv-extra_31bf3856ad364e35_*",
"amd64_microsoft-windows-s..stack-msg.resources_31bf3856ad364e35_*",
"amd64_microsoft-windows-s..stack-termsrv-extra_31bf3856ad364e35_*",
"amd64_microsoft-windows-servicingstack_31bf3856ad364e35_*",
"amd64_microsoft-windows-servicingstack-inetsrv_31bf3856ad364e35_*",
"amd64_microsoft-windows-servicingstack-msg_31bf3856ad364e35_*",
"amd64_microsoft-windows-servicingstack-onecore_31bf3856ad364e35_*",
"Catalogs",
"FileMaps",
"Fusion",
"InstallTemp",
"Manifests",
"x86_microsoft.vc80.crt_1fc8b3b9a1e18e3b_*",
"x86_microsoft.vc90.crt_1fc8b3b9a1e18e3b_*",
"x86_microsoft.windows.c..-controls.resources_6595b64144ccf1df_*",
"x86_microsoft.windows.c..-controls.resources_6595b64144ccf1df_*"
)
# Copy each directory
foreach ($dir in $dirsToCopy) {
$sourceDirs = Get-ChildItem -Path $sourceDirectory -Filter $dir -Directory
foreach ($sourceDir in $sourceDirs) {
$destDir = Join-Path -Path $destinationDirectory -ChildPath $sourceDir.Name
Write-Host "Copying $sourceDir.FullName to $destDir"
Copy-Item -Path $sourceDir.FullName -Destination $destDir -Recurse -Force
}
}
}
elseif ($architecture -eq "arm64") {
# Specify the list of files to copy
$dirsToCopy = @(
"arm64_microsoft-windows-servicingstack-onecore_31bf3856ad364e35_*",
"Catalogs"
"FileMaps"
"Fusion"
"InstallTemp"
"Manifests"
"SettingsManifests"
"Temp"
"x86_microsoft.vc80.crt_1fc8b3b9a1e18e3b_*"
"x86_microsoft.vc90.crt_1fc8b3b9a1e18e3b_*"
"x86_microsoft.windows.c..-controls.resources_6595b64144ccf1df_*"
"x86_microsoft.windows.common-controls_6595b64144ccf1df_*"
"x86_microsoft.windows.gdiplus_6595b64144ccf1df_*"
"x86_microsoft.windows.i..utomation.proxystub_6595b64144ccf1df_*"
"x86_microsoft.windows.isolationautomation_6595b64144ccf1df_*"
"arm_microsoft.windows.c..-controls.resources_6595b64144ccf1df_*"
"arm_microsoft.windows.common-controls_6595b64144ccf1df_*"
"arm_microsoft.windows.gdiplus_6595b64144ccf1df_*"
"arm_microsoft.windows.i..utomation.proxystub_6595b64144ccf1df_*"
"arm_microsoft.windows.isolationautomation_6595b64144ccf1df_*"
"arm64_microsoft.vc80.crt_1fc8b3b9a1e18e3b_*"
"arm64_microsoft.vc90.crt_1fc8b3b9a1e18e3b_*"
"arm64_microsoft.windows.c..-controls.resources_6595b64144ccf1df_*"
"arm64_microsoft.windows.common-controls_6595b64144ccf1df_*"
"arm64_microsoft.windows.gdiplus_6595b64144ccf1df_*"
"arm64_microsoft.windows.i..utomation.proxystub_6595b64144ccf1df_*"
"arm64_microsoft.windows.isolationautomation_6595b64144ccf1df_*"
"arm64_microsoft-windows-servicing-adm_31bf3856ad364e35_*"
"arm64_microsoft-windows-servicingcommon_31bf3856ad364e35_*"
"arm64_microsoft-windows-servicing-onecore-uapi_31bf3856ad364e35_*"
"arm64_microsoft-windows-servicingstack_31bf3856ad364e35_*"
"arm64_microsoft-windows-servicingstack-inetsrv_31bf3856ad364e35_*"
"arm64_microsoft-windows-servicingstack-msg_31bf3856ad364e35_*"
)
$dirsToCopy = @( "x86_microsoft.windows.common-controls_6595b64144ccf1df_*", "x86_microsoft.windows.gdiplus_6595b64144ccf1df_*", "x86_microsoft.windows.i..utomation.proxystub_6595b64144ccf1df_*", "x86_microsoft.windows.isolationautomation_6595b64144ccf1df_*", "x86_microsoft-windows-s..ngstack-onecorebase_31bf3856ad364e35_*", "x86_microsoft-windows-s..stack-termsrv-extra_31bf3856ad364e35_*", "x86_microsoft-windows-servicingstack_31bf3856ad364e35_*", "x86_microsoft-windows-servicingstack-inetsrv_*", "x86_microsoft-windows-servicingstack-onecore_*", "amd64_microsoft.vc80.crt_1fc8b3b9a1e18e3b_*", "amd64_microsoft.vc90.crt_1fc8b3b9a1e18e3b_*", "amd64_microsoft.windows.c..-controls.resources_6595b64144ccf1df_*", "amd64_microsoft.windows.common-controls_6595b64144ccf1df_*", "amd64_microsoft.windows.gdiplus_6595b64144ccf1df_*", "amd64_microsoft.windows.i..utomation.proxystub_6595b64144ccf1df_*", "amd64_microsoft.windows.isolationautomation_6595b64144ccf1df_*", "amd64_microsoft-windows-s..stack-inetsrv-extra_31bf3856ad364e35_*", "amd64_microsoft-windows-s..stack-msg.resources_31bf3856ad364e35_*", "amd64_microsoft-windows-s..stack-termsrv-extra_31bf3856ad364e35_*", "amd64_microsoft-windows-servicingstack_31bf3856ad364e35_*", "amd64_microsoft-windows-servicingstack-inetsrv_31bf3856ad364e35_*", "amd64_microsoft-windows-servicingstack-msg_31bf3856ad364e35_*", "amd64_microsoft-windows-servicingstack-onecore_31bf3856ad364e35_*", "Catalogs", "FileMaps", "Fusion", "InstallTemp", "Manifests", "x86_microsoft.vc80.crt_1fc8b3b9a1e18e3b_*", "x86_microsoft.vc90.crt_1fc8b3b9a1e18e3b_*", "x86_microsoft.windows.c..-controls.resources_6595b64144ccf1df_*", "x86_microsoft.windows.c..-controls.resources_6595b64144ccf1df_*" )
} elseif ($architecture -eq "arm64") {
$dirsToCopy = @( "arm64_microsoft-windows-servicingstack-onecore_31bf3856ad364e35_*", "Catalogs", "FileMaps", "Fusion", "InstallTemp", "Manifests", "SettingsManifests", "Temp", "x86_microsoft.vc80.crt_1fc8b3b9a1e18e3b_*", "x86_microsoft.vc90.crt_1fc8b3b9a1e18e3b_*", "x86_microsoft.windows.c..-controls.resources_6595b64144ccf1df_*", "x86_microsoft.windows.common-controls_6595b64144ccf1df_*", "x86_microsoft.windows.gdiplus_6595b64144ccf1df_*", "x86_microsoft.windows.i..utomation.proxystub_6595b64144ccf1df_*", "x86_microsoft.windows.isolationautomation_6595b64144ccf1df_*", "arm_microsoft.windows.c..-controls.resources_6595b64144ccf1df_*", "arm_microsoft.windows.common-controls_6595b64144ccf1df_*", "arm_microsoft.windows.gdiplus_6595b64144ccf1df_*", "arm_microsoft.windows.i..utomation.proxystub_6595b64144ccf1df_*", "arm_microsoft.windows.isolationautomation_6595b64144ccf1df_*", "arm64_microsoft.vc80.crt_1fc8b3b9a1e18e3b_*", "arm64_microsoft.vc90.crt_1fc8b3b9a1e18e3b_*", "arm64_microsoft.windows.c..-controls.resources_6595b64144ccf1df_*", "arm64_microsoft.windows.common-controls_6595b64144ccf1df_*", "arm64_microsoft.windows.gdiplus_6595b64144ccf1df_*", "arm64_microsoft.windows.i..utomation.proxystub_6595b64144ccf1df_*", "arm64_microsoft.windows.isolationautomation_6595b64144ccf1df_*", "arm64_microsoft-windows-servicing-adm_31bf3856ad364e35_*", "arm64_microsoft-windows-servicingcommon_31bf3856ad364e35_*", "arm64_microsoft-windows-servicing-onecore-uapi_31bf3856ad364e35_*", "arm64_microsoft-windows-servicingstack_31bf3856ad364e35_*", "arm64_microsoft-windows-servicingstack-inetsrv_31bf3856ad364e35_*", "arm64_microsoft-windows-servicingstack-msg_31bf3856ad364e35_*" )
}
foreach ($dir in $dirsToCopy) {
$sourceDirs = Get-ChildItem -Path $sourceDirectory -Filter $dir -Directory
@ -324,11 +282,15 @@ foreach ($dir in $dirsToCopy) {
}
}
Write-Host "Deleting WinSxS. This may take a while..."
Remove-Item -Path $mainOSDrive\scratchdir\Windows\WinSxS -Recurse -Force
# FIX: Use robocopy to reliably delete the protected WinSxS folder contents.
$emptyDir = Join-Path -Path $scratchDir -ChildPath "empty_temp_for_delete"
New-Item -Path $emptyDir -ItemType Directory -Force | Out-Null
& robocopy $emptyDir "$mainOSDrive\scratchdir\Windows\WinSxS" /MIR /R:0 /W:0 | Out-Null
Remove-Item -Path "$mainOSDrive\scratchdir\Windows\WinSxS" -Recurse -Force
Remove-Item -Path $emptyDir -Recurse -Force
Rename-Item -Path $mainOSDrive\scratchdir\Windows\WinSxS_edit -NewName $mainOSDrive\scratchdir\Windows\WinSxS
Rename-Item -Path "$mainOSDrive\scratchdir\Windows\WinSxS_edit" -NewName "$mainOSDrive\scratchdir\Windows\WinSxS"
Write-Host "Complete!"
Write-Host "Loading registry..."
@ -355,22 +317,10 @@ Write-Host "Disabling Sponsored Apps:"
& 'reg' 'add' 'HKLM\zSOFTWARE\Policies\Microsoft\Windows\CloudContent' '/v' 'DisableWindowsConsumerFeatures' '/t' 'REG_DWORD' '/d' '1' '/f' | Out-Null
& 'reg' 'add' 'HKLM\zNTUSER\Software\Microsoft\Windows\CurrentVersion\ContentDeliveryManager' '/v' 'ContentDeliveryAllowed' '/t' 'REG_DWORD' '/d' '0' '/f' | Out-Null
& 'reg' 'add' 'HKLM\zSOFTWARE\Microsoft\PolicyManager\current\device\Start' '/v' 'ConfigureStartPins' '/t' 'REG_SZ' '/d' '{"pinnedList": [{}]}' '/f' | Out-Null
& 'reg' 'add' 'HKLM\zNTUSER\Software\Microsoft\Windows\CurrentVersion\ContentDeliveryManager' '/v' 'ContentDeliveryAllowed' '/t' 'REG_DWORD' '/d' '0' '/f' | Out-Null
& 'reg' 'add' 'HKLM\zNTUSER\Software\Microsoft\Windows\CurrentVersion\ContentDeliveryManager' '/v' 'ContentDeliveryAllowed' '/t' 'REG_DWORD' '/d' '0' '/f' | Out-Null
& 'reg' 'add' 'HKLM\zNTUSER\Software\Microsoft\Windows\CurrentVersion\ContentDeliveryManager' '/v' 'FeatureManagementEnabled' '/t' 'REG_DWORD' '/d' '0' '/f' | Out-Null
& 'reg' 'add' 'HKLM\zNTUSER\Software\Microsoft\Windows\CurrentVersion\ContentDeliveryManager' '/v' 'OemPreInstalledAppsEnabled' '/t' 'REG_DWORD' '/d' '0' '/f' | Out-Null
& 'reg' 'add' 'HKLM\zNTUSER\Software\Microsoft\Windows\CurrentVersion\ContentDeliveryManager' '/v' 'PreInstalledAppsEnabled' '/t' 'REG_DWORD' '/d' '0' '/f' | Out-Null
& 'reg' 'add' 'HKLM\zNTUSER\Software\Microsoft\Windows\CurrentVersion\ContentDeliveryManager' '/v' 'PreInstalledAppsEverEnabled' '/t' 'REG_DWORD' '/d' '0' '/f' | Out-Null
& 'reg' 'add' 'HKLM\zNTUSER\Software\Microsoft\Windows\CurrentVersion\ContentDeliveryManager' '/v' 'SilentInstalledAppsEnabled' '/t' 'REG_DWORD' '/d' '0' '/f' | Out-Null
& 'reg' 'add' 'HKLM\zNTUSER\Software\Microsoft\Windows\CurrentVersion\ContentDeliveryManager' '/v' 'SoftLandingEnabled' '/t' 'REG_DWORD' '/d' '0' '/f'| Out-Null
& 'reg' 'add' 'HKLM\zNTUSER\Software\Microsoft\Windows\CurrentVersion\ContentDeliveryManager' '/v' 'SubscribedContentEnabled' '/t' 'REG_DWORD' '/d' '0' '/f' | Out-Null
& 'reg' 'add' 'HKLM\zNTUSER\Software\Microsoft\Windows\CurrentVersion\ContentDeliveryManager' '/v' 'SubscribedContent-310093Enabled' '/t' 'REG_DWORD' '/d' '0' '/f' | Out-Null
& 'reg' 'add' 'HKLM\zNTUSER\Software\Microsoft\Windows\CurrentVersion\ContentDeliveryManager' '/v' 'SubscribedContent-338388Enabled' '/t' 'REG_DWORD' '/d' '0' '/f' | Out-Null
& 'reg' 'add' 'HKLM\zNTUSER\Software\Microsoft\Windows\CurrentVersion\ContentDeliveryManager' '/v' 'SubscribedContent-338389Enabled' '/t' 'REG_DWORD' '/d' '0' '/f' | Out-Null
& 'reg' 'add' 'HKLM\zNTUSER\Software\Microsoft\Windows\CurrentVersion\ContentDeliveryManager' '/v' 'SubscribedContent-338393Enabled' '/t' 'REG_DWORD' '/d' '0' '/f' | Out-Null
& 'reg' 'add' 'HKLM\zNTUSER\Software\Microsoft\Windows\CurrentVersion\ContentDeliveryManager' '/v' 'SubscribedContent-353694Enabled' '/t' 'REG_DWORD' '/d' '0' '/f' | Out-Null
& 'reg' 'add' 'HKLM\zNTUSER\Software\Microsoft\Windows\CurrentVersion\ContentDeliveryManager' '/v' 'SubscribedContent-353696Enabled' '/t' 'REG_DWORD' '/d' '0' '/f' | Out-Null
& 'reg' 'add' 'HKLM\zNTUSER\Software\Microsoft\Windows\CurrentVersion\ContentDeliveryManager' '/v' 'SubscribedContentEnabled' '/t' 'REG_DWORD' '/d' '0' '/f' | Out-Null
& 'reg' 'add' 'HKLM\zNTUSER\Software\Microsoft\Windows\CurrentVersion\ContentDeliveryManager' '/v' 'SystemPaneSuggestionsEnabled' '/t' 'REG_DWORD' '/d' '0' '/f' | Out-Null
& 'reg' 'add' 'HKLM\zSOFTWARE\Policies\Microsoft\PushToInstall' '/v' 'DisablePushToInstall' '/t' 'REG_DWORD' '/d' '1' '/f' | Out-Null
& 'reg' 'add' 'HKLM\zSOFTWARE\Policies\Microsoft\MRT' '/v' 'DontOfferThroughWUAU' '/t' 'REG_DWORD' '/d' '1' '/f' | Out-Null
@ -417,23 +367,14 @@ 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"
$tasksPath = "$mainOSDrive\scratchdir\Windows\System32\Tasks"
Write-Host "Deleting scheduled task definition files..."
# Application Compatibility Appraiser
Remove-Item -Path "$tasksPath\Microsoft\Windows\Application Experience\Microsoft Compatibility Appraiser" -Force -ErrorAction SilentlyContinue
# 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
# Program Data Updater
Remove-Item -Path "$tasksPath\Microsoft\Windows\Application Experience\ProgramDataUpdater" -Force -ErrorAction SilentlyContinue
# 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."
@ -455,15 +396,7 @@ Write-Host "Disabling Windows Update..."
& 'reg' 'delete' 'HKLM\zSYSTEM\ControlSet001\Services\UsoSvc' '/f'
& 'reg' 'add' 'HKEY_LOCAL_MACHINE\zSOFTWARE\Policies\Microsoft\Windows\WindowsUpdate\AU' '/v' 'NoAutoUpdate' '/t' 'REG_DWORD' '/d' '1' '/f'
Write-Host "Disabling Windows Defender"
# Set registry values for Windows Defender services
$servicePaths = @(
"WinDefend",
"WdNisSvc",
"WdNisDrv",
"WdFilter",
"Sense"
)
$servicePaths = @( "WinDefend", "WdNisSvc", "WdNisDrv", "WdFilter", "Sense" )
foreach ($path in $servicePaths) {
Set-ItemProperty -Path "HKLM:\zSYSTEM\ControlSet001\Services\$path" -Name "Start" -Value 4
}
@ -489,17 +422,16 @@ Write-Host "Windows image completed. Continuing with boot.wim."
Start-Sleep -Seconds 2
Clear-Host
Write-Host "Mounting boot image:"
$wimFilePath = "$($env:SystemDrive)\tiny11\sources\boot.wim"
& takeown "/F" $wimFilePath >null
& icacls $wimFilePath "/grant" "$($adminGroup.Value):(F)"
Set-ItemProperty -Path $wimFilePath -Name IsReadOnly -Value $false
$bootWimPath = "$($env:SystemDrive)\tiny11\sources\boot.wim"
Set-ItemOwnershipAndAccess -Path $bootWimPath
Set-ItemProperty -Path $bootWimPath -Name IsReadOnly -Value $false
& 'dism' '/English' '/mount-image' "/imagefile:$mainOSDrive\tiny11\sources\boot.wim" '/index:2' "/mountdir:$mainOSDrive\scratchdir"
Write-Host "Loading registry..."
reg load HKLM\zCOMPONENTS $mainOSDrive\scratchdir\Windows\System32\config\COMPONENTS
reg load HKLM\zDEFAULT $mainOSDrive\scratchdir\Windows\System32\config\default
reg load HKLM\zNTUSER $mainOSDrive\scratchdir\Users\Default\ntuser.dat
reg load HKLM\zSOFTWARE $mainOSDrive\scratchdir\Windows\System32\config\SOFTWARE
reg load HKLM\zSYSTEM $mainOSDrive\scratchdir\Windows\System32\config\SYSTEM
reg load HKLM\zCOMPONENTS $mainOSDrive\scratchdir\Windows\System32\config\COMPONENTS | Out-Null
reg load HKLM\zDEFAULT $mainOSDrive\scratchdir\Windows\System32\config\default | Out-Null
reg load HKLM\zNTUSER $mainOSDrive\scratchdir\Users\Default\ntuser.dat | Out-Null
reg load HKLM\zSOFTWARE $mainOSDrive\scratchdir\Windows\System32\config\SOFTWARE | Out-Null
reg load HKLM\zSYSTEM $mainOSDrive\scratchdir\Windows\System32\config\SYSTEM | Out-Null
Write-Host "Bypassing system requirements(on the setup image):"
& 'reg' 'add' 'HKLM\zDEFAULT\Control Panel\UnsupportedHardwareNotificationCache' '/v' 'SV1' '/t' 'REG_DWORD' '/d' '0' '/f' >null
& 'reg' 'add' 'HKLM\zDEFAULT\Control Panel\UnsupportedHardwareNotificationCache' '/v' 'SV2' '/t' 'REG_DWORD' '/d' '0' '/f' >null
@ -535,8 +467,6 @@ if ([System.IO.Directory]::Exists($ADKDepTools)) {
$OSCDIMG = "$ADKDepTools\oscdimg.exe"
} else {
Write-Host "ADK folder not found. Will be using bundled oscdimg.exe."
$url = "https://msdl.microsoft.com/download/symbols/oscdimg.exe/3D44737265000/oscdimg.exe"
if (-not (Test-Path -Path $localOSCDIMGPath)) {
@ -552,11 +482,10 @@ if ([System.IO.Directory]::Exists($ADKDepTools)) {
} else {
Write-Host "oscdimg.exe already exists locally."
}
$OSCDIMG = $localOSCDIMGPath
}
& "$OSCDIMG" '-m' '-o' '-u2' '-udfver102' "-bootdata:2#p0,e,b$ScratchDisk\tiny11\boot\etfsboot.com#pEF,e,b$ScratchDisk\tiny11\efi\microsoft\boot\efisys.bin" "$ScratchDisk\tiny11" "$PSScriptRoot\tiny11.iso"
& "$OSCDIMG" '-m' '-o' '-u2' '-udfver102' "-bootdata:2#p0,e,b$mainOSDrive\tiny11\boot\etfsboot.com#pEF,e,b$mainOSDrive\tiny11\efi\microsoft\boot\efisys.bin" "$mainOSDrive\tiny11" "$PSScriptRoot\tiny11.iso"
# Finishing up
Write-Host "Creation completed! Press any key to exit the script..."
@ -567,13 +496,10 @@ Remove-Item -Path "$mainOSDrive\scratchdir" -Recurse -Force >null
# Stop the transcript
Stop-Transcript
exit
}
elseif ($input -eq 'n') {
Write-Host "You chose not to continue. The script will now exit."
exit
}
else {
Write-Host "Invalid input. Please enter 'y' to continue or 'n' to exit."
Write-Host "You chose not to continue. The script will now exit."
exit
}

View file

@ -39,7 +39,65 @@ if (-not $SCRATCH) {
$ScratchDisk = $SCRATCH + ":"
}
#---------[ Initial Checks and Setup ]---------#
# Check if PowerShell execution is restricted
if ((Get-ExecutionPolicy) -eq 'Restricted') {
Write-Output "Your current PowerShell Execution Policy is set to Restricted, which prevents scripts from running. Do you want to change it to RemoteSigned? (yes/no)"
$response = Read-Host
if ($response.ToLower() -eq 'yes') {
Set-ExecutionPolicy RemoteSigned -Scope CurrentUser -Confirm:$false
} else {
Write-Output "The script cannot be run without changing the execution policy. Exiting..."
exit
}
}
# Check and run the script as admin if required
$myWindowsID = [System.Security.Principal.WindowsIdentity]::GetCurrent()
$myWindowsPrincipal = New-Object System.Security.Principal.WindowsPrincipal($myWindowsID)
if (-not $myWindowsPrincipal.IsInRole([System.Security.Principal.WindowsBuiltInRole]::Administrator)) {
Write-Output "Restarting Tiny11 image creator as admin in a new window, you can close this one."
$newProcess = New-Object System.Diagnostics.ProcessStartInfo "PowerShell"
$newProcess.Arguments = "-File `"$($myInvocation.MyCommand.Definition)`""
$newProcess.Verb = "runas"
[System.Diagnostics.Process]::Start($newProcess)
exit
}
# Get the Administrators group in a language-independent way via its well-known SID
$adminGroupSid = New-Object System.Security.Principal.SecurityIdentifier([System.Security.Principal.WellKnownSidType]::BuiltinAdministratorsSid, $null)
$adminGroup = $adminGroupSid.Translate([System.Security.Principal.NTAccount])
#---------[ Functions ]---------#
# FIX: Language-independent function to take ownership and set permissions
function Set-ItemOwnershipAndAccess {
param(
[string]$Path,
[switch]$Recurse
)
if (-not (Test-Path $Path)) {
Write-Warning "Path not found: $Path"
return
}
Write-Host "Taking ownership and setting permissions for: $Path"
try {
$acl = Get-Acl $Path
$acl.SetOwner($adminGroup)
if ($Recurse) {
$rule = New-Object System.Security.AccessControl.FileSystemAccessRule($adminGroup, [System.Security.AccessControl.FileSystemRights]::FullControl, "ContainerInherit, ObjectInherit", "None", "Allow")
} else {
$rule = New-Object System.Security.AccessControl.FileSystemAccessRule($adminGroup, [System.Security.AccessControl.FileSystemRights]::FullControl, "Allow")
}
$acl.AddAccessRule($rule)
Set-Acl -Path $Path -AclObject $acl
Write-Host " - Success."
} catch {
Write-Error "Error processing '$Path': $_"
}
}
function Set-RegistryValue {
param (
[string]$path,
@ -68,33 +126,6 @@ function Remove-RegistryValue {
}
#---------[ Execution ]---------#
# Check if PowerShell execution is restricted
if ((Get-ExecutionPolicy) -eq 'Restricted') {
Write-Output "Your current PowerShell Execution Policy is set to Restricted, which prevents scripts from running. Do you want to change it to RemoteSigned? (yes/no)"
$response = Read-Host
if ($response -eq 'yes') {
Set-ExecutionPolicy RemoteSigned -Scope CurrentUser -Confirm:$false
} else {
Write-Output "The script cannot be run without changing the execution policy. Exiting..."
exit
}
}
# Check and run the script as admin if required
$adminSID = New-Object System.Security.Principal.SecurityIdentifier("S-1-5-32-544")
$adminGroup = $adminSID.Translate([System.Security.Principal.NTAccount])
$myWindowsID=[System.Security.Principal.WindowsIdentity]::GetCurrent()
$myWindowsPrincipal=new-object System.Security.Principal.WindowsPrincipal($myWindowsID)
$adminRole=[System.Security.Principal.WindowsBuiltInRole]::Administrator
if (! $myWindowsPrincipal.IsInRole($adminRole))
{
Write-Output "Restarting Tiny11 image creator as admin in a new window, you can close this one."
$newProcess = new-object System.Diagnostics.ProcessStartInfo "PowerShell";
$newProcess.Arguments = $myInvocation.MyCommand.Definition;
$newProcess.Verb = "runas";
[System.Diagnostics.Process]::Start($newProcess);
exit
}
if (-not (Test-Path -Path "$PSScriptRoot/autounattend.xml")) {
Invoke-RestMethod "https://raw.githubusercontent.com/ntdevlabs/tiny11builder/refs/heads/main/autounattend.xml" -OutFile "$PSScriptRoot/autounattend.xml"
@ -153,12 +184,13 @@ while ($ImagesIndex -notcontains $index) {
}
Write-Output "Mounting Windows image. This may take a while."
$wimFilePath = "$ScratchDisk\tiny11\sources\install.wim"
& takeown "/F" $wimFilePath
& icacls $wimFilePath "/grant" "$($adminGroup.Value):(F)"
# FIX: Use robust function to take ownership
Set-ItemOwnershipAndAccess -Path $wimFilePath
try {
Set-ItemProperty -Path $wimFilePath -Name IsReadOnly -Value $false -ErrorAction Stop
} catch {
# This block will catch the error and suppress it.
Write-Error "$wimFilePath not found"
}
New-Item -ItemType Directory -Force -Path "$ScratchDisk\scratchdir" > $null
@ -180,7 +212,6 @@ $lines = $imageInfo -split '\r?\n'
foreach ($line in $lines) {
if ($line -like '*Architecture : *') {
$architecture = $line -replace 'Architecture : ',''
# If the architecture is x64, replace it with amd64
if ($architecture -eq 'x64') {
$architecture = 'amd64'
}
@ -265,16 +296,27 @@ foreach ($package in $packagesToRemove) {
}
Write-Output "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
& '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
Remove-Item -Path "$ScratchDisk\scratchdir\Program Files (x86)\Microsoft\Edge" -Recurse -Force -ErrorAction SilentlyContinue
Remove-Item -Path "$ScratchDisk\scratchdir\Program Files (x86)\Microsoft\EdgeUpdate" -Recurse -Force -ErrorAction SilentlyContinue
Remove-Item -Path "$ScratchDisk\scratchdir\Program Files (x86)\Microsoft\EdgeCore" -Recurse -Force -ErrorAction SilentlyContinue
# FIX: Use robust robocopy method to delete protected Edge WebView folder
$edgeWebViewPath = "$ScratchDisk\scratchdir\Windows\System32\Microsoft-Edge-Webview"
if (Test-Path $edgeWebViewPath) {
Write-Host "Force-deleting Edge WebView folder..."
Set-ItemOwnershipAndAccess -Path $edgeWebViewPath -Recurse
$emptyDirForEdge = Join-Path -Path $ScratchDisk -ChildPath "empty_edge_delete"
New-Item -Path $emptyDirForEdge -ItemType Directory -Force | Out-Null
& robocopy $emptyDirForEdge $edgeWebViewPath /MIR /R:0 /W:0 | Out-Null
Remove-Item -Path $edgeWebViewPath -Recurse -Force
Remove-Item -Path $emptyDirForEdge -Recurse -Force
}
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
$oneDriveSetupPath = "$ScratchDisk\scratchdir\Windows\System32\OneDriveSetup.exe"
Set-ItemOwnershipAndAccess -Path $oneDriveSetupPath
Remove-Item -Path $oneDriveSetupPath -Force | Out-Null
Write-Output "Removal complete!"
Start-Sleep -Seconds 2
Clear-Host
@ -401,16 +443,18 @@ 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)"
# FIX: Use robust function to take ownership
Set-ItemOwnershipAndAccess -Path $wimFilePath
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
reg load HKLM\zNTUSER $ScratchDisk\scratchdir\Users\Default\ntuser.dat
reg load HKLM\zSOFTWARE $ScratchDisk\scratchdir\Windows\System32\config\SOFTWARE
reg load HKLM\zSYSTEM $ScratchDisk\scratchdir\Windows\System32\config\SYSTEM
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 setup image):"
Set-RegistryValue 'HKLM\zDEFAULT\Control Panel\UnsupportedHardwareNotificationCache' 'SV1' 'REG_DWORD' '0'
@ -530,6 +574,3 @@ if (Test-Path -Path "$PSScriptRoot\autounattend.xml") {
# Stop the transcript
Stop-Transcript
exit