Skip to content

Commit c58e26e

Browse files
committed
Implemet changes in various PRs against origin
1 parent af69a48 commit c58e26e

File tree

2 files changed

+92
-50
lines changed

2 files changed

+92
-50
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ You can now use it on ANY Windows 11 release (not just a specific build), as wel
1010
This is made possible thanks to the much-improved scripting capabilities of PowerShell, compared to the older Batch release.
1111
</br>
1212
Since it is written in PowerShell, you need to set the execution policy to `Unrestricted`, so that you could run the script.
13-
If you haven't done this before, make sure to run `Set-ExecutionPolicy unrestricted` as administrator in PowerShell before running the script, otherwise it would just crash.
13+
If you haven't done this before, make sure to run `Set-ExecutionPolicy -Scope Process unrestricted` as administrator in PowerShell before running the script, otherwise it would just crash.
1414

1515

1616
This is a script created to automate the build of a streamlined Windows 11 image, similar to tiny11.

tiny11maker.ps1

Lines changed: 91 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,28 @@
11
# Enable debugging
2-
#Set-PSDebug -Trace 1
2+
# Set-PSDebug -Trace 1
33

44
param (
5-
[ValidatePattern('^[c-zC-Z]$')]
5+
[ValidatePattern('^[c-zC-Z]:$')]
66
[string]$ScratchDisk
77
)
88

99
if (-not $ScratchDisk) {
10-
$ScratchDisk = $PSScriptRoot -replace '[\\]+$', ''
10+
$ScratchDisk = ((Get-Location).Drive.Name) + ":"
1111
} else {
1212
$ScratchDisk = $ScratchDisk + ":"
1313
}
1414

1515
Write-Output "Scratch disk set to $ScratchDisk"
1616

