Files
windows-builder/tiny11Coremaker.ps1
2026-06-02 03:37:09 -07:00

897 lines
59 KiB
PowerShell

# Enable debugging
#Set-PSDebug -Trace 1
param (
[ValidatePattern('^[c-zC-Z]:?$|^[a-zA-Z]:\\.*$')]
[string]$ScratchDisk,
[string]$imageindex,
[switch]$UseSetupTemplate
)
$needchange = @("AllSigned", "Restricted", "Undefined")
$curpolicy = Get-ExecutionPolicy
if ($curpolicy -in $needchange) {
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)"
$response = Read-Host
if ($response -eq 'yes') {
Set-ExecutionPolicy RemoteSigned -Scope Process -Confirm:$false
} else {
Write-Host "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-Host "Restarting Tiny11 image creator as admin in a new window, you can close this one."
$newProcess = new-object System.Diagnostics.ProcessStartInfo "PowerShell";
$argString = "-NoProfile -ExecutionPolicy Bypass -File `"$PSCommandPath`""
if ($ScratchDisk) { $argString += " -ScratchDisk `"$ScratchDisk`"" }
if ($imageindex) { $argString += " -imageindex `"$imageindex`"" }
if ($UseSetupTemplate) { $argString += " -UseSetupTemplate" }
$newProcess.Arguments = $argString;
$newProcess.Verb = "runas";
[System.Diagnostics.Process]::Start($newProcess);
exit
}
Start-Transcript -Path "$PSScriptRoot\tiny11core.log"
# Ask the user for input
Write-Host "Welcome to tiny11 core builder! BETA 05-06-24"
Write-Host "This script generates a significantly reduced Windows 11 image. However, it's not suitable for regular use due to its lack of serviceability - you can't add languages, updates, or features post-creation. tiny11 Core is not a full Windows 11 substitute but a rapid testing or development tool, potentially useful for VM environments."
Write-Host "Do you want to continue? (y/n)"
$input = Read-Host
if ($input -eq 'y') {
Write-Host "Off we go..."
Start-Sleep -Seconds 3
Clear-Host
if (-not $ScratchDisk) {
$ScratchDisk = Join-Path $PSScriptRoot 'working'
} else {
if ($ScratchDisk -match '^[a-zA-Z]:?$') {
$ScratchDisk = $ScratchDisk[0] + ':'
}
}
Write-Output "Scratch disk set to $ScratchDisk"
$hostArchitecture = $Env:PROCESSOR_ARCHITECTURE
$setupMediaTemplatePath = "$PSScriptRoot\setup-media-template"
New-Item -ItemType Directory -Force -Path "$ScratchDisk\tiny11\sources" >null
$DriveLetter = Read-Host "Please enter the drive letter for the Windows 11 image"
$DriveLetter = $DriveLetter + ":"
if ((-not $UseSetupTemplate -and (Test-Path "$DriveLetter\sources\boot.wim") -eq $false) -or (Test-Path "$DriveLetter\sources\install.wim") -eq $false) {
if ((Test-Path "$DriveLetter\sources\install.esd") -eq $true) {
Write-Host "Found install.esd, converting to install.wim..."
& 'dism' '/English' "/Get-WimInfo" "/wimfile:$DriveLetter\sources\install.esd"
$index = Read-Host "Please enter the image index"
Write-Host ' '
Write-Host 'Converting install.esd to install.wim. This may take a while...'
& 'DISM' /Export-Image /SourceImageFile:"$DriveLetter\sources\install.esd" /SourceIndex:$index /DestinationImageFile:"$ScratchDisk\tiny11\sources\install.wim" /Compress:max /CheckIntegrity
} else {
Write-Host "Can't find Windows OS Installation files in the specified Drive Letter.."
Write-Host "Please enter the correct DVD Drive Letter.."
exit
}
}
if ($UseSetupTemplate) {
if (-not (Test-Path "$ScratchDisk\tiny11\sources\install.wim")) {
Write-Host "Template mode: copying install.wim from source..."
Copy-Item -Path "$DriveLetter\sources\install.wim" -Destination "$ScratchDisk\tiny11\sources\install.wim" -Force > $null
}
if (-not (Test-Path "$setupMediaTemplatePath")) {
Write-Error "setup-media-template folder not found: $setupMediaTemplatePath"
exit 1
}
Write-Host "Copying setup media template..."
Copy-Item -Path "$setupMediaTemplatePath\*" -Destination "$ScratchDisk\tiny11" -Recurse -Force | Out-Null
Write-Host "Template copy complete."
} else {
Write-Host "Copying Windows image..."
Copy-Item -Path "$DriveLetter\*" -Destination "$ScratchDisk\tiny11" -Recurse -Force > $null
Set-ItemProperty -Path "$ScratchDisk\tiny11\sources\install.esd" -Name IsReadOnly -Value $false > $null 2>&1
Remove-Item "$ScratchDisk\tiny11\sources\install.esd" > $null 2>&1
Write-Host "Copy complete!"
Start-Sleep -Seconds 2
Clear-Host
}
Write-Host "Getting image information:"
& 'dism' '/English' "/Get-WimInfo" "/wimfile:$ScratchDisk\tiny11\sources\install.wim"
if ($imageindex) {
$index = $imageindex
Write-Host "Using provided image index: $index"
} else {
$index = Read-Host "Please enter the image index"
}
Write-Host "Mounting Windows image. This may take a while."
$wimFilePath = "$ScratchDisk\tiny11\sources\install.wim"
& takeown "/F" $wimFilePath
& icacls $wimFilePath "/grant" "$($adminGroup.Value):(F)"
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
& dism /English "/mount-image" "/imagefile:$ScratchDisk\tiny11\sources\install.wim" "/index:$index" "/mountdir:$ScratchDisk\scratchdir"
$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-Host "Default system UI language code: $languageCode"
} else {
Write-Host "Default system UI language code not found."
}
$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 : ',''
# If the architecture is x64, replace it with amd64
if ($architecture -eq 'x64') {
$architecture = 'amd64'
}
Write-Host "Architecture: $architecture"
break
}
}
if (-not $architecture) {
Write-Host "Architecture information not found."
}
Write-Host "Mounting complete! Performing removal of applications..."
$packages = & 'dism' '/English' "/image:$ScratchDisk\scratchdir" '/Get-ProvisionedAppxPackages' |
ForEach-Object {
if ($_ -match 'PackageName : (.*)') {
$matches[1]
}
}
$packagePrefixes = 'Clipchamp.Clipchamp_', 'Microsoft.SecHealthUI_', 'Microsoft.Windows.PeopleExperienceHost_', 'Microsoft.Windows.PinningConfirmationDialog_', 'Windows.CBSPreview_', '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_'
$packagesToRemove = $packages | Where-Object {
$packageName = $_
$packagePrefixes -contains ($packagePrefixes | Where-Object { $packageName -like "$_*" })
}
foreach ($package in $packagesToRemove) {
write-host "Removing $package :"
& 'dism' '/English' "/image:$ScratchDisk\scratchdir" '/Remove-ProvisionedAppxPackage' "/PackageName:$package"
}
Write-Host "Removing of system apps complete! Now proceeding to removal of system packages..."
Start-Sleep -Seconds 1
Clear-Host
$scratchDir = "$ScratchDisk\scratchdir"
$packagePatterns = @(
"Microsoft-Windows-InternetExplorer-Optional-Package~31bf3856ad364e35",
"Microsoft-Windows-Kernel-LA57-FoD-Package~31bf3856ad364e35~amd64",
"Microsoft-Windows-LanguageFeatures-Handwriting-$languageCode-Package~31bf3856ad364e35",
"Microsoft-Windows-LanguageFeatures-OCR-$languageCode-Package~31bf3856ad364e35",
"Microsoft-Windows-LanguageFeatures-Speech-$languageCode-Package~31bf3856ad364e35",
"Microsoft-Windows-LanguageFeatures-TextToSpeech-$languageCode-Package~31bf3856ad364e35",
"Microsoft-Windows-MediaPlayer-Package~31bf3856ad364e35",
"Microsoft-Windows-Wallpaper-Content-Extended-FoD-Package~31bf3856ad364e35",
"Windows-Defender-Client-Package~31bf3856ad364e35~",
"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? (y/n)"
$input = Read-Host
# Check the user's input
if ($input -eq 'y') {
# If the user entered 'y', enable .NET 3.5 using DISM
Write-Host "Enabling .NET 3.5..."
& 'dism' "/image:$scratchDir" '/enable-feature' '/featurename:NetFX3' '/All' "/source:$ScratchDisk\tiny11\sources\sxs"
Write-Host ".NET 3.5 has been enabled."
}
elseif ($input -eq 'n') {
# If the user entered 'n', exit the script
Write-Host "You chose not to enable .NET 3.5. Continuing..."
}
else {
# If the user entered anything other than 'y' or 'n', ask for input again
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 "$ScratchDisk\scratchdir\Program Files (x86)\Microsoft\Edge" -Recurse -Force >null
Remove-Item -Path "$ScratchDisk\scratchdir\Program Files (x86)\Microsoft\EdgeUpdate" -Recurse -Force >null
Remove-Item -Path "$ScratchDisk\scratchdir\Program Files (x86)\Microsoft\EdgeCore" -Recurse -Force >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' >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 "$ScratchDisk\scratchdir\Windows\WinSxS" -Filter "arm64_microsoft-edge-webview_31bf3856ad364e35*" -Directory | Select-Object -ExpandProperty FullName >null
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."
}
} else {
Write-Host "Unknown architecture: $architecture"
}
& 'takeown' '/f' "$ScratchDisk\scratchdir\Windows\System32\Microsoft-Edge-Webview" '/r'
& 'icacls' "$ScratchDisk\scratchdir\Windows\System32\Microsoft-Edge-Webview" '/grant' "$($adminGroup.Value):(F)" '/T' '/C'
Remove-Item -Path "$ScratchDisk\scratchdir\Windows\System32\Microsoft-Edge-Webview" -Recurse -Force
Write-Host "Removing WinRE"
& 'takeown' '/f' "$ScratchDisk\scratchdir\Windows\System32\Recovery" '/r'
& 'icacls' "$ScratchDisk\scratchdir\Windows\System32\Recovery" '/grant' 'Administrators:F' '/T' '/C'
Remove-Item -Path "$ScratchDisk\scratchdir\Windows\System32\Recovery\winre.wim" -Recurse -Force
New-Item -Path "$ScratchDisk\scratchdir\Windows\System32\Recovery\winre.wim" -ItemType File -Force
Write-Host "Removing OneDrive:"
& 'takeown' '/f' "$ScratchDisk\scratchdir\Windows\System32\OneDriveSetup.exe" >null
& 'icacls' "$ScratchDisk\scratchdir\Windows\System32\OneDriveSetup.exe" '/grant' "$($adminGroup.Value):(F)" '/T' '/C' >null
Remove-Item -Path "$ScratchDisk\scratchdir\Windows\System32\OneDriveSetup.exe" -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' "$ScratchDisk\scratchdir\Windows\WinSxS" '/r'
& 'icacls' "$ScratchDisk\scratchdir\Windows\WinSxS" '/grant' "$($adminGroup.Value):(F)" '/T' '/C'
Write-host "Complete!"
Start-Sleep -Seconds 2
Clear-Host
Write-Host "Preparing..."
$folderPath = Join-Path -Path $ScratchDisk -ChildPath "\scratchdir\Windows\WinSxS_edit"
$sourceDirectory = "$ScratchDisk\scratchdir\Windows\WinSxS"
$destinationDirectory = "$ScratchDisk\scratchdir\Windows\WinSxS_edit"
New-Item -Path $folderPath -ItemType Directory
if ($architecture -eq "amd64") {
# Specify the list of files to copy
$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_*"
)
}
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
}
}
Write-Host "Deleting WinSxS. This may take a while..."
Remove-Item -Path $ScratchDisk\scratchdir\Windows\WinSxS -Recurse -Force
Rename-Item -Path $ScratchDisk\scratchdir\Windows\WinSxS_edit -NewName $ScratchDisk\scratchdir\Windows\WinSxS
Write-Host "Complete!"
Write-Host "Loading registry..."
reg load HKLM\zCOMPONENTS $ScratchDisk\scratchdir\Windows\System32\config\COMPONENTS >null
reg load HKLM\zDEFAULT $ScratchDisk\scratchdir\Windows\System32\config\default >null
reg load HKLM\zNTUSER $ScratchDisk\scratchdir\Users\Default\ntuser.dat >null
reg load HKLM\zSOFTWARE $ScratchDisk\scratchdir\Windows\System32\config\SOFTWARE >null
reg load HKLM\zSYSTEM $ScratchDisk\scratchdir\Windows\System32\config\SYSTEM >null
# Set-RegistryValue function for robust registry operations with automatic key creation
function Set-RegistryValue {
param(
[string]$KeyPath,
[string]$ValueName,
[string]$ValueType,
[string]$ValueData,
[string]$Description = ""
)
try {
# Use reg add with /f flag to force creation of keys and overwrite existing values
$result = & 'reg' 'add' $KeyPath '/v' $ValueName '/t' $ValueType '/d' $ValueData '/f' 2>&1
if ($LASTEXITCODE -ne 0) {
$errorMsg = if ($Description) { "Failed to set registry value for $Description" } else { "Failed to set registry value $ValueName in $KeyPath" }
Write-Warning "$errorMsg. Error: $result"
}
}
catch {
$errorMsg = if ($Description) { "Exception setting registry value for $Description" } else { "Exception setting registry value $ValueName in $KeyPath" }
Write-Warning "$errorMsg. Exception: $($_.Exception.Message)"
}
}
Write-Host "Bypassing system requirements(on the system image):"
Set-RegistryValue -KeyPath 'HKLM\zDEFAULT\Control Panel\UnsupportedHardwareNotificationCache' -ValueName 'SV1' -ValueType 'REG_DWORD' -ValueData '0' -Description "Unsupported hardware notification SV1"
Set-RegistryValue -KeyPath 'HKLM\zDEFAULT\Control Panel\UnsupportedHardwareNotificationCache' -ValueName 'SV2' -ValueType 'REG_DWORD' -ValueData '0' -Description "Unsupported hardware notification SV2"
Set-RegistryValue -KeyPath 'HKLM\zNTUSER\Control Panel\UnsupportedHardwareNotificationCache' -ValueName 'SV1' -ValueType 'REG_DWORD' -ValueData '0' -Description "User unsupported hardware notification SV1"
Set-RegistryValue -KeyPath 'HKLM\zNTUSER\Control Panel\UnsupportedHardwareNotificationCache' -ValueName 'SV2' -ValueType 'REG_DWORD' -ValueData '0' -Description "User unsupported hardware notification SV2"
Set-RegistryValue -KeyPath 'HKLM\zSYSTEM\Setup\LabConfig' -ValueName 'BypassCPUCheck' -ValueType 'REG_DWORD' -ValueData '1' -Description "Bypass CPU check"
Set-RegistryValue -KeyPath 'HKLM\zSYSTEM\Setup\LabConfig' -ValueName 'BypassRAMCheck' -ValueType 'REG_DWORD' -ValueData '1' -Description "Bypass RAM check"
Set-RegistryValue -KeyPath 'HKLM\zSYSTEM\Setup\LabConfig' -ValueName 'BypassSecureBootCheck' -ValueType 'REG_DWORD' -ValueData '1' -Description "Bypass Secure Boot check"
Set-RegistryValue -KeyPath 'HKLM\zSYSTEM\Setup\LabConfig' -ValueName 'BypassStorageCheck' -ValueType 'REG_DWORD' -ValueData '1' -Description "Bypass storage check"
Set-RegistryValue -KeyPath 'HKLM\zSYSTEM\Setup\LabConfig' -ValueName 'BypassTPMCheck' -ValueType 'REG_DWORD' -ValueData '1' -Description "Bypass TPM check"
Set-RegistryValue -KeyPath 'HKLM\zSYSTEM\Setup\MoSetup' -ValueName 'AllowUpgradesWithUnsupportedTPMOrCPU' -ValueType 'REG_DWORD' -ValueData '1' -Description "Allow upgrades with unsupported TPM or CPU"
Write-Host "Disabling Sponsored Apps:"
Set-RegistryValue -KeyPath 'HKLM\zNTUSER\SOFTWARE\Microsoft\Windows\CurrentVersion\ContentDeliveryManager' -ValueName 'OemPreInstalledAppsEnabled' -ValueType 'REG_DWORD' -ValueData '0' -Description "OEM pre-installed apps"
Set-RegistryValue -KeyPath 'HKLM\zNTUSER\SOFTWARE\Microsoft\Windows\CurrentVersion\ContentDeliveryManager' -ValueName 'PreInstalledAppsEnabled' -ValueType 'REG_DWORD' -ValueData '0' -Description "Pre-installed apps"
Set-RegistryValue -KeyPath 'HKLM\zNTUSER\SOFTWARE\Microsoft\Windows\CurrentVersion\ContentDeliveryManager' -ValueName 'SilentInstalledAppsEnabled' -ValueType 'REG_DWORD' -ValueData '0' -Description "Silent installed apps"
Set-RegistryValue -KeyPath 'HKLM\zSOFTWARE\Policies\Microsoft\Windows\CloudContent' -ValueName 'DisableWindowsConsumerFeatures' -ValueType 'REG_DWORD' -ValueData '1' -Description "Windows consumer features"
Set-RegistryValue -KeyPath 'HKLM\zNTUSER\Software\Microsoft\Windows\CurrentVersion\ContentDeliveryManager' -ValueName 'ContentDeliveryAllowed' -ValueType 'REG_DWORD' -ValueData '0' -Description "Content delivery allowed"
Set-RegistryValue -KeyPath 'HKLM\zSOFTWARE\Microsoft\PolicyManager\current\device\Start' -ValueName 'ConfigureStartPins' -ValueType 'REG_SZ' -ValueData '{"pinnedList": [{}]}' -Description "Start menu pins configuration"
Set-RegistryValue -KeyPath 'HKLM\zNTUSER\Software\Microsoft\Windows\CurrentVersion\ContentDeliveryManager' -ValueName 'ContentDeliveryAllowed' -ValueType 'REG_DWORD' -ValueData '0' -Description "Content delivery allowed (duplicate)"
Set-RegistryValue -KeyPath 'HKLM\zNTUSER\Software\Microsoft\Windows\CurrentVersion\ContentDeliveryManager' -ValueName 'ContentDeliveryAllowed' -ValueType 'REG_DWORD' -ValueData '0' -Description "Content delivery allowed (duplicate 2)"
Set-RegistryValue -KeyPath 'HKLM\zNTUSER\Software\Microsoft\Windows\CurrentVersion\ContentDeliveryManager' -ValueName 'FeatureManagementEnabled' -ValueType 'REG_DWORD' -ValueData '0' -Description "Feature management"
Set-RegistryValue -KeyPath 'HKLM\zNTUSER\Software\Microsoft\Windows\CurrentVersion\ContentDeliveryManager' -ValueName 'OemPreInstalledAppsEnabled' -ValueType 'REG_DWORD' -ValueData '0' -Description "OEM pre-installed apps (duplicate)"
Set-RegistryValue -KeyPath 'HKLM\zNTUSER\Software\Microsoft\Windows\CurrentVersion\ContentDeliveryManager' -ValueName 'PreInstalledAppsEnabled' -ValueType 'REG_DWORD' -ValueData '0' -Description "Pre-installed apps (duplicate)"
Set-RegistryValue -KeyPath 'HKLM\zNTUSER\Software\Microsoft\Windows\CurrentVersion\ContentDeliveryManager' -ValueName 'PreInstalledAppsEverEnabled' -ValueType 'REG_DWORD' -ValueData '0' -Description "Pre-installed apps ever enabled"
Set-RegistryValue -KeyPath 'HKLM\zNTUSER\Software\Microsoft\Windows\CurrentVersion\ContentDeliveryManager' -ValueName 'SilentInstalledAppsEnabled' -ValueType 'REG_DWORD' -ValueData '0' -Description "Silent installed apps (duplicate)"
Set-RegistryValue -KeyPath 'HKLM\zNTUSER\Software\Microsoft\Windows\CurrentVersion\ContentDeliveryManager' -ValueName 'SoftLandingEnabled' -ValueType 'REG_DWORD' -ValueData '0' -Description "Soft landing enabled"
Set-RegistryValue -KeyPath 'HKLM\zNTUSER\Software\Microsoft\Windows\CurrentVersion\ContentDeliveryManager' -ValueName 'SubscribedContentEnabled' -ValueType 'REG_DWORD' -ValueData '0' -Description "Subscribed content"
Set-RegistryValue -KeyPath 'HKLM\zNTUSER\Software\Microsoft\Windows\CurrentVersion\ContentDeliveryManager' -ValueName 'SubscribedContent-310093Enabled' -ValueType 'REG_DWORD' -ValueData '0' -Description "Subscribed content 310093"
Set-RegistryValue -KeyPath 'HKLM\zNTUSER\Software\Microsoft\Windows\CurrentVersion\ContentDeliveryManager' -ValueName 'SubscribedContent-338388Enabled' -ValueType 'REG_DWORD' -ValueData '0' -Description "Subscribed content 338388"
Set-RegistryValue -KeyPath 'HKLM\zNTUSER\Software\Microsoft\Windows\CurrentVersion\ContentDeliveryManager' -ValueName 'SubscribedContent-338389Enabled' -ValueType 'REG_DWORD' -ValueData '0' -Description "Subscribed content 338389"
Set-RegistryValue -KeyPath 'HKLM\zNTUSER\Software\Microsoft\Windows\CurrentVersion\ContentDeliveryManager' -ValueName 'SubscribedContent-338393Enabled' -ValueType 'REG_DWORD' -ValueData '0' -Description "Subscribed content 338393"
Set-RegistryValue -KeyPath 'HKLM\zNTUSER\Software\Microsoft\Windows\CurrentVersion\ContentDeliveryManager' -ValueName 'SubscribedContent-353694Enabled' -ValueType 'REG_DWORD' -ValueData '0' -Description "Subscribed content 353694"
Set-RegistryValue -KeyPath 'HKLM\zNTUSER\Software\Microsoft\Windows\CurrentVersion\ContentDeliveryManager' -ValueName 'SubscribedContent-353696Enabled' -ValueType 'REG_DWORD' -ValueData '0' -Description "Subscribed content 353696"
Set-RegistryValue -KeyPath 'HKLM\zNTUSER\Software\Microsoft\Windows\CurrentVersion\ContentDeliveryManager' -ValueName 'SubscribedContentEnabled' -ValueType 'REG_DWORD' -ValueData '0' -Description "Subscribed content enabled (duplicate)"
Set-RegistryValue -KeyPath 'HKLM\zNTUSER\Software\Microsoft\Windows\CurrentVersion\ContentDeliveryManager' -ValueName 'SystemPaneSuggestionsEnabled' -ValueType 'REG_DWORD' -ValueData '0' -Description "System pane suggestions"
Set-RegistryValue -KeyPath 'HKLM\zSOFTWARE\Policies\Microsoft\PushToInstall' -ValueName 'DisablePushToInstall' -ValueType 'REG_DWORD' -ValueData '1' -Description "Push to install feature"
Set-RegistryValue -KeyPath 'HKLM\zSOFTWARE\Policies\Microsoft\MRT' -ValueName 'DontOfferThroughWUAU' -ValueType 'REG_DWORD' -ValueData '1' -Description "Malicious software removal tool through Windows Update"
& 'reg' 'delete' 'HKLM\zNTUSER\Software\Microsoft\Windows\CurrentVersion\ContentDeliveryManager\Subscriptions' '/f' >null
& 'reg' 'delete' 'HKLM\zNTUSER\Software\Microsoft\Windows\CurrentVersion\ContentDeliveryManager\SuggestedApps' '/f' >null
Set-RegistryValue -KeyPath 'HKLM\zSOFTWARE\Policies\Microsoft\Windows\CloudContent' -ValueName 'DisableConsumerAccountStateContent' -ValueType 'REG_DWORD' -ValueData '1' -Description "Consumer account state content"
Set-RegistryValue -KeyPath 'HKLM\zSOFTWARE\Policies\Microsoft\Windows\CloudContent' -ValueName 'DisableCloudOptimizedContent' -ValueType 'REG_DWORD' -ValueData '1' -Description "Cloud optimized content"
Write-Host "Enabling Local Accounts on OOBE:"
Set-RegistryValue -KeyPath 'HKLM\zSOFTWARE\Microsoft\Windows\CurrentVersion\OOBE' -ValueName 'BypassNRO' -ValueType 'REG_DWORD' -ValueData '1' -Description "Bypass Network Requirement in OOBE"
Write-Host "Disabling Reserved Storage:"
Set-RegistryValue -KeyPath 'HKLM\zSOFTWARE\Microsoft\Windows\CurrentVersion\ReserveManager' -ValueName 'ShippedWithReserves' -ValueType 'REG_DWORD' -ValueData '0' -Description "Reserved storage feature"
Write-Host "Disabling BitLocker Device Encryption"
Set-RegistryValue -KeyPath 'HKLM\zSYSTEM\ControlSet001\Control\BitLocker' -ValueName 'PreventDeviceEncryption' -ValueType 'REG_DWORD' -ValueData '1' -Description "BitLocker device encryption"
Write-Host "Disabling Chat icon:"
Set-RegistryValue -KeyPath 'HKLM\zSOFTWARE\Policies\Microsoft\Windows\Windows Chat' -ValueName 'ChatIcon' -ValueType 'REG_DWORD' -ValueData '3' -Description "Windows Chat icon"
Set-RegistryValue -KeyPath 'HKLM\zNTUSER\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\Advanced' -ValueName 'TaskbarMn' -ValueType 'REG_DWORD' -ValueData '0' -Description "Taskbar Teams/Meet Now button"
Write-Host "Disabling Telemetry:"
Set-RegistryValue -KeyPath 'HKLM\zNTUSER\Software\Microsoft\Windows\CurrentVersion\AdvertisingInfo' -ValueName 'Enabled' -ValueType 'REG_DWORD' -ValueData '0' -Description "Advertising info collection"
Set-RegistryValue -KeyPath 'HKLM\zNTUSER\Software\Microsoft\Windows\CurrentVersion\Privacy' -ValueName 'TailoredExperiencesWithDiagnosticDataEnabled' -ValueType 'REG_DWORD' -ValueData '0' -Description "Tailored experiences with diagnostic data"
Set-RegistryValue -KeyPath 'HKLM\zNTUSER\Software\Microsoft\Speech_OneCore\Settings\OnlineSpeechPrivacy' -ValueName 'HasAccepted' -ValueType 'REG_DWORD' -ValueData '0' -Description "Online speech privacy"
Set-RegistryValue -KeyPath 'HKLM\zNTUSER\Software\Microsoft\Input\TIPC' -ValueName 'Enabled' -ValueType 'REG_DWORD' -ValueData '0' -Description "Text input personalization"
Set-RegistryValue -KeyPath 'HKLM\zNTUSER\Software\Microsoft\InputPersonalization' -ValueName 'RestrictImplicitInkCollection' -ValueType 'REG_DWORD' -ValueData '1' -Description "Implicit ink collection restriction"
Set-RegistryValue -KeyPath 'HKLM\zNTUSER\Software\Microsoft\InputPersonalization' -ValueName 'RestrictImplicitTextCollection' -ValueType 'REG_DWORD' -ValueData '1' -Description "Implicit text collection restriction"
Set-RegistryValue -KeyPath 'HKLM\zNTUSER\Software\Microsoft\InputPersonalization\TrainedDataStore' -ValueName 'HarvestContacts' -ValueType 'REG_DWORD' -ValueData '0' -Description "Contact harvesting for input personalization"
Set-RegistryValue -KeyPath 'HKLM\zNTUSER\Software\Microsoft\Personalization\Settings' -ValueName 'AcceptedPrivacyPolicy' -ValueType 'REG_DWORD' -ValueData '0' -Description "Personalization privacy policy"
Set-RegistryValue -KeyPath 'HKLM\zSOFTWARE\Policies\Microsoft\Windows\DataCollection' -ValueName 'AllowTelemetry' -ValueType 'REG_DWORD' -ValueData '0' -Description "Telemetry data collection"
Set-RegistryValue -KeyPath 'HKLM\zSYSTEM\ControlSet001\Services\dmwappushservice' -ValueName 'Start' -ValueType 'REG_DWORD' -ValueData '4' -Description "Device management WAP push service"
Set-RegistryValue -KeyPath 'HKLM\zSOFTWARE\Policies\Microsoft\Windows\Windows Chat' -ValueName 'ChatIcon' -ValueType 'REG_DWORD' -ValueData '3' -Description "Windows Chat icon (duplicate)"
Set-RegistryValue -KeyPath 'HKLM\zNTUSER\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\Advanced' -ValueName 'TaskbarMn' -ValueType 'REG_DWORD' -ValueData '0' -Description "Taskbar Teams/Meet Now button (duplicate)"
Write-Host "Disabling OneDrive folder backup"
Set-RegistryValue -KeyPath "HKLM\zSOFTWARE\Policies\Microsoft\Windows\OneDrive" -ValueName 'DisableFileSyncNGSC' -ValueType 'REG_DWORD' -ValueData '1' -Description "OneDrive file sync"
Write-Host "Removing Edge related registries"
reg delete "HKEY_LOCAL_MACHINE\zSOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall\Microsoft Edge" /f
reg delete "HKEY_LOCAL_MACHINE\zSOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall\Microsoft Edge Update" /f
Write-Host "Disabling bing in Start Menu:"
Set-RegistryValue -KeyPath 'HKLM\zNTUSER\Software\Policies\Microsoft\Windows\Explorer' -ValueName '' -ValueType 'REG_SZ' -ValueData '' -Description "Explorer policies key creation"
Set-RegistryValue -KeyPath 'HKLM\zNTUSER\Software\Policies\Microsoft\Windows\Explorer' -ValueName 'ShowRunAsDifferentUserInStart' -ValueType 'REG_DWORD' -ValueData '1' -Description "Show run as different user in Start menu"
Set-RegistryValue -KeyPath 'HKLM\zNTUSER\Software\Policies\Microsoft\Windows\Explorer' -ValueName 'DisableSearchBoxSuggestions' -ValueType 'REG_DWORD' -ValueData '1' -Description "Disable search box suggestions"
## Prevents installation or DevHome and Outlook
Write-Host "Prevents installation or DevHome and Outlook:"
Set-RegistryValue -KeyPath 'HKLM\zSOFTWARE\Microsoft\Windows\CurrentVersion\WindowsUpdate\Orchestrator\UScheduler\OutlookUpdate' -ValueName 'workCompleted' -ValueType 'REG_DWORD' -ValueData '1' -Description "Outlook update orchestrator"
Set-RegistryValue -KeyPath 'HKLM\zSOFTWARE\Microsoft\Windows\CurrentVersion\WindowsUpdate\Orchestrator\UScheduler\DevHomeUpdate' -ValueName 'workCompleted' -ValueType 'REG_DWORD' -ValueData '1' -Description "DevHome update orchestrator"
& '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
## 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;
}
}
'@
$processHandle = (Get-Process -id $ProcessId).Handle
$type = Add-Type $definition -PassThru
$type[0]::EnablePrivilege($processHandle, $Privilege, $Disable)
}
Enable-Privilege SeTakeOwnershipPrivilege
$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()
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
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
reg delete "HKEY_LOCAL_MACHINE\zSOFTWARE\Microsoft\Windows NT\CurrentVersion\Schedule\TaskCache\Tasks\{6FAC31FA-4A85-4E64-BFD5-2154FF4594B3}" /f
reg delete "HKEY_LOCAL_MACHINE\zSOFTWARE\Microsoft\Windows NT\CurrentVersion\Schedule\TaskCache\Tasks\{FC931F16-B50A-472E-B061-B6F79A71EF59}" /f
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
Write-Host 'Deleting autochk proxy'
reg delete "HKEY_LOCAL_MACHINE\zSOFTWARE\Microsoft\Windows NT\CurrentVersion\Schedule\TaskCache\Tasks\{87BF85F4-2CE1-4160-96EA-52F554AA28A2}" /f
reg delete "HKEY_LOCAL_MACHINE\zSOFTWARE\Microsoft\Windows NT\CurrentVersion\Schedule\TaskCache\Tasks\{8A9C643C-3D74-4099-B6BD-9C6D170898B1}" /f
Write-Host 'Deleting QueueReporting'
reg delete "HKEY_LOCAL_MACHINE\zSOFTWARE\Microsoft\Windows NT\CurrentVersion\Schedule\TaskCache\Tasks\{E3176A65-4E44-4ED3-AA73-3283660ACB9C}" /f
Write-Host "Disabling Windows Update..."
Set-RegistryValue -KeyPath "HKLM\zSOFTWARE\Microsoft\Windows\CurrentVersion\RunOnce" -ValueName 'StopWUPostOOBE1' -ValueType 'REG_SZ' -ValueData 'net stop wuauserv' -Description "Stop Windows Update service post-OOBE (method 1)"
Set-RegistryValue -KeyPath "HKLM\zSOFTWARE\Microsoft\Windows\CurrentVersion\RunOnce" -ValueName 'StopWUPostOOBE2' -ValueType 'REG_SZ' -ValueData 'sc stop wuauserv' -Description "Stop Windows Update service post-OOBE (method 2)"
Set-RegistryValue -KeyPath "HKLM\zSOFTWARE\Microsoft\Windows\CurrentVersion\RunOnce" -ValueName 'StopWUPostOOBE3' -ValueType 'REG_SZ' -ValueData 'sc config wuauserv start= disabled' -Description "Disable Windows Update service post-OOBE"
Set-RegistryValue -KeyPath "HKLM\zSOFTWARE\Microsoft\Windows\CurrentVersion\RunOnce" -ValueName 'DisbaleWUPostOOBE1' -ValueType 'REG_SZ' -ValueData 'reg add HKLM\SYSTEM\CurrentControlSet\Services\wuauserv /v Start /t REG_DWORD /d 4 /f' -Description "Disable Windows Update service via registry (CurrentControlSet)"
Set-RegistryValue -KeyPath "HKLM\zSOFTWARE\Microsoft\Windows\CurrentVersion\RunOnce" -ValueName 'DisbaleWUPostOOBE2' -ValueType 'REG_SZ' -ValueData 'reg add HKLM\SYSTEM\ControlSet001\Services\wuauserv /v Start /t REG_DWORD /d 4 /f' -Description "Disable Windows Update service via registry (ControlSet001)"
Set-RegistryValue -KeyPath 'HKLM\zSOFTWARE\Policies\Microsoft\Windows\WindowsUpdate' -ValueName 'DoNotConnectToWindowsUpdateInternetLocations' -ValueType 'REG_DWORD' -ValueData '1' -Description "Do not connect to Windows Update internet locations"
Set-RegistryValue -KeyPath 'HKLM\zSOFTWARE\Policies\Microsoft\Windows\WindowsUpdate' -ValueName 'DisableWindowsUpdateAccess' -ValueType 'REG_DWORD' -ValueData '1' -Description "Disable Windows Update access"
Set-RegistryValue -KeyPath 'HKLM\zSOFTWARE\Policies\Microsoft\Windows\WindowsUpdate' -ValueName 'WUServer' -ValueType 'REG_SZ' -ValueData 'localhost' -Description "Windows Update server URL"
Set-RegistryValue -KeyPath 'HKLM\zSOFTWARE\Policies\Microsoft\Windows\WindowsUpdate' -ValueName 'WUStatusServer' -ValueType 'REG_SZ' -ValueData 'localhost' -Description "Windows Update status server URL"
Set-RegistryValue -KeyPath 'HKLM\zSOFTWARE\Policies\Microsoft\Windows\WindowsUpdate' -ValueName 'UpdateServiceUrlAlternate' -ValueType 'REG_SZ' -ValueData 'localhost' -Description "Alternative update service URL"
Set-RegistryValue -KeyPath 'HKLM\zSOFTWARE\Policies\Microsoft\Windows\WindowsUpdate\AU' -ValueName 'UseWUServer' -ValueType 'REG_DWORD' -ValueData '1' -Description "Use Windows Update server"
Set-RegistryValue -KeyPath 'HKLM\zSOFTWARE\Microsoft\Windows\CurrentVersion\OOBE' -ValueName 'DisableOnline' -ValueType 'REG_DWORD' -ValueData '1' -Description "Disable online OOBE"
Set-RegistryValue -KeyPath 'HKLM\zSYSTEM\ControlSet001\Services\wuauserv' -ValueName 'Start' -ValueType 'REG_DWORD' -ValueData '4' -Description "Windows Update service start type"
function Disable-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;
}
}
'@
$processHandle = (Get-Process -id $ProcessId).Handle
$type = Add-Type $definition -PassThru
$type[0]::EnablePrivilege($processHandle, $Privilege, $Disable)
}
Disable-Privilege SeTakeOwnershipPrivilege
$everyone = New-Object System.Security.Principal.NTAccount('Everyone')
$accessRule = New-Object System.Security.AccessControl.RegistryAccessRule($everyone, 'ReadKey', 'Allow')
$regKey = [Microsoft.Win32.Registry]::LocalMachine.OpenSubKey("zSYSTEM\ControlSet001\Services\wuauserv",[Microsoft.Win32.RegistryKeyPermissionCheck]::ReadWriteSubTree,[System.Security.AccessControl.RegistryRights]::TakeOwnership)
$regACL = $regKey.GetAccessControl()
$regACL.SetOwner($everyone)
$regKey.Close()
Write-Host "Owner changed to Everyone."
$regKey = [Microsoft.Win32.Registry]::LocalMachine.OpenSubKey("zSYSTEM\ControlSet001\Services\wuauserv",[Microsoft.Win32.RegistryKeyPermissionCheck]::ReadWriteSubTree,[System.Security.AccessControl.RegistryRights]::ChangePermissions)
$regACL = $regKey.GetAccessControl()
$regRule = New-Object System.Security.AccessControl.RegistryAccessRule ($everyone, 'ReadKey', 'Allow')
$regACL.SetAccessRule($regRule)
$regKey.SetAccessControl($regACL)
Write-Host "Permissions modified for Everyone group."
Write-Host "Registry key permissions successfully updated."
Write-Host "All users have been granted read-only access to the registry key."
$regKey.Close()
& 'reg' 'delete' "HKEY_LOCAL_MACHINE\zSOFTWARE\Microsoft\Windows NT\CurrentVersion\Schedule\TaskCache\Tasks\{2540477E-E654-4302-AD44-383BBFFBFF16}" '/f'
& 'reg' 'delete' "HKEY_LOCAL_MACHINE\zSOFTWARE\Microsoft\Windows NT\CurrentVersion\Schedule\TaskCache\Tasks\{341B2255-6A6B-442A-AF5A-C610B7DBE12D}" '/f'
& 'reg' 'delete' "HKEY_LOCAL_MACHINE\zSOFTWARE\Microsoft\Windows NT\CurrentVersion\Schedule\TaskCache\Tasks\{476E8CFA-78E2-4C51-854E-538F8643B4FD}" '/f'
& 'reg' 'delete' "HKEY_LOCAL_MACHINE\zSOFTWARE\Microsoft\Windows NT\CurrentVersion\Schedule\TaskCache\Tasks\{764DDB74-CB08-4E0A-8580-B41F94F2C7BE}" '/f'
& 'reg' 'delete' "HKEY_LOCAL_MACHINE\zSOFTWARE\Microsoft\Windows NT\CurrentVersion\Schedule\TaskCache\Tasks\{817CCFDD-4DD0-4102-AC6E-3F5D3B789FB8}" '/f'
& 'reg' 'delete' "HKEY_LOCAL_MACHINE\zSOFTWARE\Microsoft\Windows NT\CurrentVersion\Schedule\TaskCache\Tasks\{99CEDA8C-A866-4787-BBD3-6F3C9F61DD5C}" '/f'
& 'reg' 'delete' "HKEY_LOCAL_MACHINE\zSOFTWARE\Microsoft\Windows NT\CurrentVersion\Schedule\TaskCache\Tasks\{9B3CDCDA-4197-490B-AA5C-C9F5F42A9D88}" '/f'
& 'reg' 'delete' "HKEY_LOCAL_MACHINE\zSOFTWARE\Microsoft\Windows NT\CurrentVersion\Schedule\TaskCache\Tasks\{9CBBFAAE-DB9F-48B4-BAC0-4CFF482A4E01}" '/f'
& 'reg' 'delete' "HKEY_LOCAL_MACHINE\zSOFTWARE\Microsoft\Windows NT\CurrentVersion\Schedule\TaskCache\Tasks\{A31197EC-EAEE-4837-8A9C-3A17D358B9EB}" '/f'
& 'reg' 'delete' "HKEY_LOCAL_MACHINE\zSOFTWARE\Microsoft\Windows NT\CurrentVersion\Schedule\TaskCache\Tasks\{B4FBEFA9-6F7C-4C74-A891-3774B7BCD072}" '/f'
& 'reg' 'delete' "HKEY_LOCAL_MACHINE\zSOFTWARE\Microsoft\Windows NT\CurrentVersion\Schedule\TaskCache\Tasks\{B53BD60A-5823-411C-9C75-AA91DB3C35F8}" '/f'
& 'reg' 'delete' "HKEY_LOCAL_MACHINE\zSOFTWARE\Microsoft\Windows NT\CurrentVersion\Schedule\TaskCache\Tasks\{CECDC345-7460-4A15-9D8B-DAC3F9CC5368}" '/f'
& 'reg' 'delete' "HKEY_LOCAL_MACHINE\zSOFTWARE\Microsoft\Windows NT\CurrentVersion\Schedule\TaskCache\Tasks\{E0F10DCF-44AD-40E8-9370-FB5DA59F93FB}" '/f'
& 'reg' 'delete' 'HKLM\zSYSTEM\ControlSet001\Services\WaaSMedicSVC' '/f'
& 'reg' 'delete' 'HKLM\zSYSTEM\ControlSet001\Services\UsoSvc' '/f'
Set-RegistryValue -KeyPath 'HKEY_LOCAL_MACHINE\zSOFTWARE\Policies\Microsoft\Windows\WindowsUpdate\AU' -ValueName 'NoAutoUpdate' -ValueType 'REG_DWORD' -ValueData '1' -Description "Disable automatic updates"
Write-Host "Disabling Windows Defender"
# Set registry values for Windows Defender services
$servicePaths = @(
"WinDefend",
"WdNisSvc",
"WdNisDrv",
"WdFilter",
"Sense"
)
foreach ($path in $servicePaths) {
try {
if (Test-Path "HKLM:\zSYSTEM\ControlSet001\Services\$path") {
Set-ItemProperty -Path "HKLM:\zSYSTEM\ControlSet001\Services\$path" -Name "Start" -Value 4
} else {
Write-Host "Warning: Service path not found: $path"
}
}
catch {
Write-Host "Warning: Could not modify service $path - $($_.Exception.Message)"
}
}
Set-RegistryValue -KeyPath 'HKLM\zSOFTWARE\Microsoft\Windows\CurrentVersion\Policies\Explorer' -ValueName 'SettingsPageVisibility' -ValueType 'REG_SZ' -ValueData 'hide:virus;windowsupdate;mobile-devices;gaming;cortana;search;maps;yourinfo;workplace;easeofaccess;recovery;troubleshoot;backup;sync;findmydevice;developers;activation;deviceencryption' -Description "Hide rarely used Settings pages, showing only basic functionality"
Write-Host "Tweaking complete!"
Write-Host "Unmounting Registry..."
$regKey.Close()
reg unload HKLM\zCOMPONENTS >null
reg unload HKLM\zDEFAULT >null
reg unload HKLM\zNTUSER >null
reg unload HKLM\zSOFTWARE
reg unload HKLM\zSYSTEM >null
$replaceBranding = $true # Set to $false to skip branding replacement
if ($replaceBranding) {
Write-Host "Replacing system files for OEM branding..."
& 'takeown' '/f' "$ScratchDisk\scratchdir\Windows\Branding\Basebrd\basebrd.dll" | Out-Null
& 'icacls' "$ScratchDisk\scratchdir\Windows\Branding\Basebrd\basebrd.dll" '/grant' "$($adminGroup.Value):(F)" '/C' | Out-Null
& 'takeown' '/f' "$ScratchDisk\scratchdir\Windows\Branding\Basebrd\en-US\basebrd.dll.mui" | Out-Null
& 'icacls' "$ScratchDisk\scratchdir\Windows\Branding\Basebrd\en-US\basebrd.dll.mui" '/grant' "$($adminGroup.Value):(F)" '/C' | Out-Null
& 'takeown' '/f' "$ScratchDisk\scratchdir\Windows\Branding\shellbrd\shellbrd.dll" | Out-Null
& 'icacls' "$ScratchDisk\scratchdir\Windows\Branding\shellbrd\shellbrd.dll" '/grant' "$($adminGroup.Value):(F)" '/C' | Out-Null
Copy-Item -Path "$PSScriptRoot\includes\branding-resources\system\basebrd.dll" -Destination "$ScratchDisk\scratchdir\Windows\Branding\Basebrd\basebrd.dll" -Force | Out-Null
Copy-Item -Path "$PSScriptRoot\includes\branding-resources\system\basebrd.dll.mui" -Destination "$ScratchDisk\scratchdir\Windows\Branding\Basebrd\en-US\basebrd.dll.mui" -Force | Out-Null
Copy-Item -Path "$PSScriptRoot\includes\branding-resources\system\shellbrd.dll" -Destination "$ScratchDisk\scratchdir\Windows\Branding\shellbrd\shellbrd.dll" -Force | Out-Null
$brandingBootRes = "$PSScriptRoot\includes\branding-resources\system\bootres.dll"
if (Test-Path $brandingBootRes) {
Write-Host "Copying bootres.dll..."
foreach ($bootresPath in @(
"$ScratchDisk\scratchdir\Windows\Boot\EFI\bootres.dll",
"$ScratchDisk\scratchdir\Windows\Boot\PCAT\bootres.dll"
)) {
if (Test-Path $bootresPath) {
& 'takeown' '/f' $bootresPath | Out-Null
& 'icacls' $bootresPath '/grant' "$($adminGroup.Value):(F)" '/C' | Out-Null
Copy-Item -Path $brandingBootRes -Destination $bootresPath -Force | Out-Null
}
}
}
}
Write-Host "Cleaning up image..."
& 'dism' '/English' "/image:$ScratchDisk\scratchdir" '/Cleanup-Image' '/StartComponentCleanup' '/ResetBase' >null
Write-Host "Cleanup complete."
Write-Host ' '
Write-Host "Unmounting image..."
& 'dism' '/English' '/unmount-image' "/mountdir:$ScratchDisk\scratchdir" '/commit'
Write-Host "Exporting image..."
& 'dism' '/English' '/Export-Image' "/SourceImageFile:$ScratchDisk\tiny11\sources\install.wim" "/SourceIndex:$index" "/DestinationImageFile:$ScratchDisk\tiny11\sources\install2.wim" '/compress:max'
Remove-Item -Path "$ScratchDisk\tiny11\sources\install.wim" -Force >null
Rename-Item -Path "$ScratchDisk\tiny11\sources\install2.wim" -NewName "install.wim" >null
Write-Host "Windows image completed. Continuing with boot.wim."
Start-Sleep -Seconds 2
Clear-Host
Write-Host "Mounting boot image:"
$wimFilePath = "$ScratchDisk\tiny11\sources\boot.wim"
& takeown "/F" $wimFilePath >null
& icacls $wimFilePath "/grant" "$($adminGroup.Value):(F)"
Set-ItemProperty -Path $wimFilePath -Name IsReadOnly -Value $false
& 'dism' '/English' '/mount-image' "/imagefile:$ScratchDisk\tiny11\sources\boot.wim" '/index:2' "/mountdir:$ScratchDisk\scratchdir"
Write-Host "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
Write-Host "Bypassing system requirements(on the setup image):"
Set-RegistryValue -KeyPath 'HKLM\zDEFAULT\Control Panel\UnsupportedHardwareNotificationCache' -ValueName 'SV1' -ValueType 'REG_DWORD' -ValueData '0' -Description "Setup image unsupported hardware notification SV1"
Set-RegistryValue -KeyPath 'HKLM\zDEFAULT\Control Panel\UnsupportedHardwareNotificationCache' -ValueName 'SV2' -ValueType 'REG_DWORD' -ValueData '0' -Description "Setup image unsupported hardware notification SV2"
Set-RegistryValue -KeyPath 'HKLM\zNTUSER\Control Panel\UnsupportedHardwareNotificationCache' -ValueName 'SV1' -ValueType 'REG_DWORD' -ValueData '0' -Description "Setup image user unsupported hardware notification SV1"
Set-RegistryValue -KeyPath 'HKLM\zNTUSER\Control Panel\UnsupportedHardwareNotificationCache' -ValueName 'SV2' -ValueType 'REG_DWORD' -ValueData '0' -Description "Setup image user unsupported hardware notification SV2"
Set-RegistryValue -KeyPath 'HKLM\zSYSTEM\Setup\LabConfig' -ValueName 'BypassCPUCheck' -ValueType 'REG_DWORD' -ValueData '1' -Description "Setup image bypass CPU check"
Set-RegistryValue -KeyPath 'HKLM\zSYSTEM\Setup\LabConfig' -ValueName 'BypassRAMCheck' -ValueType 'REG_DWORD' -ValueData '1' -Description "Setup image bypass RAM check"
Set-RegistryValue -KeyPath 'HKLM\zSYSTEM\Setup\LabConfig' -ValueName 'BypassSecureBootCheck' -ValueType 'REG_DWORD' -ValueData '1' -Description "Setup image bypass Secure Boot check"
Set-RegistryValue -KeyPath 'HKLM\zSYSTEM\Setup\LabConfig' -ValueName 'BypassStorageCheck' -ValueType 'REG_DWORD' -ValueData '1' -Description "Setup image bypass storage check"
Set-RegistryValue -KeyPath 'HKLM\zSYSTEM\Setup\LabConfig' -ValueName 'BypassTPMCheck' -ValueType 'REG_DWORD' -ValueData '1' -Description "Setup image bypass TPM check"
Set-RegistryValue -KeyPath 'HKLM\zSYSTEM\Setup\MoSetup' -ValueName 'AllowUpgradesWithUnsupportedTPMOrCPU' -ValueType 'REG_DWORD' -ValueData '1' -Description "Setup image allow upgrades with unsupported TPM or CPU"
Set-RegistryValue -KeyPath 'HKEY_LOCAL_MACHINE\zSYSTEM\Setup' -ValueName 'CmdLine' -ValueType 'REG_SZ' -ValueData 'X:\sources\setup.exe' -Description "Setup command line"
Write-Host "Tweaking complete!"
Write-Host "Unmounting Registry..."
$regKey.Close()
reg unload HKLM\zCOMPONENTS >null
reg unload HKLM\zDEFAULT >null
reg unload HKLM\zNTUSER >null
$regKey.Close()
reg unload HKLM\zSOFTWARE
reg unload HKLM\zSYSTEM >null
if ($replaceBranding -and (Test-Path $brandingBootRes)) {
Write-Host "Copying bootres.dll to boot image..."
foreach ($bootresPath in @(
"$ScratchDisk\scratchdir\Windows\Boot\EFI\bootres.dll",
"$ScratchDisk\scratchdir\Windows\Boot\PCAT\bootres.dll",
"$ScratchDisk\scratchdir\Windows\Boot\Resources\bootres.dll"
)) {
if (Test-Path $bootresPath) {
& 'takeown' '/f' $bootresPath | Out-Null
& 'icacls' $bootresPath '/grant' "$($adminGroup.Value):(F)" '/C' | Out-Null
Copy-Item -Path $brandingBootRes -Destination $bootresPath -Force | Out-Null
}
}
}
Write-Host "Unmounting image..."
& 'dism' '/English' '/unmount-image' "/mountdir:$ScratchDisk\scratchdir" '/commit'
Clear-Host
Write-Host "Exporting ESD. This may take a while..."
& dism /Export-Image /SourceImageFile:"$ScratchDisk\tiny11\sources\install.wim" /SourceIndex:1 /DestinationImageFile:"$ScratchDisk\tiny11\sources\install.esd" /Compress:recovery
Remove-Item "$ScratchDisk\tiny11\sources\install.wim" > $null 2>&1
Write-Host "The tiny11 image is now completed. Proceeding with the making of the ISO..."
Write-Host "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-Host "Will be using oscdimg.exe from system ADK."
$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)) {
Write-Host "Downloading oscdimg.exe..."
Invoke-WebRequest -Uri $url -OutFile $localOSCDIMGPath
if (Test-Path $localOSCDIMGPath) {
Write-Host "oscdimg.exe downloaded successfully."
} else {
Write-Error "Failed to download oscdimg.exe."
exit 1
}
} 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\tiny11core.iso"
# Finishing up
Write-Host "Creation completed! Press any key to exit the script..."
Read-Host "Press Enter to continue"
Write-Host "Performing Cleanup..."
Remove-Item -Path "$ScratchDisk\tiny11" -Recurse -Force >null
Remove-Item -Path "$ScratchDisk\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."
}