17-
# Check if PowerShell execution is restricted
18-
if ((Get-ExecutionPolicy) -eq 'Restricted') {
19-
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)"
17+
# Check if PowerShell execution is Restricted or AllSigned or Undefined
18+
$needchange = @("AllSigned", "Restricted", "Undefined")
19+
$curpolicy = Get-ExecutionPolicy
20+
if ($curpolicy -in $needchange) {
21+
Write-Host "Your current PowerShell Execution Policy is set to $curpolicy, which prevents scripts from running. Do you want to change it to RemoteSigned? (yes/no)"
2022
$response = Read-Host
2123
if ($response -eq 'yes') {
2224
Set-ExecutionPolicy RemoteSigned -Scope CurrentUser -Confirm:$false
25+
Set-ExecutionPolicy RemoteSigned -Scope Process -Confirm:$false
2326
} else {
2427
Write-Host "The script cannot be run without changing the execution policy. Exiting..."
2528
exit
@@ -32,8 +35,7 @@ $adminGroup = $adminSID.Translate([System.Security.Principal.NTAccount])
3235
$myWindowsID=[System.Security.Principal.WindowsIdentity]::GetCurrent()
3336
$myWindowsPrincipal=new-object System.Security.Principal.WindowsPrincipal($myWindowsID)
3437
$adminRole=[System.Security.Principal.WindowsBuiltInRole]::Administrator
35-
if (! $myWindowsPrincipal.IsInRole($adminRole))
36-
{
38+
if (! $myWindowsPrincipal.IsInRole($adminRole)) {
3739
Write-Host "Restarting Tiny11 image creator as admin in a new window, you can close this one."
3840
$newProcess = new-object System.Diagnostics.ProcessStartInfo "PowerShell";
3941
$newProcess.Arguments = $myInvocation.MyCommand.Definition;
@@ -42,10 +44,8 @@ if (! $myWindowsPrincipal.IsInRole($adminRole))
4244
exit
4345
}
4446

45-
46-
4747
# Start the transcript and prepare the window
48-
Start-Transcript -Path "$ScratchDisk\tiny11.log"
48+
Start-Transcript -Path "$ScratchDisk\tiny11.log"
4949

5050
$Host.UI.RawUI.WindowTitle = "Tiny11 image creator"
5151
Clear-Host
@@ -87,19 +87,26 @@ Start-Sleep -Seconds 2
8787
Clear-Host
8888
Write-Host "Getting image information:"
8989
Get-WindowsImage -ImagePath $ScratchDisk\tiny11\sources\install.wim
90-
$index = Read-Host "Please enter the image index"
90+
91+
$index = Read-Host "Please enter the image index : "
92+
$ImagesIndex = (Get-WindowsImage -ImagePath $ScratchDisk\tiny11\sources\install.wim).ImageIndex
93+
while ($ImagesIndex -notcontains $index) {
94+
$index = Read-Host "Please enter a valide image index : "
95+
}
96+
9197
Write-Host "Mounting Windows image. This may take a while."
9298
$wimFilePath = "$ScratchDisk\tiny11\sources\install.wim"
93-
& takeown "/F" $wimFilePath
99+
& takeown "/F" $wimFilePath
94100
& icacls $wimFilePath "/grant" "$($adminGroup.Value):(F)"
95101
try {
96102
Set-ItemProperty -Path $wimFilePath -Name IsReadOnly -Value $false -ErrorAction Stop
97103
} catch {
98104
# This block will catch the error and suppress it.
99105
}
100106
New-Item -ItemType Directory -Force -Path "$ScratchDisk\scratchdir" > $null
101-
Mount-WindowsImage -ImagePath $ScratchDisk\tiny11\sources\install.wim -Index $index -Path $ScratchDisk\scratchdir
107+
Mount-WindowsImage -ImagePath $wimFilePath -Index $index -Path $ScratchDisk\scratchdir
102108

109+
# Powershell dism module does not have direct equivalent for /Get-Intl
103110
$imageIntl = & dism /English /Get-Intl "/Image:$($ScratchDisk)\scratchdir"
104111
$languageLine = $imageIntl -split '\n' | Where-Object { $_ -match 'Default system UI language : ([a-zA-Z]{2}-[a-zA-Z]{2})' }
105112

@@ -110,45 +117,71 @@ if ($languageLine) {
110117
Write-Host "Default system UI language code not found."
111118
}
112119

113-
$imageInfo = & 'dism' '/English' '/Get-WimInfo' "/wimFile:$($ScratchDisk)\tiny11\sources\install.wim" "/index:$index"
114-
$lines = $imageInfo -split '\r?\n'
115-
116-
foreach ($line in $lines) {
117-
if ($line -like '*Architecture : *') {
118-
$architecture = $line -replace 'Architecture : ',''
119-
# If the architecture is x64, replace it with amd64
120-
if ($architecture -eq 'x64') {
121-
$architecture = 'amd64'
122-
}
123-
Write-Host "Architecture: $architecture"
124-
break
125-
}
120+
# Defined in (Microsoft.Dism.Commands.ImageInfoObject).Architecture formatting script
121+
# 0 -> x86, 5 -> arm(currently unused), 6 -> ia64(currently unused), 9 -> x64, 12 -> arm64
122+
switch ((Get-WindowsImage -ImagePath $wimFilePath -Index $index).Architecture)
123+
{
124+
0 { $architecture = "x86" }
125+
9 { $architecture = "amd64" }
126+
12 { $architecture = "arm64" }
126127
}
127128

128129
if (-not $architecture) {
130+
if ($architecture) {
131+
Write-Host "Architecture: $architecture"
132+
} else {
129133
Write-Host "Architecture information not found."
130134
}
131135

132-
Write-Host "Mounting complete! Performing removal of applications..."
136+
Write-Host "Mounting complete! Performing removal of applications...`n"
133137

134-
$packages = & 'dism' '/English' "/image:$($ScratchDisk)\scratchdir" '/Get-ProvisionedAppxPackages' |
138+
$packages = Get-ProvisionedAppxPackage -Path "$ScratchDisk\scratchdir" |
135139
ForEach-Object {
136-
if ($_ -match 'PackageName : (.*)') {
137-
$matches[1]
138-
}
140+
$_.PackageName
139141
}
140-
$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_'
142+
143+
$packagePrefixes =
144+
'Clipchamp.Clipchamp_',
145+
'Microsoft.BingNews_',
146+
'Microsoft.BingSearch_',
147+
'Microsoft.BingWeather_',
148+
'Microsoft.GamingApp_',
149+
'Microsoft.GetHelp_',
150+
'Microsoft.Getstarted_',
151+
'Microsoft.MicrosoftOfficeHub_',
152+
'Microsoft.MicrosoftSolitaireCollection_',
153+
'Microsoft.OutlookForWindows_',
154+
'Microsoft.People_',
155+
'Microsoft.MicrosoftStickyNotes_',
156+
'Microsoft.Todos_',
157+
'Microsoft.WindowsAlarms_',
158+
'microsoft.windowscommunicationsapps_',
159+
'Microsoft.WindowsFeedbackHub_',
160+
'Microsoft.WindowsMaps_',
161+
'Microsoft.WindowsSoundRecorder_',
162+
'Microsoft.Xbox.TCUI_',
163+
'Microsoft.XboxGameOverlay_',
164+
'Microsoft.XboxGamingOverlay_',
165+
'Microsoft.XboxSpeechToTextOverlay_',
166+
'Microsoft.YourPhone_',
167+
'Microsoft.ZuneMusic_',
168+
'Microsoft.ZuneVideo_',
169+
'MicrosoftCorporationII.MicrosoftFamily_',
170+
'MicrosoftCorporationII.QuickAssist_',
171+
'MicrosoftTeams_',
172+
'Microsoft.549981C3F5F10_',
173+
'MSTeams_'
141174

142175
$packagesToRemove = $packages | Where-Object {
143176
$packageName = $_
144177
$packagePrefixes -contains ($packagePrefixes | Where-Object { $packageName -like "$_*" })
145178
}
146179
foreach ($package in $packagesToRemove) {
147-
& 'dism' '/English' "/image:$($ScratchDisk)\scratchdir" '/Remove-ProvisionedAppxPackage' "/PackageName:$package"
180+
Write-Host "Removing $package..."
181+
Remove-AppxProvisionedPackage -Path "$ScratchDisk\scratchdir" -PackageName "$package" | Out-Null
148182
}
149183

150-
151-
Write-Host "Removing Edge:"
184+
Write-Host "`nRemoving Edge:"
152185
Remove-Item -Path "$ScratchDisk\scratchdir\Program Files (x86)\Microsoft\Edge" -Recurse -Force | Out-Null
153186
Remove-Item -Path "$ScratchDisk\scratchdir\Program Files (x86)\Microsoft\EdgeUpdate" -Recurse -Force | Out-Null
154187
Remove-Item -Path "$ScratchDisk\scratchdir\Program Files (x86)\Microsoft\EdgeCore" -Recurse -Force | Out-Null
@@ -258,8 +291,8 @@ Write-Host "Disabling Telemetry:"
258291
& 'reg' 'add' 'HKLM\zNTUSER\Software\Microsoft\Personalization\Settings' '/v' 'AcceptedPrivacyPolicy' '/t' 'REG_DWORD' '/d' '0' '/f' | Out-Null
259292
& 'reg' 'add' 'HKLM\zSOFTWARE\Policies\Microsoft\Windows\DataCollection' '/v' 'AllowTelemetry' '/t' 'REG_DWORD' '/d' '0' '/f' | Out-Null
260293
& 'reg' 'add' 'HKLM\zSYSTEM\ControlSet001\Services\dmwappushservice' '/v' 'Start' '/t' 'REG_DWORD' '/d' '4' '/f' | Out-Null
261-
## Prevents installation or DevHome and Outlook
262-
Write-Host "Prevents installation or DevHome and Outlook:"
294+
## Prevents installation of DevHome and Outlook
295+
Write-Host "Prevents installation of DevHome and Outlook:"
263296
& 'reg' 'add' 'HKLM\zSOFTWARE\Microsoft\Windows\CurrentVersion\WindowsUpdate\Orchestrator\UScheduler\OutlookUpdate' '/v' 'workCompleted' '/t' 'REG_DWORD' '/d' '1' '/f' | Out-Null
264297
& 'reg' 'add' 'HKLM\zSOFTWARE\Microsoft\Windows\CurrentVersion\WindowsUpdate\Orchestrator\UScheduler\DevHomeUpdate' '/v' 'workCompleted' '/t' 'REG_DWORD' '/d' '1' '/f' | Out-Null
265298
& 'reg' 'delete' 'HKLM\zSOFTWARE\Microsoft\WindowsUpdate\Orchestrator\UScheduler_Oobe\OutlookUpdate' '/f' | Out-Null
@@ -289,13 +322,13 @@ function Enable-Privilege {
289322
$definition = @'
290323
using System;
291324
using System.Runtime.InteropServices;
292-
325+
293326
public class AdjPriv
294327
{
295328
[DllImport("advapi32.dll", ExactSpelling = true, SetLastError = true)]
296329
internal static extern bool AdjustTokenPrivileges(IntPtr htok, bool disall,
297330
ref TokPriv1Luid newst, int len, IntPtr prev, IntPtr relen);
298-
331+
299332
[DllImport("advapi32.dll", ExactSpelling = true, SetLastError = true)]
300333
internal static extern bool OpenProcessToken(IntPtr h, int acc, ref IntPtr phtok);
301334
[DllImport("advapi32.dll", SetLastError = true)]
@@ -307,7 +340,7 @@ function Enable-Privilege {
307340
public long Luid;
308341
public int Attr;
309342
}
310-
343+
311344
internal const int SE_PRIVILEGE_ENABLED = 0x00000002;
312345
internal const int SE_PRIVILEGE_DISABLED = 0x00000000;
313346
internal const int TOKEN_QUERY = 0x00000008;
@@ -364,7 +397,7 @@ Write-Host 'Deleting Customer Experience Improvement Program'
364397
reg delete "HKEY_LOCAL_MACHINE\zSOFTWARE\Microsoft\Windows NT\CurrentVersion\Schedule\TaskCache\Tasks\{4738DE7A-BCC1-4E2D-B1B0-CADB044BFA81}" /f | Out-Null
365398
reg delete "HKEY_LOCAL_MACHINE\zSOFTWARE\Microsoft\Windows NT\CurrentVersion\Schedule\TaskCache\Tasks\{6FAC31FA-4A85-4E64-BFD5-2154FF4594B3}" /f | Out-Null
366399
reg delete "HKEY_LOCAL_MACHINE\zSOFTWARE\Microsoft\Windows NT\CurrentVersion\Schedule\TaskCache\Tasks\{FC931F16-B50A-472E-B061-B6F79A71EF59}" /f | Out-Null
367-
Write-Host 'Deleting Program Data Updater'
400+
Write-Host 'Deleting Program Data Updater'
368401
reg delete "HKEY_LOCAL_MACHINE\zSOFTWARE\Microsoft\Windows NT\CurrentVersion\Schedule\TaskCache\Tasks\{0671EB05-7D95-4153-A32B-1426B9FE61DB}" /f | Out-Null
369402
Write-Host 'Deleting autochk proxy'
370403
reg delete "HKEY_LOCAL_MACHINE\zSOFTWARE\Microsoft\Windows NT\CurrentVersion\Schedule\TaskCache\Tasks\{87BF85F4-2CE1-4160-96EA-52F554AA28A2}" /f | Out-Null
@@ -396,7 +429,7 @@ Write-Host "Windows image completed. Continuing with boot.wim."
396429
Start-Sleep -Seconds 2
397430
Clear-Host
398431
Write-Host "Mounting boot image:"
399-
$wimFilePath = "$ScratchDisk\tiny11\sources\boot.wim"
432+
$wimFilePath = "$ScratchDisk\tiny11\sources\boot.wim"
400433
& takeown "/F" $wimFilePath | Out-Null
401434
& icacls $wimFilePath "/grant" "$($adminGroup.Value):(F)"
402435
Set-ItemProperty -Path $wimFilePath -Name IsReadOnly -Value $false
@@ -436,22 +469,31 @@ Write-Host "The tiny11 image is now completed. Proceeding with the making of the
436469
Write-Host "Copying unattended file for bypassing MS account on OOBE..."
437470
Copy-Item -Path "$PSScriptRoot\autounattend.xml" -Destination "$ScratchDisk\tiny11\autounattend.xml" -Force | Out-Null
438471
Write-Host "Creating ISO image..."
439-
$ADKDepTools = "C:\Program Files (x86)\Windows Kits\10\Assessment and Deployment Kit\Deployment Tools\$hostarchitecture\Oscdimg"
472+
# Get Windows ADK path from registry(following Visual Studio's winsdk.bat approach).
473+
$WinSDKPath = [Microsoft.Win32.Registry]::GetValue("HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\Microsoft\Windows Kits\Installed Roots", "KitsRoot10", $null)
474+
if (!$WinSDKPath) {
475+
$WinSDKPath = [Microsoft.Win32.Registry]::GetValue("HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Kits\Installed Roots", "KitsRoot10", $null)
476+
}
477+
if ($WinSDKPath) {
478+
# Trim the following backslash for path concatenation.
479+
$WinSDKPath = $WinSDKPath.TrimEnd('\')
480+
$ADKDepTools = "$WinSDKPath\Assessment and Deployment Kit\Deployment Tools\$hostarchitecture\Oscdimg"
481+
}
440482
$localOSCDIMGPath = "$PSScriptRoot\oscdimg.exe"
441483

442-
if ([System.IO.Directory]::Exists($ADKDepTools)) {
484+
if ($ADKDepTools -and [System.IO.File]::Exists("$ADKDepTools\oscdimg.exe")) {
443485
Write-Host "Will be using oscdimg.exe from system ADK."
444486
$OSCDIMG = "$ADKDepTools\oscdimg.exe"
445487
} else {
446-
Write-Host "ADK folder not found. Will be using bundled oscdimg.exe."
447-
488+
Write-Host "oscdimg.exe from system ADK not found. Will be using bundled oscdimg.exe."
489+
448490
$url = "https://msdl.microsoft.com/download/symbols/oscdimg.exe/3D44737265000/oscdimg.exe"
449491

450-
if (-not (Test-Path -Path $localOSCDIMGPath)) {
492+
if (![System.IO.File]::Exists($localOSCDIMGPath)) {
451493
Write-Host "Downloading oscdimg.exe..."
452494
Invoke-WebRequest -Uri $url -OutFile $localOSCDIMGPath
453495

454-
if (Test-Path $localOSCDIMGPath) {
496+
if ([System.IO.File]::Exists($localOSCDIMGPath)) {
455497
Write-Host "oscdimg.exe downloaded successfully."
456498
} else {
457499
Write-Error "Failed to download oscdimg.exe."

0 commit comments

Comments
 (0)