Remove microwin (#3999)

* Delete microwin functions

* Update main.ps1

* Remove oscdimg.exe which is used by microwin

* Delete config/autounattend.xml

* Update .gitignore

* Update bug_report.yaml

* Update themes.json

* Update Invoke-WinUtilFontScaling.ps1

* Update Invoke-AutoConfigDialog.ps1

* Update Invoke-WPFButton.ps1

* Update inputXML.xaml

* Delete docs/assets/images/microwin directory

* Delete docs/assets/images/MicroWinScreen.png

* Delete docs/assets/images/Microwin-Dark.png

* Delete docs/assets/images/Microwin-Light.png

* Update faq.md

* Update KnownIssues.md

* Update getting-started.md

* Update _index.md

* Delete docs/content/userguide/microwin directory

* Update architecture.md

---------

Co-authored-by: Chris Titus <dfm.titus@gmail.com>
This commit is contained in:
Gabi
2026-02-06 18:29:10 +02:00
committed by GitHub
parent ac116d7083
commit fcc5481477
42 changed files with 7 additions and 3270 deletions

View File

@@ -1,53 +0,0 @@
function Copy-Files {
<#
.DESCRIPTION
Copies the contents of a given ISO file to a given destination
.PARAMETER Path
The source of the files to copy
.PARAMETER Destination
The destination to copy the files to
.PARAMETER Recurse
Determines whether or not to copy all files of the ISO file, including those in subdirectories
.PARAMETER Force
Determines whether or not to overwrite existing files
.EXAMPLE
Copy-Files "D:" "C:\ISOFile" -Recurse -Force
#>
param (
[string]$Path,
[string]$Destination,
[switch]$Recurse = $false,
[switch]$Force = $false
)
try {
$files = Get-ChildItem -Path $path -Recurse:$recurse
Write-Host "Copy $($files.Count) file(s) from $path to $destination"
foreach ($file in $files) {
$status = "Copying file {0} of {1}: {2}" -f $counter, $files.Count, $file.Name
Write-Progress -Activity "Copy disc image files" -Status $status -PercentComplete ($counter++/$files.count*100)
$restpath = $file.FullName -Replace $path, ''
if ($file.PSIsContainer -eq $true) {
Write-Debug "Creating $($destination + $restpath)"
New-Item ($destination+$restpath) -Force:$force -Type Directory -ErrorAction SilentlyContinue
} else {
Write-Debug "Copy from $($file.FullName) to $($destination+$restpath)"
Copy-Item $file.FullName ($destination+$restpath) -ErrorAction SilentlyContinue -Force:$force
Set-ItemProperty -Path ($destination+$restpath) -Name IsReadOnly -Value $false
}
}
Write-Progress -Activity "Copy disc image files" -Status "Ready" -Completed
} catch {
Write-Host "Unable to Copy all the files due to an unhandled exception" -ForegroundColor Yellow
Write-Host "Error information: $($_.Exception.Message)`n" -ForegroundColor Yellow
Write-Host "Additional information:" -ForegroundColor Yellow
Write-Host $PSItem.Exception.StackTrace
# Write possible suggestions
Write-Host "`nIf you are using an antivirus, try configuring exclusions"
}
}

View File

@@ -1,624 +0,0 @@
function Invoke-Microwin {
<#
.DESCRIPTION
Invoke MicroWin routines...
#>
if($sync.ProcessRunning) {
$msg = "GetIso process is currently running."
[System.Windows.MessageBox]::Show($msg, "Winutil", [System.Windows.MessageBoxButton]::OK, [System.Windows.MessageBoxImage]::Warning)
return
}
# Define the constants for Windows API
Add-Type @"
using System;
using System.Runtime.InteropServices;
public class PowerManagement {
[DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
public static extern EXECUTION_STATE SetThreadExecutionState(EXECUTION_STATE esFlags);
[FlagsAttribute]
public enum EXECUTION_STATE : uint {
ES_SYSTEM_REQUIRED = 0x00000001,
ES_DISPLAY_REQUIRED = 0x00000002,
ES_CONTINUOUS = 0x80000000,
}
}
"@
# Prevent the machine from sleeping
[PowerManagement]::SetThreadExecutionState([PowerManagement]::EXECUTION_STATE::ES_CONTINUOUS -bor [PowerManagement]::EXECUTION_STATE::ES_SYSTEM_REQUIRED -bor [PowerManagement]::EXECUTION_STATE::ES_DISPLAY_REQUIRED)
# Ask the user where to save the file
$SaveDialog = New-Object System.Windows.Forms.SaveFileDialog
$SaveDialog.InitialDirectory = [Environment]::GetFolderPath('Desktop')
$SaveDialog.Filter = "ISO images (*.iso)|*.iso"
$SaveDialog.ShowDialog() | Out-Null
if ($SaveDialog.FileName -eq "") {
$msg = "No file name for the target image was specified"
Write-Host $msg
Invoke-MicrowinBusyInfo -action "warning" -message $msg
Set-WinUtilTaskbaritem -state "Error" -value 1 -overlay "warning"
return
}
Set-WinUtilTaskbaritem -state "Indeterminate" -overlay "logo"
Invoke-MicrowinBusyInfo -action "wip" -message "Busy..." -interactive $false
Write-Host "Target ISO location: $($SaveDialog.FileName)"
$index = $sync.MicrowinWindowsFlavors.SelectedValue.Split(":")[0].Trim()
Write-Host "Index chosen: '$index' from $($sync.MicrowinWindowsFlavors.SelectedValue)"
$injectDrivers = $sync.MicrowinInjectDrivers.IsChecked
$importDrivers = $sync.MicrowinImportDrivers.IsChecked
$importVirtIO = $sync.MicrowinCopyVirtIO.IsChecked
$mountDir = $sync.MicrowinMountDir.Text
$scratchDir = $sync.MicrowinScratchDir.Text
# Detect if the Windows image is an ESD file and convert it to WIM
if (-not (Test-Path -Path "$mountDir\sources\install.wim" -PathType Leaf) -and (Test-Path -Path "$mountDir\sources\install.esd" -PathType Leaf)) {
Write-Host "Exporting Windows image to a WIM file, keeping the index we want to work on. This can take several minutes, depending on the performance of your computer..."
try {
Export-WindowsImage -SourceImagePath "$mountDir\sources\install.esd" -SourceIndex $index -DestinationImagePath "$mountDir\sources\install.wim" -CompressionType "Max"
} catch {
# Usually the case if it can't find unattend.dll on the host system. Guys, fix your corrupt messes that are your installations!
dism /english /export-image /sourceimagefile="$mountDir\sources\install.esd" /sourceindex=$index /destinationimagefile="$mountDir\sources\install.wim" /compress:max
}
if ($?) {
Remove-Item -Path "$mountDir\sources\install.esd" -Force
# Since we've already exported the image index we wanted, switch to the first one
$index = 1
} else {
$msg = "The export process has failed and MicroWin processing cannot continue"
Write-Host $msg
Set-WinUtilTaskbaritem -state "Error" -value 1 -overlay "warning"
Invoke-MicrowinBusyInfo -action "warning" -message $msg
[System.Windows.MessageBox]::Show($msg, "Winutil", [System.Windows.MessageBoxButton]::OK, [System.Windows.MessageBoxImage]::Error)
return
}
}
$imgVersion = (Get-WindowsImage -ImagePath "$mountDir\sources\install.wim" -Index $index).Version
# Windows Setup is the second index in the boot image.
$bootVersion = (Get-WindowsImage -ImagePath "$mountDir\sources\boot.wim" -Index 2).Version
Write-Host "The Windows Image Build Version is: $imgVersion"
Write-Host "The WinPE boot image Build Version is: $bootVersion"
# Detect image version to avoid performing MicroWin processing on Windows 8 and earlier
if ((Microwin-TestCompatibleImage $imgVersion $([System.Version]::new(10,0,10240,0))) -eq $false) {
$msg = "This image is not compatible with MicroWin processing. Make sure it isn't a Windows 8 or earlier image."
$dlg_msg = $msg + "`n`nIf you want more information, the version of the image selected is $($imgVersion)`n`nIf an image has been incorrectly marked as incompatible, report an issue to the developers."
Write-Host $msg
[System.Windows.MessageBox]::Show($dlg_msg, "Winutil", [System.Windows.MessageBoxButton]::OK, [System.Windows.MessageBoxImage]::Exclamation)
Set-WinUtilTaskbaritem -state "Error" -value 1 -overlay "warning"
Invoke-MicrowinBusyInfo -action "warning" -message $msg
return
}
# Detect whether the image to process contains Windows 10 and show warning
if ((Microwin-TestCompatibleImage $imgVersion $([System.Version]::new(10,0,21996,1))) -eq $false) {
$msg = "Windows 10 has been detected in the image you want to process. While you can continue, Windows 10 is not a recommended target for MicroWin, and you may not get the full experience."
$dlg_msg = $msg
Write-Host $msg
[System.Windows.MessageBox]::Show($dlg_msg, "Winutil", [System.Windows.MessageBoxButton]::OK, [System.Windows.MessageBoxImage]::Exclamation)
}
$mountDirExists = Test-Path $mountDir
$scratchDirExists = Test-Path $scratchDir
if (-not $mountDirExists -or -not $scratchDirExists) {
$msg = "Required directories '$mountDirExists' '$scratchDirExists' and do not exist."
Write-Error $msg
Set-WinUtilTaskbaritem -state "Error" -value 1 -overlay "warning"
Invoke-MicrowinBusyInfo -action "warning" -message $msg
return
}
try {
Write-Host "Mounting Windows image. This may take a while."
Mount-WindowsImage -ImagePath "$mountDir\sources\install.wim" -Index $index -Path "$scratchDir"
if ($?) {
Write-Host "The Windows image has been mounted successfully. Continuing processing..."
} else {
$msg = "Could not mount image. Exiting..."
Write-Host $msg
Set-WinUtilTaskbaritem -state "Error" -value 1 -overlay "warning"
Invoke-MicrowinBusyInfo -action "warning" -message $msg
return
}
if ($importDrivers) {
Write-Host "Exporting drivers from active installation..."
if (Test-Path "$env:TEMP\DRV_EXPORT") {
Remove-Item "$env:TEMP\DRV_EXPORT" -Recurse -Force
}
if (($injectDrivers -and (Test-Path "$($sync.MicrowinDriverLocation.Text)"))) {
Write-Host "Using specified driver source..."
dism /english /online /export-driver /destination="$($sync.MicrowinDriverLocation.Text)" | Out-Host
if ($?) {
# Don't add exported drivers yet, that is run later
Write-Host "Drivers have been exported successfully."
} else {
Write-Host "Failed to export drivers."
}
} else {
New-Item -Path "$env:TEMP\DRV_EXPORT" -ItemType Directory -Force
dism /english /online /export-driver /destination="$env:TEMP\DRV_EXPORT" | Out-Host
if ($?) {
Write-Host "Adding exported drivers..."
dism /english /image="$scratchDir" /add-driver /driver="$env:TEMP\DRV_EXPORT" /recurse | Out-Host
} else {
Write-Host "Failed to export drivers. Continuing without importing them..."
}
if (Test-Path "$env:TEMP\DRV_EXPORT") {
Remove-Item "$env:TEMP\DRV_EXPORT" -Recurse -Force
}
}
}
if ($injectDrivers) {
$driverPath = $sync.MicrowinDriverLocation.Text
if (Test-Path $driverPath) {
Write-Host "Adding Windows Drivers image($scratchDir) drivers($driverPath) "
dism /English /image:$scratchDir /add-driver /driver:$driverPath /recurse | Out-Host
} else {
Write-Host "Path to drivers is invalid continuing without driver injection"
}
}
Write-Host "Disabling WPBT Execution"
reg load HKLM\zSYSTEM "$($scratchDir)\Windows\System32\config\SYSTEM"
reg add "HKLM\zSYSTEM\ControlSet001\Control\Session Manager" /v DisableWpbtExecution /t REG_DWORD /d 1 /f
reg unload HKLM\zSYSTEM
Write-Host "Skipping first logon animation..."
reg load HKLM\zSOFTWARE "$($scratchDir)\Windows\System32\config\SOFTWARE"
reg add "HKLM\zSOFTWARE\Microsoft\Active Setup\Installed Components\CMP_NoFla" /f
reg add "HKLM\zSOFTWARE\Microsoft\Active Setup\Installed Components\CMP_NoFla" /f /ve /t REG_SZ /d "Stop First Logon Animation Process"
reg add "HKLM\zSOFTWARE\Microsoft\Active Setup\Installed Components\CMP_NoFla" /f /v StubPath /t REG_EXPAND_SZ /d '\"%WINDIR%\System32\cmd.exe\" /C \"taskkill /f /im firstlogonanim.exe\"'
reg unload HKLM\zSOFTWARE
# We have to prepare the target system to accept the diagnostics script
reg load HKLM\zSOFTWARE "$($scratchDir)\Windows\System32\config\SOFTWARE"
reg add "HKLM\zSOFTWARE\WinUtil" /f
reg add "HKLM\zSOFTWARE\WinUtil" /f /v "ToolboxVersion" /t REG_SZ /d "$($sync.version)"
reg add "HKLM\zSOFTWARE\WinUtil" /f /v "MicroWinBuildDate" /t REG_SZ /d "$((Get-Date).ToString('yyMMdd-HHmm'))"
# REAL software developers set execution policies to unrestricted but, because we're targeting
# mainstream population, we have to lower the level of "riskiness" -- set remotesigned; at least that
# lets us run PWSH scripts that WE create. Execution policies don't really make sense anyway if common sense
# is lacking.
reg add "HKLM\zSOFTWARE\Microsoft\PowerShell\1\ShellIds\Microsoft.PowerShell" /v "ExecutionPolicy" /t REG_SZ /d "RemoteSigned" /f
reg unload HKLM\zSOFTWARE
if ($importVirtIO) {
Write-Host "Copying VirtIO drivers..."
Microwin-CopyVirtIO
}
Write-Host "Remove Features from the image"
Microwin-RemoveFeatures -UseCmdlets $true
Write-Host "Removing features complete!"
Write-Host "Removing OS packages"
Microwin-RemovePackages -UseCmdlets $true
Write-Host "Removing Appx Bloat"
Microwin-RemoveProvisionedPackages -UseCmdlets $true
# Detect Windows 11 24H2 and add dependency to FileExp to prevent Explorer look from going back - thanks @WitherOrNot and @thecatontheceiling
# ----- UPDATE UPDATE UPDATE: they fixed this in 10.0.26100.7019. DO NOT DO THIS OTHERWISE IT BREAKS EXPLORER AGAIN BECAUSE THE CHEEKY LITTLE
# ----- PoS CHANGED APPRUNTIME.CBS TO APPRUNTIME.CBS.1.6. Thing is, we don't need to patch this in those builds because it no longer breaks
# ----- when you don't patch.
if (((Microwin-TestCompatibleImage $imgVersion $([System.Version]::new(10,0,26100,1))) -eq $true) -and ((Microwin-TestCompatibleImage $imgVersion $([System.Version]::new(10,0,26100,7019))) -eq $false)) {
try {
if (Test-Path "$scratchDir\Windows\SystemApps\MicrosoftWindows.Client.FileExp_cw5n1h2txyewy\appxmanifest.xml" -PathType Leaf) {
# Found the culprit. Do the following:
# 1. Take ownership of the file, from TrustedInstaller to Administrators
takeown /F "$scratchDir\Windows\SystemApps\MicrosoftWindows.Client.FileExp_cw5n1h2txyewy\appxmanifest.xml" /A
# 2. Set ACLs so that we can write to it
icacls "$scratchDir\Windows\SystemApps\MicrosoftWindows.Client.FileExp_cw5n1h2txyewy\appxmanifest.xml" /grant "$(Microwin-GetLocalizedUsers -admins $true):(M)" | Out-Host
# 3. Open the file and do the modification
$appxManifest = Get-Content -Path "$scratchDir\Windows\SystemApps\MicrosoftWindows.Client.FileExp_cw5n1h2txyewy\appxmanifest.xml"
$originalLine = $appxManifest[13]
$dependency = "`n <PackageDependency Name=`"Microsoft.WindowsAppRuntime.CBS`" MinVersion=`"1.0.0.0`" Publisher=`"CN=Microsoft Corporation, O=Microsoft Corporation, L=Redmond, S=Washington, C=US`" />"
$appxManifest[13] = "$originalLine$dependency"
Set-Content -Path "$scratchDir\Windows\SystemApps\MicrosoftWindows.Client.FileExp_cw5n1h2txyewy\appxmanifest.xml" -Value $appxManifest -Force -Encoding utf8
}
}
catch {
# Fall back to what we used to do: delayed disablement
Enable-WindowsOptionalFeature -Path "$scratchDir" -FeatureName "Recall"
}
}
Microwin-RemoveFileOrDirectory -pathToDelete "$($scratchDir)\Windows\System32\LogFiles\WMI\RtBackup" -Directory
Microwin-RemoveFileOrDirectory -pathToDelete "$($scratchDir)\Windows\DiagTrack" -Directory
Microwin-RemoveFileOrDirectory -pathToDelete "$($scratchDir)\Windows\InboxApps" -Directory
Microwin-RemoveFileOrDirectory -pathToDelete "$($scratchDir)\Windows\System32\LocationNotificationWindows.exe"
Microwin-RemoveFileOrDirectory -pathToDelete "$($scratchDir)\Program Files (x86)\Windows Media Player" -Directory
Microwin-RemoveFileOrDirectory -pathToDelete "$($scratchDir)\Program Files\Windows Media Player" -Directory
Microwin-RemoveFileOrDirectory -pathToDelete "$($scratchDir)\Program Files (x86)\Windows Mail" -Directory
Microwin-RemoveFileOrDirectory -pathToDelete "$($scratchDir)\Program Files\Windows Mail" -Directory
Microwin-RemoveFileOrDirectory -pathToDelete "$($scratchDir)\Program Files (x86)\Internet Explorer" -Directory
Microwin-RemoveFileOrDirectory -pathToDelete "$($scratchDir)\Program Files\Internet Explorer" -Directory
Microwin-RemoveFileOrDirectory -pathToDelete "$($scratchDir)\Windows\GameBarPresenceWriter"
Microwin-RemoveFileOrDirectory -pathToDelete "$($scratchDir)\Windows\System32\OneDriveSetup.exe"
Microwin-RemoveFileOrDirectory -pathToDelete "$($scratchDir)\Windows\System32\OneDrive.ico"
Microwin-RemoveFileOrDirectory -pathToDelete "$($scratchDir)\Windows\SystemApps" -mask "*narratorquickstart*" -Directory
Microwin-RemoveFileOrDirectory -pathToDelete "$($scratchDir)\Windows\SystemApps" -mask "*ParentalControls*" -Directory
Write-Host "Removal complete!"
Write-Host "Create unattend.xml"
if (($sync.MicrowinAutoConfigBox.Text -ne "") -and (Test-Path "$($sync.MicrowinAutoConfigBox.Text)"))
{
try
{
Write-Host "A configuration file has been specified. Copying to WIM file..."
Copy-Item "$($sync.MicrowinAutoConfigBox.Text)" "$($scratchDir)\winutil-config.json"
}
catch
{
Write-Host "The config file could not be copied. Continuing without it..."
}
}
# Create unattended answer file with user information - Check condition to learn more about this functionality
if ($sync.MicrowinUserName.Text -eq "")
{
Microwin-NewUnattend -userName "User"
}
else
{
if ($sync.MicrowinUserPassword.Password -eq "")
{
Microwin-NewUnattend -userName "$($sync.MicrowinUserName.Text)"
}
else
{
Microwin-NewUnattend -userName "$($sync.MicrowinUserName.Text)" -userPassword "$($sync.MicrowinUserPassword.Password)"
}
}
Write-Host "Done Create unattend.xml"
Write-Host "Copy unattend.xml file into the ISO"
New-Item -ItemType Directory -Force -Path "$($scratchDir)\Windows\Panther"
Copy-Item "$env:temp\unattend.xml" "$($scratchDir)\Windows\Panther\unattend.xml" -force
New-Item -ItemType Directory -Force -Path "$($scratchDir)\Windows\System32\Sysprep"
Copy-Item "$env:temp\unattend.xml" "$($scratchDir)\Windows\System32\Sysprep\unattend.xml" -force
Write-Host "Done Copy unattend.xml"
Write-Host "Create FirstRun"
Microwin-NewFirstRun
Write-Host "Done create FirstRun"
Write-Host "Copy FirstRun.ps1 into the ISO"
Copy-Item "$env:temp\FirstStartup.ps1" "$($scratchDir)\Windows\FirstStartup.ps1" -force
Write-Host "Done copy FirstRun.ps1"
Write-Host "Copy checkinstall.cmd into the ISO"
Microwin-NewCheckInstall
Copy-Item "$env:temp\checkinstall.cmd" "$($scratchDir)\Windows\checkinstall.cmd" -force
Write-Host "Done copy checkinstall.cmd"
Write-Host "Creating a directory that allows to bypass Wifi setup"
New-Item -ItemType Directory -Force -Path "$($scratchDir)\Windows\System32\OOBE\BYPASSNRO"
Write-Host "Loading registry"
reg load HKLM\zDEFAULT "$($scratchDir)\Windows\System32\config\default"
reg load HKLM\zNTUSER "$($scratchDir)\Users\Default\ntuser.dat"
reg load HKLM\zSOFTWARE "$($scratchDir)\Windows\System32\config\SOFTWARE"
reg load HKLM\zSYSTEM "$($scratchDir)\Windows\System32\config\SYSTEM"
Write-Host "Disabling Teams"
reg add "HKLM\zSOFTWARE\Microsoft\Windows\CurrentVersion\Communications" /v "ConfigureChatAutoInstall" /t REG_DWORD /d 0 /f >$null 2>&1
reg add "HKLM\zSOFTWARE\Policies\Microsoft\Windows\Windows Chat" /v ChatIcon /t REG_DWORD /d 2 /f >$null 2>&1
reg add "HKLM\zNTUSER\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\Advanced" /v "TaskbarMn" /t REG_DWORD /d 0 /f >$null 2>&1
reg query "HKLM\zSOFTWARE\Microsoft\Windows\CurrentVersion\Communications" /v "ConfigureChatAutoInstall" >$null 2>&1
Write-Host "Done disabling Teams"
Write-Host "Fix Windows Volume Mixer Issue"
reg add "HKLM\zNTUSER\Software\Microsoft\Internet Explorer\LowRegistry\Audio\PolicyConfig\PropertyStore" /f
Write-Host "Bypassing system requirements (system image)"
reg add "HKLM\zDEFAULT\Control Panel\UnsupportedHardwareNotificationCache" /v "SV1" /t REG_DWORD /d 0 /f
reg add "HKLM\zDEFAULT\Control Panel\UnsupportedHardwareNotificationCache" /v "SV2" /t REG_DWORD /d 0 /f
reg add "HKLM\zNTUSER\Control Panel\UnsupportedHardwareNotificationCache" /v "SV1" /t REG_DWORD /d 0 /f
reg add "HKLM\zNTUSER\Control Panel\UnsupportedHardwareNotificationCache" /v "SV2" /t REG_DWORD /d 0 /f
reg add "HKLM\zSYSTEM\Setup\LabConfig" /v "BypassCPUCheck" /t REG_DWORD /d 1 /f
reg add "HKLM\zSYSTEM\Setup\LabConfig" /v "BypassRAMCheck" /t REG_DWORD /d 1 /f
reg add "HKLM\zSYSTEM\Setup\LabConfig" /v "BypassSecureBootCheck" /t REG_DWORD /d 1 /f
reg add "HKLM\zSYSTEM\Setup\LabConfig" /v "BypassStorageCheck" /t REG_DWORD /d 1 /f
reg add "HKLM\zSYSTEM\Setup\LabConfig" /v "BypassTPMCheck" /t REG_DWORD /d 1 /f
reg add "HKLM\zSYSTEM\Setup\MoSetup" /v "AllowUpgradesWithUnsupportedTPMOrCPU" /t REG_DWORD /d 1 /f
# Prevent Windows Update Installing so called Expedited Apps - 24H2 and newer
if ((Microwin-TestCompatibleImage $imgVersion $([System.Version]::new(10,0,26100,1))) -eq $true) {
@(
'EdgeUpdate',
'DevHomeUpdate',
'OutlookUpdate',
'CrossDeviceUpdate'
) | ForEach-Object {
Write-Host "Removing Windows Expedited App: $_"
reg delete "HKLM\zSOFTWARE\Microsoft\WindowsUpdate\Orchestrator\UScheduler_Oobe\$_" /f | Out-Null
}
}
reg add "HKLM\zSOFTWARE\Microsoft\Windows\CurrentVersion\Search" /v "SearchboxTaskbarMode" /t REG_DWORD /d 0 /f
Write-Host "Setting all services to start manually"
reg add "HKLM\zSOFTWARE\CurrentControlSet\Services" /v Start /t REG_DWORD /d 3 /f
Write-Host "Enabling Local Accounts on OOBE"
reg add "HKLM\zSOFTWARE\Microsoft\Windows\CurrentVersion\OOBE" /v "BypassNRO" /t REG_DWORD /d "1" /f
Write-Host "Disabling Sponsored Apps"
reg add "HKLM\zNTUSER\SOFTWARE\Microsoft\Windows\CurrentVersion\ContentDeliveryManager" /v "OemPreInstalledAppsEnabled" /t REG_DWORD /d 0 /f
reg add "HKLM\zNTUSER\SOFTWARE\Microsoft\Windows\CurrentVersion\ContentDeliveryManager" /v "PreInstalledAppsEnabled" /t REG_DWORD /d 0 /f
reg add "HKLM\zNTUSER\SOFTWARE\Microsoft\Windows\CurrentVersion\ContentDeliveryManager" /v "SilentInstalledAppsEnabled" /t REG_DWORD /d 0 /f
reg add "HKLM\zSOFTWARE\Policies\Microsoft\Windows\CloudContent" /v "DisableWindowsConsumerFeatures" /t REG_DWORD /d 1 /f
reg add "HKLM\zSOFTWARE\Microsoft\PolicyManager\current\device\Start" /v "ConfigureStartPins" /t REG_SZ /d '{\"pinnedList\": [{}]}' /f
Write-Host "Done removing Sponsored Apps"
Write-Host "Disabling Reserved Storage"
reg add "HKLM\zSOFTWARE\Microsoft\Windows\CurrentVersion\ReserveManager" /v "ShippedWithReserves" /t REG_DWORD /d 0 /f
Write-Host "Showing file extensions..."
reg add "HKLM\zNTUSER\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\Advanced" /v "HideFileExt" /t REG_DWORD /d 0 /f
if ((Microwin-TestCompatibleImage $imgVersion $([System.Version]::new(10,0,21996,1))) -eq $false) {
# We're dealing with Windows 10. Configure sane desktop settings. NOTE: even though stuff to disable News and Interests is there,
# it doesn't seem to work, and I don't want to waste more time dealing with an operating system that will lose support in a year (2025)
# I invite anyone to work on improving stuff for News and Interests, but that won't be me!
Write-Host "Disabling Search Highlights..."
reg add "HKLM\zNTUSER\SOFTWARE\Microsoft\Windows\CurrentVersion\Feeds\DSB" /v "ShowDynamicContent" /t REG_DWORD /d 0 /f
reg add "HKLM\zNTUSER\SOFTWARE\Microsoft\Windows\CurrentVersion\SearchSettings" /v "IsDynamicSearchBoxEnabled" /t REG_DWORD /d 0 /f
reg add "HKLM\zSOFTWARE\Policies\Microsoft\Dsh" /v "AllowNewsAndInterests" /t REG_DWORD /d 0 /f
reg add "HKLM\zNTUSER\SOFTWARE\Microsoft\Windows\CurrentVersion\Search" /v "TraySearchBoxVisible" /t REG_DWORD /d 1 /f
reg add "HKLM\zSOFTWARE\Policies\Microsoft\Windows\Windows Feeds" /v "EnableFeeds" /t REG_DWORD /d 0 /f
}
} catch {
Write-Error "An unexpected error occurred: $_"
} finally {
Write-Host "Unmounting Registry..."
reg unload HKLM\zDEFAULT
reg unload HKLM\zNTUSER
reg unload HKLM\zSOFTWARE
reg unload HKLM\zSYSTEM
Write-Host "Cleaning up image..."
dism /English /image:$scratchDir /Cleanup-Image /StartComponentCleanup /ResetBase
Write-Host "Cleanup complete."
$committed = $false
$unmounted = $false
Write-Host "Saving image..."
try {
Save-WindowsImage -Path "$scratchDir"
$committed = $true
} catch {
do {
# we'll prevent stuff inside this loop from throwing exceptions and breaking from the loop.
try {
Save-WindowsImage -Path "$scratchDir"
$committed = $true
} catch {
Write-Host "Commit operation unsuccessful. Trying again after 3 seconds..."
Start-Sleep -Seconds 3
}
} until ($committed)
}
Write-Host "Unmounting image..."
try {
# because we've already saved the changes earlier, we can safely discard
Dismount-WindowsImage -Discard -Path "$scratchDir"
$unmounted = $true
} catch {
do {
# we'll prevent stuff inside this loop from throwing exceptions and breaking from the loop.
try {
Dismount-WindowsImage -Discard -Path "$scratchDir"
$unmounted = $true
} catch {
Write-Host "Unmount operation unsuccessful. Trying again after 3 seconds..."
Start-Sleep -Seconds 3
}
} until ($unmounted)
}
}
try {
Write-Host "Exporting image into $mountDir\sources\install2.wim"
try {
Export-WindowsImage -SourceImagePath "$mountDir\sources\install.wim" -SourceIndex $index -DestinationImagePath "$mountDir\sources\install2.wim" -CompressionType "Max"
} catch {
# Usually the case if it can't find unattend.dll on the host system. Guys, fix your corrupt messes that are your installations!
dism /english /export-image /sourceimagefile="$mountDir\sources\install.wim" /sourceindex=$index /destinationimagefile="$mountDir\sources\install2.wim" /compress:max
}
Write-Host "Remove old '$mountDir\sources\install.wim' and rename $mountDir\sources\install2.wim"
Remove-Item "$mountDir\sources\install.wim"
Rename-Item "$mountDir\sources\install2.wim" "$mountDir\sources\install.wim"
if (-not (Test-Path -Path "$mountDir\sources\install.wim")) {
$msg = "Something went wrong. Please report this bug to the devs."
Write-Error "$($msg) '$($mountDir)\sources\install.wim' doesn't exist"
Invoke-MicrowinBusyInfo -action "warning" -message $msg
Set-WinUtilTaskbaritem -state "Error" -value 1 -overlay "warning"
return
}
Write-Host "Windows image completed. Continuing with boot.wim."
# Next step boot image
Write-Host "Mounting boot image $mountDir\sources\boot.wim into $scratchDir"
Mount-WindowsImage -ImagePath "$mountDir\sources\boot.wim" -Index 2 -Path "$scratchDir"
if ($injectDrivers) {
$driverPath = $sync.MicrowinDriverLocation.Text
if (Test-Path $driverPath) {
Write-Host "Adding Windows Drivers image($scratchDir) drivers($driverPath) "
dism /English /image:$scratchDir /add-driver /driver:$driverPath /recurse | Out-Host
} else {
Write-Host "Path to drivers is invalid continuing without driver injection"
}
}
Write-Host "Loading registry..."
reg load HKLM\zDEFAULT "$($scratchDir)\Windows\System32\config\default" >$null
reg load HKLM\zNTUSER "$($scratchDir)\Users\Default\ntuser.dat" >$null
reg load HKLM\zSOFTWARE "$($scratchDir)\Windows\System32\config\SOFTWARE" >$null
reg load HKLM\zSYSTEM "$($scratchDir)\Windows\System32\config\SYSTEM" >$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
reg add "HKLM\zDEFAULT\Control Panel\UnsupportedHardwareNotificationCache" /v "SV2" /t REG_DWORD /d 0 /f
reg add "HKLM\zNTUSER\Control Panel\UnsupportedHardwareNotificationCache" /v "SV1" /t REG_DWORD /d 0 /f
reg add "HKLM\zNTUSER\Control Panel\UnsupportedHardwareNotificationCache" /v "SV2" /t REG_DWORD /d 0 /f
reg add "HKLM\zSYSTEM\Setup\LabConfig" /v "BypassCPUCheck" /t REG_DWORD /d 1 /f
reg add "HKLM\zSYSTEM\Setup\LabConfig" /v "BypassRAMCheck" /t REG_DWORD /d 1 /f
reg add "HKLM\zSYSTEM\Setup\LabConfig" /v "BypassSecureBootCheck" /t REG_DWORD /d 1 /f
reg add "HKLM\zSYSTEM\Setup\LabConfig" /v "BypassStorageCheck" /t REG_DWORD /d 1 /f
reg add "HKLM\zSYSTEM\Setup\LabConfig" /v "BypassTPMCheck" /t REG_DWORD /d 1 /f
reg add "HKLM\zSYSTEM\Setup\MoSetup" /v "AllowUpgradesWithUnsupportedTPMOrCPU" /t REG_DWORD /d 1 /f
# Fix Computer Restarted Unexpectedly Error on New Bare Metal Install
reg add "HKLM\zSYSTEM\Setup\Status\ChildCompletion" /v "setup.exe" /t REG_DWORD /d 3 /f
# Force old Setup on 24H2+ WinPE images due to personal preference; it's simply faster and
# more reliable than MoSetup. I simply can't stand that new setup system.
if ((Microwin-TestCompatibleImage $bootVersion $([System.Version]::new(10,0,26040,0))) -and (Test-Path -Path "$scratchDir\sources\setup.exe" -PathType Leaf)) {
reg add "HKLM\zSYSTEM\Setup" /f /v "CmdLine" /t REG_SZ /d "\sources\setup.exe"
}
} catch {
Write-Error "An unexpected error occurred: $_"
} finally {
Write-Host "Unmounting Registry..."
reg unload HKLM\zDEFAULT
reg unload HKLM\zNTUSER
reg unload HKLM\zSOFTWARE
reg unload HKLM\zSYSTEM
$committed = $false
$unmounted = $false
Write-Host "Saving image..."
try {
Save-WindowsImage -Path "$scratchDir"
$committed = $true
} catch {
do {
# we'll prevent stuff inside this loop from throwing exceptions and breaking from the loop.
try {
Save-WindowsImage -Path "$scratchDir"
$committed = $true
} catch {
Write-Host "Commit operation unsuccessful. Trying again after 3 seconds..."
Start-Sleep -Seconds 3
}
} until ($committed)
}
Write-Host "Unmounting image..."
try {
# because we've already saved the changes earlier, we can safely discard
Dismount-WindowsImage -Discard -Path "$scratchDir"
$unmounted = $true
} catch {
do {
# we'll prevent stuff inside this loop from throwing exceptions and breaking from the loop.
try {
Dismount-WindowsImage -Discard -Path "$scratchDir"
$unmounted = $true
} catch {
Write-Host "Unmount operation unsuccessful. Trying again after 3 seconds..."
Start-Sleep -Seconds 3
}
} until ($unmounted)
}
Write-Host "Creating ISO image"
$peToolsPath = ""
$adkKitsRoot = Microwin-GetKitsRoot -wow64environment $false
$adkKitsRoot_WOW64Environ = Microwin-GetKitsRoot -wow64environment $true
$expectedADKPath = "$($adkKitsRoot)Assessment and Deployment Kit"
$expectedADKPath_WOW64Environ = "$($adkKitsRoot_WOW64Environ)Assessment and Deployment Kit"
# if we downloaded oscdimg from github it will be in the temp directory so use it
# if it is not in temp it is part of ADK and is in global PATH so just set it to oscdimg.exe
$oscdimgPath = Join-Path $env:TEMP 'oscdimg.exe'
$oscdImgFound = Test-Path -Path "$oscdimgPath" -PathType Leaf
if ((-not ($oscdImgFound)) -and ((Microwin-TestKitsRootPaths -adkKitsRootPath "$expectedADKPath" -adkKitsRootPath_WOW64Environ "$expectedADKPath_WOW64Environ") -eq $true)) {
if ($expectedADKPath -ne "Assessment and Deployment Kit") { $peToolsPath = $expectedADKPath }
if (($peToolsPath -eq "") -and ($expectedADKPath_WOW64Environ -ne "Assessment and Deployment Kit")) { $peToolsPath = $expectedADKPath_WOW64Environ }
Write-Host "Using $peToolsPath as the Preinstallation Environment tools path..."
# Paths change depending on platform
if ([Environment]::Is64BitOperatingSystem) {
$oscdimgPath = "$peToolsPath\Deployment Tools\amd64\Oscdimg\oscdimg.exe"
} else {
$oscdimgPath = "$peToolsPath\Deployment Tools\x86\Oscdimg\oscdimg.exe"
}
}
Write-Host "[INFO] Using oscdimg.exe from: $oscdimgPath"
$oscdimgProc = Start-Process -FilePath "$oscdimgPath" -ArgumentList "-m -o -u2 -udfver102 -bootdata:2#p0,e,b`"$mountDir\boot\etfsboot.com`"#pEF,e,b`"$mountDir\efi\microsoft\boot\efisys.bin`" `"$mountDir`" `"$($SaveDialog.FileName)`"" -Wait -PassThru -NoNewWindow
$LASTEXITCODE = $oscdimgProc.ExitCode
Write-Host "OSCDIMG Error Level : $($oscdimgProc.ExitCode)"
Write-Host " _____ "
Write-Host "(____ \ "
Write-Host " _ \ \ ___ ____ ____ "
Write-Host "| | | / _ \| _ \ / _ ) "
Write-Host "| |__/ / |_| | | | ( (/ / "
Write-Host "|_____/ \___/|_| |_|\____) "
# Check if the ISO was successfully created - CTT edit
if ($LASTEXITCODE -eq 0) {
Write-Host "`n`nPerforming Cleanup..."
Remove-Item -Recurse -Force "$($scratchDir)"
Remove-Item -Recurse -Force "$($mountDir)"
$msg = "Done. ISO image is located here: $($SaveDialog.FileName)"
Write-Host $msg
Set-WinUtilTaskbaritem -state "None" -overlay "checkmark"
Invoke-MicrowinBusyInfo -action "done" -message "Finished!"
[System.Windows.MessageBox]::Show($msg, "Winutil", [System.Windows.MessageBoxButton]::OK, [System.Windows.MessageBoxImage]::Information)
} else {
Write-Host "ISO creation failed. The "$($mountDir)" directory has not been removed."
try {
# This creates a new Win32 exception from which we can extract a message in the system language.
# Now, this will NOT throw an exception
$exitCode = New-Object System.ComponentModel.Win32Exception($LASTEXITCODE)
Write-Host "Reason: $($exitCode.Message)"
Invoke-MicrowinBusyInfo -action "warning" -message $exitCode.Message
Set-WinUtilTaskbaritem -state "Error" -value 1 -overlay "warning"
[System.Windows.MessageBox]::Show("MicroWin failed to make the ISO.", "Winutil", [System.Windows.MessageBoxButton]::OK, [System.Windows.MessageBoxImage]::Error)
} catch {
# Could not get error description from Windows APIs
}
}
Toggle-MicrowinPanel 1
$sync.MicrowinFinalIsoLocation.Text = "$($SaveDialog.FileName)"
# Allow the machine to sleep again (optional)
[PowerManagement]::SetThreadExecutionState(0)
$sync.ProcessRunning = $false
}
}

View File

@@ -1,65 +0,0 @@
function Invoke-MicrowinBusyInfo {
<#
.DESCRIPTION
Function to display the busy info for the Microwin process
#>
[CmdletBinding(DefaultParameterSetName='done')]
param(
[Parameter(ParameterSetName='wip', Mandatory, Position = 0)]
[Parameter(ParameterSetName='warning', Mandatory, Position = 0)]
[Parameter(ParameterSetName='done', Mandatory, Position = 0)]
[Parameter(ParameterSetName='hide', Mandatory, Position = 0)]
[ValidateSet('wip', 'warning', 'done', 'hide')]
[string]$action,
[Parameter(ParameterSetName='wip', Mandatory, Position = 1)]
[Parameter(ParameterSetName='warning', Mandatory, Position = 1)]
[Parameter(ParameterSetName='done', Mandatory, Position = 1)]
[string]$message,
[Parameter(ParameterSetName='wip', Position = 2)] [bool]$interactive = $false
)
switch ($action) {
"wip" {
$sync.form.Dispatcher.BeginInvoke([action]{
$sync.MicrowinBusyIndicator.Visibility="Visible"
$finalMessage = ""
if ($interactive -eq $false) {
$finalMessage += "Please wait. "
}
$finalMessage += $message
$sync.BusyText.Text = $finalMessage
$sync.BusyIcon.Foreground="#FFA500"
$sync.BusyText.Foreground="#FFA500"
})
}
"warning" {
$sync.form.Dispatcher.BeginInvoke([action]{
$sync.MicrowinBusyIndicator.Visibility="Visible"
$sync.BusyText.Text=$message
$sync.BusyText.Foreground="#FF0000"
$sync.BusyIcon.Foreground="#FF0000"
})
}
"done" {
$sync.form.Dispatcher.BeginInvoke([action]{
$sync.MicrowinBusyIndicator.Visibility="Visible"
$sync.BusyText.Text=$message
$sync.BusyText.Foreground="#00FF00"
$sync.BusyIcon.Foreground="#00FF00"
})
}
"hide" {
$sync.form.Dispatcher.BeginInvoke([action]{
$sync.MicrowinBusyIndicator.Visibility="Hidden"
$sync.BusyText.Foreground=$sync.Form.Resources.MicrowinBusyColor
$sync.BusyIcon.Foreground=$sync.Form.Resources.MicrowinBusyColor
})
}
}
# Force the UI to process pending messages
[System.Windows.Forms.Application]::DoEvents()
Start-Sleep -Milliseconds 50
}

View File

@@ -1,332 +0,0 @@
function Invoke-MicrowinGetIso {
<#
.DESCRIPTION
Function to get the path to Iso file for MicroWin, unpack that isom=, read basic information and populate the UI Options
#>
Write-Debug "Invoking WPFGetIso"
if($sync.ProcessRunning) {
$msg = "GetIso process is currently running."
[System.Windows.MessageBox]::Show($msg, "Winutil", [System.Windows.MessageBoxButton]::OK, [System.Windows.MessageBoxImage]::Warning)
return
}
# Provide immediate feedback to user
Invoke-MicrowinBusyInfo -action "wip" -message "Initializing MicroWin process..." -interactive $false
Write-Host " _ __ __ _ "
Write-Host " /\/\ (_) ___ _ __ ___ / / /\ \ \(_) _ __ "
Write-Host " / \ | | / __|| '__| / _ \ \ \/ \/ /| || '_ \ "
Write-Host "/ /\/\ \| || (__ | | | (_) | \ /\ / | || | | | "
Write-Host "\/ \/|_| \___||_| \___/ \/ \/ |_||_| |_| "
if ($sync["ISOmanual"].IsChecked) {
# Open file dialog to let user choose the ISO file
Invoke-MicrowinBusyInfo -action "wip" -message "Please select an ISO file..." -interactive $true
[System.Reflection.Assembly]::LoadWithPartialName("System.windows.forms") | Out-Null
$openFileDialog = New-Object System.Windows.Forms.OpenFileDialog
$openFileDialog.initialDirectory = $initialDirectory
$openFileDialog.filter = "ISO files (*.iso)| *.iso"
$openFileDialog.ShowDialog() | Out-Null
$filePath = $openFileDialog.FileName
if ([string]::IsNullOrEmpty($filePath)) {
Write-Host "No ISO is chosen"
Invoke-MicrowinBusyInfo -action "hide" -message " "
return
}
} elseif ($sync["ISOdownloader"].IsChecked) {
# Create folder browsers for user-specified locations
Invoke-MicrowinBusyInfo -action "wip" -message "Please select download location..." -interactive $true
[System.Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms") | Out-Null
$isoDownloaderFBD = New-Object System.Windows.Forms.FolderBrowserDialog
$isoDownloaderFBD.Description = "Please specify the path to download the ISO file to:"
$isoDownloaderFBD.ShowNewFolderButton = $true
if ($isoDownloaderFBD.ShowDialog() -ne [System.Windows.Forms.DialogResult]::OK)
{
Invoke-MicrowinBusyInfo -action "hide" -message " "
return
}
Set-WinUtilTaskbaritem -state "Indeterminate" -overlay "logo"
Invoke-MicrowinBusyInfo -action "wip" -message "Preparing to download ISO..." -interactive $false
# Grab the location of the selected path
$targetFolder = $isoDownloaderFBD.SelectedPath
# Auto download newest ISO
# Credit: https://github.com/pbatard/Fido
$fidopath = "$env:temp\Fido.ps1"
$originalLocation = $PSScriptRoot
Invoke-MicrowinBusyInfo -action "wip" -message "Downloading Fido script..." -interactive $false
Invoke-WebRequest "https://github.com/pbatard/Fido/raw/master/Fido.ps1" -OutFile $fidopath
Set-Location -Path $env:temp
# Detect if the first option ("System language") has been selected and get a Fido-approved language from the current culture
$lang = if ($sync["ISOLanguage"].SelectedIndex -eq 0) {
Microwin-GetLangFromCulture -langName (Get-Culture).Name
} else {
$sync["ISOLanguage"].SelectedItem
}
Invoke-MicrowinBusyInfo -action "wip" -message "Downloading Windows ISO... (This may take a long time)" -interactive $false
& $fidopath -Win 'Windows 11' -Rel Latest -Arch "x64" -Lang $lang
if (-not $?)
{
Write-Host "Could not download the ISO file. Look at the output of the console for more information."
Write-Host "If you get an error about scripts is disabled on this system please close WinUtil and run - 'Set-ExecutionPolicy -ExecutionPolicy Unrestricted' and select 'A' and retry using MicroWin again."
$msg = "The ISO file could not be downloaded"
Invoke-MicrowinBusyInfo -action "warning" -message $msg
Set-WinUtilTaskbaritem -state "Error" -value 1 -overlay "warning"
[System.Windows.MessageBox]::Show($msg, "Winutil", [System.Windows.MessageBoxButton]::OK, [System.Windows.MessageBoxImage]::Error)
return
}
Set-Location $originalLocation
# Use the FullName property to only grab the file names. Using this property is necessary as, without it, you're passing the usual output of Get-ChildItem
# to the variable, and let's be honest, that does NOT exist in the file system
$filePath = (Get-ChildItem -Path "$env:temp" -Filter "Win11*.iso").FullName | Sort-Object LastWriteTime -Descending | Select-Object -First 1
$fileName = [IO.Path]::GetFileName("$filePath")
if (($targetFolder -ne "") -and (Test-Path "$targetFolder"))
{
try
{
# "Let it download to $env:TEMP and then we **move** it to the file path." - CodingWonders
$destinationFilePath = "$targetFolder\$fileName"
Write-Host "Moving ISO file. Please wait..."
Move-Item -Path "$filePath" -Destination "$destinationFilePath" -Force
$filePath = $destinationFilePath
}
catch
{
$msg = "Unable to move the ISO file to the location you specified. The downloaded ISO is in the `"$env:TEMP`" folder"
Write-Host $msg
Write-Host "Error information: $($_.Exception.Message)" -ForegroundColor Yellow
Invoke-MicrowinBusyInfo -action "warning" -message $msg
return
}
}
}
Write-Host "File path $($filePath)"
if (-not (Test-Path -Path "$filePath" -PathType Leaf)) {
$msg = "File you've chosen doesn't exist"
Invoke-MicrowinBusyInfo -action "warning" -message $msg
[System.Windows.MessageBox]::Show($msg, "Winutil", [System.Windows.MessageBoxButton]::OK, [System.Windows.MessageBoxImage]::Error)
return
}
Set-WinUtilTaskbaritem -state "Indeterminate" -overlay "logo"
Invoke-MicrowinBusyInfo -action "wip" -message "Checking system requirements..." -interactive $false
$adkKitsRoot = Microwin-GetKitsRoot -wow64environment $false
$adkKitsRoot_WOW64Environ = Microwin-GetKitsRoot -wow64environment $true
$expectedADKPath = "$($adkKitsRoot)Assessment and Deployment Kit"
$expectedADKPath_WOW64Environ = "$($adkKitsRoot_WOW64Environ)Assessment and Deployment Kit"
$oscdimgPath = Join-Path $env:TEMP 'oscdimg.exe'
$oscdImgFound = [bool] (Microwin-TestKitsRootPaths -adkKitsRootPath "$expectedADKPath" -adkKitsRootPath_WOW64Environ "$expectedADKPath_WOW64Environ") -or (Test-Path $oscdimgPath -PathType Leaf)
Write-Host "oscdimg.exe on system: $oscdImgFound"
if (-not ($oscdImgFound)) {
# First we try to grab it from github, if not, run the ADK installer.
if ((Microwin-GetOscdimg -oscdimgPath $oscdimgPath) -eq $true) {
Write-Host "OSCDIMG download succeeded."
} else {
Write-Host "OSCDIMG could not be downloaded from GitHub. Downloading deployment tools..."
if (-not (Microwin-GetAdkDeploymentTools)) {
Invoke-MicrowinBusyInfo -action "warning" -message "Neither OSCDIMG nor ADK could be downloaded."
Write-Host "Neither OSCDIMG nor ADK could be downloaded."
return
} else {
$msg = "ADK/OSCDIMG is installed, now restart this process."
Invoke-MicrowinBusyInfo -action "done" -message $msg # We set it to done because it immediately returns from this function
[System.Windows.MessageBox]::Show($msg)
Remove-Item -Path "$env:TEMP\adksetup.exe" -Force -ErrorAction SilentlyContinue
return
}
}
} elseif (Microwin-TestKitsRootPaths -adkKitsRootPath "$expectedADKPath" -adkKitsRootPath_WOW64Environ "$expectedADKPath_WOW64Environ") {
# We have to guess where oscdimg is. We'll check both values...
$peToolsPath = ""
if ($expectedADKPath -ne "Assessment and Deployment Kit") { $peToolsPath = $expectedADKPath }
if (($peToolsPath -eq "") -and ($expectedADKPath_WOW64Environ -ne "Assessment and Deployment Kit")) { $peToolsPath = $expectedADKPath_WOW64Environ }
Write-Host "Using $peToolsPath as the Preinstallation Environment tools path..."
# Paths change depending on platform
if ([Environment]::Is64BitOperatingSystem) {
$oscdimgPath = "$peToolsPath\Deployment Tools\amd64\Oscdimg\oscdimg.exe"
} else {
$oscdimgPath = "$peToolsPath\Deployment Tools\x86\Oscdimg\oscdimg.exe"
}
# If it's a non-existent file, we won't continue.
if (-not (Test-Path -Path "$oscdimgPath" -PathType Leaf)) {
$oscdimgFound = $false
}
}
$oscdImgFound = [bool] (Microwin-TestKitsRootPaths -adkKitsRootPath "$expectedADKPath" -adkKitsRootPath_WOW64Environ "$expectedADKPath_WOW64Environ") -or (Test-Path $oscdimgPath -PathType Leaf)
if (-not ($oscdimgFound)) {
[System.Windows.MessageBox]::Show("oscdimg.exe is not found on the system. Cannot continue.")
return
}
Invoke-MicrowinBusyInfo -action "wip" -message "Checking disk space..." -interactive $false
# Detect the file size of the ISO and compare it with the free space of the system drive
$isoSize = (Get-Item -Path "$filePath").Length
Write-Debug "Size of ISO file: $($isoSize) bytes"
# Use this procedure to get the free space of the drive depending on where the user profile folder is stored.
# This is done to guarantee a dynamic solution, as the installation drive may be mounted to a letter different than C
$driveSpace = (Get-Volume -DriveLetter ([IO.Path]::GetPathRoot([Environment]::GetFolderPath([Environment+SpecialFolder]::UserProfile)).Replace(":\", "").Trim())).SizeRemaining
Write-Debug "Free space on installation drive: $($driveSpace) bytes"
if ($driveSpace -lt ($isoSize * 2)) {
# It's not critical and we _may_ continue. Output a warning
Write-Warning "You may not have enough space for this operation. Proceed at your own risk."
}
elseif ($driveSpace -lt $isoSize) {
# It's critical and we can't continue. Output an error
$msg = "You don't have enough space for this operation. You need at least $([Math]::Round(($isoSize / ([Math]::Pow(1024, 2))) * 2, 2)) MB of free space to copy the ISO files to a temp directory and to be able to perform additional operations."
Write-Host $msg
Set-WinUtilTaskbaritem -state "Error" -value 1 -overlay "warning"
Invoke-MicrowinBusyInfo -action "warning" -message $msg
return
} else {
Write-Host "You have enough space for this operation."
}
try {
Invoke-MicrowinBusyInfo -action "wip" -message "Mounting ISO file..." -interactive $false
Write-Host "Mounting Iso. Please wait."
$mountedISO = Mount-DiskImage -PassThru "$filePath"
Write-Host "Done mounting Iso `"$($mountedISO.ImagePath)`""
$driveLetter = (Get-Volume -DiskImage $mountedISO).DriveLetter
Write-Host "Iso mounted to '$driveLetter'"
} catch {
# @ChrisTitusTech please copy this wiki and change the link below to your copy of the wiki
$msg = "Failed to mount the image. Error: $($_.Exception.Message)"
Write-Error $msg
Write-Error "This is NOT winutil's problem, your ISO might be corrupt, or there is a problem on the system"
Write-Host "Please refer to this wiki for more details: https://winutil.christitus.com/knownissues/" -ForegroundColor Red
Set-WinUtilTaskbaritem -state "Error" -value 1 -overlay "warning"
Invoke-MicrowinBusyInfo -action "warning" -message $msg
return
}
# storing off values in hidden fields for further steps
# there is probably a better way of doing this, I don't have time to figure this out
$sync.MicrowinIsoDrive.Text = $driveLetter
# Detect if the folders already exist and remove them
if (($sync.MicrowinMountDir.Text -ne "") -and (Test-Path -Path $sync.MicrowinMountDir.Text)) {
try {
Write-Host "Deleting temporary files from previous run. Please wait..."
Remove-Item -Path $sync.MicrowinMountDir.Text -Recurse -Force
Remove-Item -Path $sync.MicrowinScratchDir.Text -Recurse -Force
} catch {
Write-Host "Could not delete temporary files. You need to delete those manually."
}
}
Write-Host "Setting up mount dir and scratch dirs"
$timestamp = Get-Date -Format "yyyyMMdd_HHmmss"
$randomNumber = Get-Random -Minimum 1 -Maximum 9999
$randomMicrowin = "Microwin_${timestamp}_${randomNumber}"
$randomMicrowinScratch = "MicrowinScratch_${timestamp}_${randomNumber}"
$sync.BusyText.Text=" - Mounting"
Write-Host "Mounting Iso. Please wait."
$mountDir = Join-Path $env:TEMP $randomMicrowin
$scratchDir = Join-Path $env:TEMP $randomMicrowinScratch
$sync.MicrowinMountDir.Text = $mountDir
$sync.MicrowinScratchDir.Text = $scratchDir
Write-Host "Done setting up mount dir and scratch dirs"
Write-Host "Scratch dir is $scratchDir"
Write-Host "Image dir is $mountDir"
try {
#$data = @($driveLetter, $filePath)
Invoke-MicrowinBusyInfo -action "wip" -message "Creating directories..." -interactive $false
New-Item -ItemType Directory -Force -Path "$($mountDir)" | Out-Null
New-Item -ItemType Directory -Force -Path "$($scratchDir)" | Out-Null
Invoke-MicrowinBusyInfo -action "wip" -message "Copying Windows files... (This may take several minutes)" -interactive $false
Write-Host "Copying Windows image. This will take awhile, please don't use UI or cancel this step!"
# xcopy we can verify files and also not copy files that already exist, but hard to measure
# xcopy.exe /E /I /H /R /Y /J $DriveLetter":" $mountDir >$null
$totalTime = Measure-Command {
Copy-Files "$($driveLetter):" "$mountDir" -Recurse -Force
# Force UI update during long operation
[System.Windows.Forms.Application]::DoEvents()
}
Write-Host "Copy complete! Total Time: $($totalTime.Minutes) minutes, $($totalTime.Seconds) seconds"
Invoke-MicrowinBusyInfo -action "wip" -message "Processing Windows image..." -interactive $false
$wimFile = "$mountDir\sources\install.wim"
Write-Host "Getting image information $wimFile"
if ((-not (Test-Path -Path "$wimFile" -PathType Leaf)) -and (-not (Test-Path -Path "$($wimFile.Replace(".wim", ".esd").Trim())" -PathType Leaf))) {
$msg = "Neither install.wim nor install.esd exist in the image, this could happen if you use unofficial Windows images. Please don't use shady images from the internet."
Write-Host "$($msg) Only use official images. Here are instructions how to download ISO images if the Microsoft website is not showing the link to download and ISO. https://www.techrepublic.com/article/how-to-download-a-windows-10-iso-file-without-using-the-media-creation-tool/"
Invoke-MicrowinBusyInfo -action "warning" -message $msg
Set-WinUtilTaskbaritem -state "Error" -value 1 -overlay "warning"
[System.Windows.MessageBox]::Show($msg, "Winutil", [System.Windows.MessageBoxButton]::OK, [System.Windows.MessageBoxImage]::Error)
throw
}
elseif ((-not (Test-Path -Path $wimFile -PathType Leaf)) -and (Test-Path -Path $wimFile.Replace(".wim", ".esd").Trim() -PathType Leaf)) {
Write-Host "Install.esd found on the image. It needs to be converted to a WIM file in order to begin processing"
$wimFile = $wimFile.Replace(".wim", ".esd").Trim()
}
$sync.MicrowinWindowsFlavors.Items.Clear()
Get-WindowsImage -ImagePath $wimFile | ForEach-Object {
$imageIdx = $_.ImageIndex
$imageName = $_.ImageName
$sync.MicrowinWindowsFlavors.Items.Add("$imageIdx : $imageName")
}
[System.Windows.Forms.Application]::DoEvents()
$sync.MicrowinWindowsFlavors.SelectedIndex = 0
Write-Host "Finding suitable Pro edition. This can take some time. Do note that this is an automatic process that might not select the edition you want."
Invoke-MicrowinBusyInfo -action "wip" -message "Finding suitable Pro edition..." -interactive $false
Get-WindowsImage -ImagePath $wimFile | ForEach-Object {
if ((Get-WindowsImage -ImagePath $wimFile -Index $_.ImageIndex).EditionId -eq "Professional") {
# We have found the Pro edition
$sync.MicrowinWindowsFlavors.SelectedIndex = $_.ImageIndex - 1
}
# Allow UI updates during this loop
[System.Windows.Forms.Application]::DoEvents()
}
Get-Volume $driveLetter | Get-DiskImage | Dismount-DiskImage
Write-Host "Selected value '$($sync.MicrowinWindowsFlavors.SelectedValue)'....."
Toggle-MicrowinPanel 2
} catch {
Write-Host "Dismounting bad image..."
Get-Volume $driveLetter | Get-DiskImage | Dismount-DiskImage
Remove-Item -Recurse -Force "$($scratchDir)"
Remove-Item -Recurse -Force "$($mountDir)"
Invoke-MicrowinBusyInfo -action "warning" -message "Failed to read and unpack ISO"
Set-WinUtilTaskbaritem -state "Error" -value 1 -overlay "warning"
}
Write-Host "Done reading and unpacking ISO"
Write-Host ""
Write-Host "*********************************"
Write-Host "Check the UI for further steps!!!"
Invoke-MicrowinBusyInfo -action "done" -message "Done! Proceed with customization."
$sync.ProcessRunning = $false
Set-WinUtilTaskbaritem -state "None" -overlay "checkmark"
}

View File

@@ -1,10 +0,0 @@
class ErroredPackage {
[string]$PackageName
[string]$ErrorMessage
ErroredPackage() { $this.Init(@{} )}
# Constructor for packages that have errored out
ErroredPackage([string]$pkgName, [string]$reason) {
$this.PackageName = $pkgName
$this.ErrorMessage = $reason
}
}

View File

@@ -1,40 +0,0 @@
function Microwin-CopyVirtIO {
<#
.SYNOPSIS
Downloads and copies the VirtIO Guest Tools drivers to the target MicroWin ISO
.NOTES
A network connection must be available and the servers of Fedora People must be up. Automatic driver installation will not be added yet - I want this implementation to be reliable.
#>
try {
Write-Host "Checking existing files..."
if (Test-Path -Path "$($env:TEMP)\virtio.iso" -PathType Leaf) {
Write-Host "VirtIO ISO has been detected. Deleting..."
Remove-Item -Path "$($env:TEMP)\virtio.iso" -Force
}
Write-Host "Getting latest VirtIO drivers. Please wait. This can take some time, depending on your network connection speed and the speed of the servers..."
Start-BitsTransfer -Source "https://fedorapeople.org/groups/virt/virtio-win/direct-downloads/stable-virtio/virtio-win.iso" -Destination "$($env:TEMP)\virtio.iso" -DisplayName "Downloading VirtIO drivers..."
# Do everything else if the VirtIO ISO exists
if (Test-Path -Path "$($env:TEMP)\virtio.iso" -PathType Leaf) {
Write-Host "Mounting ISO. Please wait."
$virtIO_ISO = Mount-DiskImage -PassThru "$($env:TEMP)\virtio.iso"
$driveLetter = (Get-Volume -DiskImage $virtIO_ISO).DriveLetter
# Create new directory for VirtIO on ISO
New-Item -Path "$mountDir\VirtIO" -ItemType Directory | Out-Null
$totalTime = Measure-Command { Copy-Files "$($driveLetter):" "$mountDir\VirtIO" -Recurse -Force }
Write-Host "VirtIO contents have been successfully copied. Time taken: $($totalTime.Minutes) minutes, $($totalTime.Seconds) seconds`n"
Get-Volume $driveLetter | Get-DiskImage | Dismount-DiskImage
Remove-Item -Path "$($env:TEMP)\virtio.iso" -Force -ErrorAction SilentlyContinue
Write-Host "To proceed with installation of the MicroWin image in QEMU/Proxmox VE:"
Write-Host "1. Proceed with Setup until you reach the disk selection screen, in which you won't see any drives"
Write-Host "2. Click `"Load Driver`" and click Browse"
Write-Host "3. In the folder selection dialog, point to this path:`n`n `"D:\VirtIO\vioscsi\w11\amd64`" (replace amd64 with ARM64 if you are using Windows on ARM, and `"D:`" with the drive letter of the ISO)`n"
Write-Host "4. Select all drivers that will appear in the list box and click OK"
} else {
throw "Could not download VirtIO drivers"
}
} catch {
Write-Host "We could not download and/or prepare the VirtIO drivers. Error information: $_`n"
Write-Host "You will need to download these drivers manually. Location: https://fedorapeople.org/groups/virt/virtio-win/direct-downloads/stable-virtio/virtio-win.iso"
}
}

View File

@@ -1,25 +0,0 @@
function Microwin-GetAdkDeploymentTools {
<#
.DESCRIPTION
This function will download the deployment tools from Microsoft
.EXAMPLE
Microwin-GetAdkDeploymentTools
#>
# ADK 10.1.28000.1 download link is the same; no need to guess it
$adkDownloadLink = "https://download.microsoft.com/download/615540bc-be0b-433a-b91b-1f2b0642bb24/adk/adksetup.exe"
$adkVersion = "10.1.28000.1"
Write-Host "Downloading ADK version $adkVersion ..."
Invoke-WebRequest -UseBasicParsing -Uri "$adkDownloadLink" -OutFile "$env:TEMP\adksetup.exe"
if ((-not ($?)) -or (-not (Test-Path -Path "$env:TEMP\adksetup.exe" -PathType Leaf))) {
Write-Host "ADK could not be downloaded."
return $false
}
Write-Host "Installing ADK version $adkVersion -- This may take a few minutes..."
Start-Process -FilePath "$env:TEMP\adksetup.exe" -ArgumentList "/features OptionId.DeploymentTools /q /ceip off" -Wait
return $?
}

View File

@@ -1,40 +0,0 @@
function Microwin-GetKitsRoot {
<#
.SYNOPSIS
Gets the kits root path for the Windows Assessment and Deployment Kit (ADK)
.PARAMETER wow64environment
Determines whether to search in a WOW64 compatibility environment (HKLM\SOFTWARE\WOW6432Node)
.OUTPUTS
The path to the kits root
#>
param (
[Parameter(Mandatory = $true, Position = 0)] [bool]$wow64environment
)
$adk10KitsRoot = ""
# if we set the wow64 bit on and we're on a 32-bit system, then we prematurely return the value
if (($wow64environment -eq $true) -and (-not [Environment]::Is64BitOperatingSystem)) {
return $adk10KitsRoot
}
$regPath = ""
if ($wow64environment) {
$regPath = "HKLM:\SOFTWARE\WOW6432Node\Microsoft\Windows Kits\Installed Roots"
} else {
$regPath = "HKLM:\SOFTWARE\Microsoft\Windows Kits\Installed Roots"
}
if ((Test-Path "$regPath") -eq $false) {
return $adk10KitsRoot
}
try {
$adk10KitsRoot = Get-ItemPropertyValue -Path $regPath -Name "KitsRoot10" -ErrorAction Stop
} catch {
Write-Debug "Could not find ADK."
}
return $adk10KitsRoot
}

View File

@@ -1,49 +0,0 @@
function Microwin-GetLangFromCulture {
param (
[Parameter(Mandatory, Position = 0)] [string]$langName
)
switch -Wildcard ($langName)
{
"ar*" { return "Arabic" }
"pt-BR" { return "Brazilian Portuguese" }
"bg*" { return "Bulgarian" }
{($_ -eq "zh-CH") -or ($_ -like "zh-Hans*") -or ($_ -eq "zh-SG") -or ($_ -eq "zh-CHS")} { return "Chinese (Simplified)" }
{($_ -eq "zh") -or ($_ -eq "zh-Hant") -or ($_ -eq "zh-HK") -or ($_ -eq "zh-MO") -or ($_ -eq "zh-TW") -or ($_ -eq "zh-CHT")} { return "Chinese (Traditional)" }
"hr*" { return "Croatian" }
"cs*" { return "Czech" }
"da*" { return "Danish" }
"nl*" { return "Dutch" }
"en-US" { return "English" }
{($_ -like "en*") -and ($_ -ne "en-US")} { return "English International" }
"et*" { return "Estonian" }
"fi*" { return "Finnish" }
{($_ -like "fr*") -and ($_ -ne "fr-CA")} { return "French" }
"fr-CA" { return "French Canadian" }
"de*" { return "German" }
"el*" { return "Greek" }
"he*" { return "Hebrew" }
"hu*" { return "Hungarian" }
"it*" { return "Italian" }
"ja*" { return "Japanese" }
"ko*" { return "Korean" }
"lv*" { return "Latvian" }
"lt*" { return "Lituanian" }
"nb*" { return "Norwegian" }
"pl*" { return "Polish" }
{($_ -like "pt*") -and ($_ -ne "pt-BR")} { return "Portuguese" }
"ro*" { return "Romanian" }
"ru*" { return "Russian" }
"sr-Latn*" { return "Serbian Latin" }
"sk*" { return "Slovak" }
"sl*" { return "Slovenian" }
{($_ -like "es*") -and ($_ -ne "es-MX")} { return "Spanish" }
"es-MX" { return "Spanish (Mexico)" }
"sv*" { return "Swedish" }
"th*" { return "Thai" }
"tr*" { return "Turkish" }
"uk*" { return "Ukrainian" }
default { return "English" }
}
}

View File

@@ -1,21 +0,0 @@
function Microwin-GetLocalizedUsers
{
<#
.SYNOPSIS
Gets a localized user group representation for ICACLS commands (Port from DISMTools PE Helper)
.PARAMETER admins
Determines whether to get a localized user group representation for the Administrators user group
.OUTPUTS
A string containing the localized user group
.EXAMPLE
Microwin-GetLocalizedUsers -admins $true
#>
param (
[Parameter(Mandatory = $true, Position = 0)] [bool]$admins
)
if ($admins) {
return (Get-LocalGroup | Where-Object { $_.SID.Value -like "S-1-5-32-544" }).Name
} else {
return (Get-LocalGroup | Where-Object { $_.SID.Value -like "S-1-5-32-545" }).Name
}
}

View File

@@ -1,35 +0,0 @@
function Microwin-GetOscdimg {
<#
.DESCRIPTION
This function will download oscdimg file from github Release folders and put it into env:temp folder
.EXAMPLE
Microwin-GetOscdimg
#>
param(
[Parameter(Mandatory, position=0)]
[string]$oscdimgPath
)
$oscdimgPath = "$env:TEMP\oscdimg.exe"
$downloadUrl = "https://github.com/ChrisTitusTech/winutil/raw/main/releases/oscdimg.exe"
Invoke-RestMethod -Uri $downloadUrl -OutFile $oscdimgPath
if (-not (Test-Path "$oscdimgPath" -PathType Leaf)) {
Write-Host "OSCDIMG could not be downloaded."
return $false
}
$hashResult = Get-FileHash -Path $oscdimgPath -Algorithm SHA256
$sha256Hash = $hashResult.Hash
Write-Host "[INFO] oscdimg.exe SHA-256 Hash: $sha256Hash"
$expectedHash = "AB9E161049D293B544961BFDF2D61244ADE79376D6423DF4F60BF9B147D3C78D" # Replace with the actual expected hash
if ($sha256Hash -eq $expectedHash) {
Write-Host "Hashes match. File is verified."
return $true
} else {
Write-Host "Hashes do not match. File may be corrupted or tampered with."
return $false
}
}

View File

@@ -1,73 +0,0 @@
function Microwin-NewCheckInstall {
# using here string to embed firstrun
$checkInstall = @'
@echo off
if exist "%HOMEDRIVE%\windows\cpu.txt" (
echo %HOMEDRIVE%\windows\cpu.txt exists
) else (
echo %HOMEDRIVE%\windows\cpu.txt does not exist
)
if exist "%HOMEDRIVE%\windows\SerialNumber.txt" (
echo %HOMEDRIVE%\windows\SerialNumber.txt exists
) else (
echo %HOMEDRIVE%\windows\SerialNumber.txt does not exist
)
if exist "%HOMEDRIVE%\unattend.xml" (
echo %HOMEDRIVE%\unattend.xml exists
) else (
echo %HOMEDRIVE%\unattend.xml does not exist
)
if exist "%HOMEDRIVE%\Windows\Setup\Scripts\SetupComplete.cmd" (
echo %HOMEDRIVE%\Windows\Setup\Scripts\SetupComplete.cmd exists
) else (
echo %HOMEDRIVE%\Windows\Setup\Scripts\SetupComplete.cmd does not exist
)
if exist "%HOMEDRIVE%\Windows\Panther\unattend.xml" (
echo %HOMEDRIVE%\Windows\Panther\unattend.xml exists
) else (
echo %HOMEDRIVE%\Windows\Panther\unattend.xml does not exist
)
if exist "%HOMEDRIVE%\Windows\System32\Sysprep\unattend.xml" (
echo %HOMEDRIVE%\Windows\System32\Sysprep\unattend.xml exists
) else (
echo %HOMEDRIVE%\Windows\System32\Sysprep\unattend.xml does not exist
)
if exist "%HOMEDRIVE%\Windows\FirstStartup.ps1" (
echo %HOMEDRIVE%\Windows\FirstStartup.ps1 exists
) else (
echo %HOMEDRIVE%\Windows\FirstStartup.ps1 does not exist
)
if exist "%HOMEDRIVE%\Windows\winutil.ps1" (
echo %HOMEDRIVE%\Windows\winutil.ps1 exists
) else (
echo %HOMEDRIVE%\Windows\winutil.ps1 does not exist
)
if exist "%HOMEDRIVE%\Windows\LogSpecialize.txt" (
echo %HOMEDRIVE%\Windows\LogSpecialize.txt exists
) else (
echo %HOMEDRIVE%\Windows\LogSpecialize.txt does not exist
)
if exist "%HOMEDRIVE%\Windows\LogAuditUser.txt" (
echo %HOMEDRIVE%\Windows\LogAuditUser.txt exists
) else (
echo %HOMEDRIVE%\Windows\LogAuditUser.txt does not exist
)
if exist "%HOMEDRIVE%\Windows\LogOobeSystem.txt" (
echo %HOMEDRIVE%\Windows\LogOobeSystem.txt exists
) else (
echo %HOMEDRIVE%\Windows\LogOobeSystem.txt does not exist
)
if exist "%HOMEDRIVE%\windows\csup.txt" (
echo %HOMEDRIVE%\windows\csup.txt exists
) else (
echo %HOMEDRIVE%\windows\csup.txt does not exist
)
if exist "%HOMEDRIVE%\windows\LogFirstRun.txt" (
echo %HOMEDRIVE%\windows\LogFirstRun.txt exists
) else (
echo %HOMEDRIVE%\windows\LogFirstRun.txt does not exist
)
'@
$checkInstall | Out-File -FilePath "$env:temp\checkinstall.cmd" -Force -Encoding Ascii
}

View File

@@ -1,152 +0,0 @@
function Microwin-NewFirstRun {
# using here string to embed firstrun
$firstRun = @'
# Set the global error action preference to continue
$ErrorActionPreference = "Continue"
function Remove-RegistryValue {
param (
[Parameter(Mandatory = $true)]
[string]$RegistryPath,
[Parameter(Mandatory = $true)]
[string]$ValueName
)
# Check if the registry path exists
if (Test-Path -Path $RegistryPath) {
$registryValue = Get-ItemProperty -Path $RegistryPath -Name $ValueName -ErrorAction SilentlyContinue
# Check if the registry value exists
if ($registryValue) {
# Remove the registry value
Remove-ItemProperty -Path $RegistryPath -Name $ValueName -Force
Write-Host "Registry value '$ValueName' removed from '$RegistryPath'."
} else {
Write-Host "Registry value '$ValueName' not found in '$RegistryPath'."
}
} else {
Write-Host "Registry path '$RegistryPath' not found."
}
}
"FirstStartup has worked" | Out-File -FilePath "$env:HOMEDRIVE\windows\LogFirstRun.txt" -Append -NoClobber
$taskbarPath = "$env:AppData\Microsoft\Internet Explorer\Quick Launch\User Pinned\TaskBar"
# Delete all files on the Taskbar
if (Test-Path "$taskbarPath") {
Get-ChildItem -Path $taskbarPath -File | Remove-Item -Force
}
Remove-RegistryValue -RegistryPath "HKCU:\Software\Microsoft\Windows\CurrentVersion\Explorer\Taskband" -ValueName "FavoritesRemovedChanges"
Remove-RegistryValue -RegistryPath "HKCU:\Software\Microsoft\Windows\CurrentVersion\Explorer\Taskband" -ValueName "FavoritesChanges"
Remove-RegistryValue -RegistryPath "HKCU:\Software\Microsoft\Windows\CurrentVersion\Explorer\Taskband" -ValueName "Favorites"
# Delete Edge Icon from the desktop
$edgeShortcutFiles = Get-ChildItem -Path $desktopPath -Filter "*Edge*.lnk"
# Check if Edge shortcuts exist on the desktop
if ($edgeShortcutFiles) {
foreach ($shortcutFile in $edgeShortcutFiles) {
# Remove each Edge shortcut
Remove-Item -Path $shortcutFile.FullName -Force
Write-Host "Edge shortcut '$($shortcutFile.Name)' removed from the desktop."
}
}
Remove-Item -Path "$env:USERPROFILE\Desktop\*.lnk"
Remove-Item -Path "$env:HOMEDRIVE\Users\Default\Desktop\*.lnk"
try
{
if ((Get-WindowsOptionalFeature -Online | Where-Object { $_.State -eq 'Enabled' -and $_.FeatureName -like "Recall" }).Count -gt 0)
{
Disable-WindowsOptionalFeature -Online -FeatureName "Recall" -Remove
}
}
catch
{
}
if ((Get-BitLockerVolume -MountPoint $Env:SystemDrive).ProtectionStatus -eq 'On') {
Write-Host "Disabling BitLocker..."
Disable-BitLocker -MountPoint $Env:SystemDrive
}
# Get BCD entries and set bootmgr timeout accordingly
try
{
# Check if the number of occurrences of "path" is 2 - this fixes the Boot Manager screen issue (#2562)
if ((bcdedit | Select-String "path").Count -eq 2)
{
# Set bootmgr timeout to 0
bcdedit /set `{bootmgr`} timeout 0
}
}
catch
{
}
reg add "HKCU\Software\Microsoft\Windows\CurrentVersion\Notifications\Settings\Windows.SystemToast.Suggested" /f
reg add "HKCU\Software\Microsoft\Windows\CurrentVersion\Notifications\Settings\Windows.SystemToast.Suggested" /v Enabled /t REG_DWORD /d 0 /f
reg add "HKCU\Software\Microsoft\Windows\CurrentVersion\Notifications\Settings\Windows.SystemToast.StartupApp" /f
reg add "HKCU\Software\Microsoft\Windows\CurrentVersion\Notifications\Settings\Windows.SystemToast.StartupApp" /v Enabled /t REG_DWORD /d 0 /f
reg add "HKCU\Software\Microsoft\Windows\CurrentVersion\Notifications\Settings\Microsoft.SkyDrive.Desktop" /f
reg add "HKCU\Software\Microsoft\Windows\CurrentVersion\Notifications\Settings\Microsoft.SkyDrive.Desktop" /v Enabled /t REG_DWORD /d 0 /f
reg add "HKCU\Software\Microsoft\Windows\CurrentVersion\Notifications\Settings\Windows.SystemToast.AccountHealth" /f
reg add "HKCU\Software\Microsoft\Windows\CurrentVersion\Notifications\Settings\Windows.SystemToast.AccountHealth" /v Enabled /t REG_DWORD /d 0 /f
# This will set List view in Start menu on Win11 25H2. This will not do anything in 24H2 and older
reg add "HKCU\Software\Microsoft\Windows\CurrentVersion\Start" /v AllAppsViewMode /t REG_DWORD /d 2 /f
# This will disable the Recommendations in 25H2. This is much simpler than the method used in 24H2 that requires the Education Environment policy
reg add "HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced" /v Start_IrisRecommendations /t REG_DWORD /d 0 /f
# Other Start Menu settings
reg add "HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced" /v Start_AccountNotifications /t REG_DWORD /d 0 /f
reg add "HKCU\Software\Microsoft\Windows\CurrentVersion\Start" /v ShowAllPinsList /t REG_DWORD /d 0 /f
reg add "HKCU\Software\Microsoft\Windows\CurrentVersion\Start" /v ShowFrequentList /t REG_DWORD /d 0 /f
reg add "HKCU\Software\Microsoft\Windows\CurrentVersion\Start" /v ShowRecentList /t REG_DWORD /d 0 /f
reg add "HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced" /v Start_TrackDocs /t REG_DWORD /d 0 /f
# Color Modes -- requires sending messages to apply to everything
reg add "HKCU\Software\Microsoft\Windows\CurrentVersion\Themes\Personalize" /v "AppsUseLightTheme" /t REG_DWORD /d 0 /f
reg add "HKCU\Software\Microsoft\Windows\CurrentVersion\Themes\Personalize" /v "SystemUsesLightTheme" /t REG_DWORD /d 0 /f
# Send the WM_SETTINGCHANGE message to all windows
Add-Type -TypeDefinition @"
using System;
using System.Runtime.InteropServices;
public class Win32 {
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = false)]
public static extern IntPtr SendMessageTimeout(
IntPtr hWnd,
uint Msg,
IntPtr wParam,
string lParam,
uint fuFlags,
uint uTimeout,
out IntPtr lpdwResult);
}
"@
$HWND_BROADCAST = [IntPtr]0xffff
$WM_SETTINGCHANGE = 0x1A
$SMTO_ABORTIFHUNG = 0x2
$timeout = 100
# Send the broadcast message to all windows
[Win32]::SendMessageTimeout($HWND_BROADCAST, $WM_SETTINGCHANGE, [IntPtr]::Zero, "ImmersiveColorSet", $SMTO_ABORTIFHUNG, $timeout, [ref]([IntPtr]::Zero))
Clear-Host
Write-Host "The taskbar will take around a minute to show up, but you can start using your computer now. Try pressing the Windows key to open the Start menu, or Windows + E to launch File Explorer."
Start-Sleep -Seconds 10
if (Test-Path -Path "$env:HOMEDRIVE\winutil-config.json")
{
Write-Host "Configuration file detected. Applying..."
iex "& { $(irm christitus.com/win) } -Config `"$env:HOMEDRIVE\winutil-config.json`" -Run"
}
'@
$firstRun | Out-File -FilePath "$env:temp\FirstStartup.ps1" -Force
}

View File

@@ -1,327 +0,0 @@
function Microwin-NewUnattend {
param (
[Parameter(Mandatory, Position = 0)] [string]$userName,
[Parameter(Position = 1)] [string]$userPassword
)
$unattend = @'
<?xml version="1.0" encoding="utf-8"?>
<unattend xmlns="urn:schemas-microsoft-com:unattend"
xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<#REPLACEME#>
<settings pass="auditUser">
<component name="Microsoft-Windows-Deployment" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS" xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<RunSynchronous>
<RunSynchronousCommand wcm:action="add">
<Order>1</Order>
<CommandLine>CMD /C echo LAU GG&gt;C:\Windows\LogAuditUser.txt</CommandLine>
<Description>StartMenu</Description>
</RunSynchronousCommand>
</RunSynchronous>
</component>
</settings>
<settings pass="oobeSystem">
<component name="Microsoft-Windows-Shell-Setup" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS" xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<UserAccounts>
<LocalAccounts>
<LocalAccount wcm:action="add">
<Name>USER-REPLACEME</Name>
<Group>Administrators</Group>
<Password>
<Value>PW-REPLACEME</Value>
<PlainText>PT-STATUS</PlainText>
</Password>
</LocalAccount>
</LocalAccounts>
</UserAccounts>
<AutoLogon>
<Username>USER-REPLACEME</Username>
<Enabled>true</Enabled>
<LogonCount>1</LogonCount>
<Password>
<Value>PW-REPLACEME</Value>
<PlainText>PT-STATUS</PlainText>
</Password>
</AutoLogon>
<OOBE>
<HideOEMRegistrationScreen>true</HideOEMRegistrationScreen>
<SkipUserOOBE>true</SkipUserOOBE>
<SkipMachineOOBE>true</SkipMachineOOBE>
<HideOnlineAccountScreens>true</HideOnlineAccountScreens>
<HideWirelessSetupInOOBE>true</HideWirelessSetupInOOBE>
<HideEULAPage>true</HideEULAPage>
<ProtectYourPC>3</ProtectYourPC>
</OOBE>
<FirstLogonCommands>
<SynchronousCommand wcm:action="add">
<Order>1</Order>
<CommandLine>reg.exe add "HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon" /v AutoLogonCount /t REG_DWORD /d 0 /f</CommandLine>
</SynchronousCommand>
<SynchronousCommand wcm:action="add">
<Order>2</Order>
<CommandLine>cmd.exe /c echo 23&gt;c:\windows\csup.txt</CommandLine>
</SynchronousCommand>
<SynchronousCommand wcm:action="add">
<Order>3</Order>
<CommandLine>CMD /C echo GG&gt;C:\Windows\LogOobeSystem.txt</CommandLine>
</SynchronousCommand>
<SynchronousCommand wcm:action="add">
<Order>4</Order>
<CommandLine>powershell -ExecutionPolicy Bypass -File c:\windows\FirstStartup.ps1</CommandLine>
</SynchronousCommand>
</FirstLogonCommands>
</component>
</settings>
</unattend>
'@
$specPass = @'
<settings pass="specialize">
<component name="Microsoft-Windows-SQMApi" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS" xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<CEIPEnabled>0</CEIPEnabled>
</component>
<component name="Microsoft-Windows-Shell-Setup" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS" xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<ConfigureChatAutoInstall>false</ConfigureChatAutoInstall>
</component>
<component name="Microsoft-Windows-Deployment" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS">
<RunSynchronous>
<RunSynchronousCommand wcm:action="add">
<Order>1</Order>
<Path>reg.exe add "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\OOBE" /v BypassNRO /t REG_DWORD /d 1 /f</Path>
</RunSynchronousCommand>
<RunSynchronousCommand wcm:action="add">
<Order>2</Order>
<Path>reg.exe load "HKU\DefaultUser" "C:\Users\Default\NTUSER.DAT"</Path>
</RunSynchronousCommand>
<RunSynchronousCommand wcm:action="add">
<Order>3</Order>
<Path>reg.exe add "HKU\DefaultUser\Software\Microsoft\Windows\CurrentVersion\Runonce" /v "UninstallCopilot" /t REG_SZ /d "powershell.exe -NoProfile -Command \"Get-AppxPackage -Name 'Microsoft.Windows.Ai.Copilot.Provider' | Remove-AppxPackage;\"" /f</Path>
</RunSynchronousCommand>
<RunSynchronousCommand wcm:action="add">
<Order>4</Order>
<Path>reg.exe add "HKU\DefaultUser\Software\Policies\Microsoft\Windows\WindowsCopilot" /v TurnOffWindowsCopilot /t REG_DWORD /d 1 /f</Path>
</RunSynchronousCommand>
<RunSynchronousCommand wcm:action="add">
<Order>5</Order>
<Path>reg.exe unload "HKU\DefaultUser"</Path>
</RunSynchronousCommand>
<RunSynchronousCommand wcm:action="add">
<Order>6</Order>
<Path>reg.exe delete "HKLM\SOFTWARE\Microsoft\WindowsUpdate\Orchestrator\UScheduler_Oobe\DevHomeUpdate" /f</Path>
</RunSynchronousCommand>
<RunSynchronousCommand wcm:action="add">
<Order>7</Order>
<Path>reg.exe load "HKU\DefaultUser" "C:\Users\Default\NTUSER.DAT"</Path>
</RunSynchronousCommand>
<RunSynchronousCommand wcm:action="add">
<Order>8</Order>
<Path>reg.exe add "HKU\DefaultUser\Software\Microsoft\Notepad" /v ShowStoreBanner /t REG_DWORD /d 0 /f</Path>
</RunSynchronousCommand>
<RunSynchronousCommand wcm:action="add">
<Order>9</Order>
<Path>reg.exe unload "HKU\DefaultUser"</Path>
</RunSynchronousCommand>
<RunSynchronousCommand wcm:action="add">
<Order>10</Order>
<Path>cmd.exe /c "del "C:\Users\Default\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\OneDrive.lnk""</Path>
</RunSynchronousCommand>
<RunSynchronousCommand wcm:action="add">
<Order>11</Order>
<Path>cmd.exe /c "del "C:\Windows\System32\OneDriveSetup.exe""</Path>
</RunSynchronousCommand>
<RunSynchronousCommand wcm:action="add">
<Order>12</Order>
<Path>cmd.exe /c "del "C:\Windows\SysWOW64\OneDriveSetup.exe""</Path>
</RunSynchronousCommand>
<RunSynchronousCommand wcm:action="add">
<Order>13</Order>
<Path>reg.exe load "HKU\DefaultUser" "C:\Users\Default\NTUSER.DAT"</Path>
</RunSynchronousCommand>
<RunSynchronousCommand wcm:action="add">
<Order>14</Order>
<Path>reg.exe delete "HKU\DefaultUser\Software\Microsoft\Windows\CurrentVersion\Run" /v OneDriveSetup /f</Path>
</RunSynchronousCommand>
<RunSynchronousCommand wcm:action="add">
<Order>15</Order>
<Path>reg.exe unload "HKU\DefaultUser"</Path>
</RunSynchronousCommand>
<RunSynchronousCommand wcm:action="add">
<Order>16</Order>
<Path>reg.exe delete "HKLM\SOFTWARE\Microsoft\WindowsUpdate\Orchestrator\UScheduler_Oobe\OutlookUpdate" /f</Path>
</RunSynchronousCommand>
<RunSynchronousCommand wcm:action="add">
<Order>17</Order>
<Path>reg.exe add "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Communications" /v ConfigureChatAutoInstall /t REG_DWORD /d 0 /f</Path>
</RunSynchronousCommand>
<RunSynchronousCommand wcm:action="add">
<Order>18</Order>
<Path>powershell.exe -NoProfile -Command "$xml = [xml]::new(); $xml.Load('C:\Windows\Panther\unattend.xml'); $sb = [scriptblock]::Create( $xml.unattend.Extensions.ExtractScript ); Invoke-Command -ScriptBlock $sb -ArgumentList $xml;"</Path>
</RunSynchronousCommand>
<RunSynchronousCommand wcm:action="add">
<Order>19</Order>
<Path>reg.exe add "HKLM\SOFTWARE\Microsoft\PolicyManager\current\device\Start" /v ConfigureStartPins /t REG_SZ /d "{ \"pinnedList\": [] }" /f</Path>
</RunSynchronousCommand>
<RunSynchronousCommand wcm:action="add">
<Order>20</Order>
<Path>reg.exe add "HKLM\SOFTWARE\Microsoft\PolicyManager\current\device\Start" /v ConfigureStartPins_ProviderSet /t REG_DWORD /d 1 /f</Path>
</RunSynchronousCommand>
<RunSynchronousCommand wcm:action="add">
<Order>21</Order>
<Path>reg.exe add "HKLM\SOFTWARE\Microsoft\PolicyManager\current\device\Start" /v ConfigureStartPins_WinningProvider /t REG_SZ /d B5292708-1619-419B-9923-E5D9F3925E71 /f</Path>
</RunSynchronousCommand>
<RunSynchronousCommand wcm:action="add">
<Order>22</Order>
<Path>reg.exe add "HKLM\SOFTWARE\Microsoft\PolicyManager\providers\B5292708-1619-419B-9923-E5D9F3925E71\default\Device\Start" /v ConfigureStartPins /t REG_SZ /d "{ \"pinnedList\": [] }" /f</Path>
</RunSynchronousCommand>
<RunSynchronousCommand wcm:action="add">
<Order>23</Order>
<Path>reg.exe add "HKLM\SOFTWARE\Microsoft\PolicyManager\providers\B5292708-1619-419B-9923-E5D9F3925E71\default\Device\Start" /v ConfigureStartPins_LastWrite /t REG_DWORD /d 1 /f</Path>
</RunSynchronousCommand>
<RunSynchronousCommand wcm:action="add">
<Order>24</Order>
<Path>net.exe accounts /maxpwage:UNLIMITED</Path>
</RunSynchronousCommand>
<RunSynchronousCommand wcm:action="add">
<Order>25</Order>
<Path>reg.exe add "HKLM\SYSTEM\CurrentControlSet\Control\FileSystem" /v LongPathsEnabled /t REG_DWORD /d 1 /f</Path>
</RunSynchronousCommand>
<RunSynchronousCommand wcm:action="add">
<Order>26</Order>
<Path>reg.exe add "HKLM\SYSTEM\CurrentControlSet\Control\Session Manager\Power" /v HiberbootEnabled /t REG_DWORD /d 0 /f</Path>
</RunSynchronousCommand>
<RunSynchronousCommand wcm:action="add">
<Order>27</Order>
<Path>reg.exe add "HKLM\SOFTWARE\Policies\Microsoft\Dsh" /v AllowNewsAndInterests /t REG_DWORD /d 0 /f</Path>
</RunSynchronousCommand>
<RunSynchronousCommand wcm:action="add">
<Order>28</Order>
<Path>reg.exe load "HKU\DefaultUser" "C:\Users\Default\NTUSER.DAT"</Path>
</RunSynchronousCommand>
<RunSynchronousCommand wcm:action="add">
<Order>29</Order>
<Path>reg.exe add "HKU\DefaultUser\Software\Microsoft\Windows\CurrentVersion\ContentDeliveryManager" /v "ContentDeliveryAllowed" /t REG_DWORD /d 0 /f</Path>
</RunSynchronousCommand>
<RunSynchronousCommand wcm:action="add">
<Order>30</Order>
<Path>reg.exe add "HKU\DefaultUser\Software\Microsoft\Windows\CurrentVersion\ContentDeliveryManager" /v "FeatureManagementEnabled" /t REG_DWORD /d 0 /f</Path>
</RunSynchronousCommand>
<RunSynchronousCommand wcm:action="add">
<Order>31</Order>
<Path>reg.exe add "HKU\DefaultUser\Software\Microsoft\Windows\CurrentVersion\ContentDeliveryManager" /v "OEMPreInstalledAppsEnabled" /t REG_DWORD /d 0 /f</Path>
</RunSynchronousCommand>
<RunSynchronousCommand wcm:action="add">
<Order>32</Order>
<Path>reg.exe add "HKU\DefaultUser\Software\Microsoft\Windows\CurrentVersion\ContentDeliveryManager" /v "PreInstalledAppsEnabled" /t REG_DWORD /d 0 /f</Path>
</RunSynchronousCommand>
<RunSynchronousCommand wcm:action="add">
<Order>33</Order>
<Path>reg.exe add "HKU\DefaultUser\Software\Microsoft\Windows\CurrentVersion\ContentDeliveryManager" /v "PreInstalledAppsEverEnabled" /t REG_DWORD /d 0 /f</Path>
</RunSynchronousCommand>
<RunSynchronousCommand wcm:action="add">
<Order>34</Order>
<Path>reg.exe add "HKU\DefaultUser\Software\Microsoft\Windows\CurrentVersion\ContentDeliveryManager" /v "SilentInstalledAppsEnabled" /t REG_DWORD /d 0 /f</Path>
</RunSynchronousCommand>
<RunSynchronousCommand wcm:action="add">
<Order>35</Order>
<Path>reg.exe add "HKU\DefaultUser\Software\Microsoft\Windows\CurrentVersion\ContentDeliveryManager" /v "SoftLandingEnabled" /t REG_DWORD /d 0 /f</Path>
</RunSynchronousCommand>
<RunSynchronousCommand wcm:action="add">
<Order>36</Order>
<Path>reg.exe add "HKU\DefaultUser\Software\Microsoft\Windows\CurrentVersion\ContentDeliveryManager" /v "SubscribedContentEnabled" /t REG_DWORD /d 0 /f</Path>
</RunSynchronousCommand>
<RunSynchronousCommand wcm:action="add">
<Order>37</Order>
<Path>reg.exe add "HKU\DefaultUser\Software\Microsoft\Windows\CurrentVersion\ContentDeliveryManager" /v "SubscribedContent-310093Enabled" /t REG_DWORD /d 0 /f</Path>
</RunSynchronousCommand>
<RunSynchronousCommand wcm:action="add">
<Order>38</Order>
<Path>reg.exe add "HKU\DefaultUser\Software\Microsoft\Windows\CurrentVersion\ContentDeliveryManager" /v "SubscribedContent-338387Enabled" /t REG_DWORD /d 0 /f</Path>
</RunSynchronousCommand>
<RunSynchronousCommand wcm:action="add">
<Order>39</Order>
<Path>reg.exe add "HKU\DefaultUser\Software\Microsoft\Windows\CurrentVersion\ContentDeliveryManager" /v "SubscribedContent-338388Enabled" /t REG_DWORD /d 0 /f</Path>
</RunSynchronousCommand>
<RunSynchronousCommand wcm:action="add">
<Order>40</Order>
<Path>reg.exe add "HKU\DefaultUser\Software\Microsoft\Windows\CurrentVersion\ContentDeliveryManager" /v "SubscribedContent-338389Enabled" /t REG_DWORD /d 0 /f</Path>
</RunSynchronousCommand>
<RunSynchronousCommand wcm:action="add">
<Order>41</Order>
<Path>reg.exe add "HKU\DefaultUser\Software\Microsoft\Windows\CurrentVersion\ContentDeliveryManager" /v "SubscribedContent-338393Enabled" /t REG_DWORD /d 0 /f</Path>
</RunSynchronousCommand>
<RunSynchronousCommand wcm:action="add">
<Order>42</Order>
<Path>reg.exe add "HKU\DefaultUser\Software\Microsoft\Windows\CurrentVersion\ContentDeliveryManager" /v "SubscribedContent-353698Enabled" /t REG_DWORD /d 0 /f</Path>
</RunSynchronousCommand>
<RunSynchronousCommand wcm:action="add">
<Order>43</Order>
<Path>reg.exe add "HKU\DefaultUser\Software\Microsoft\Windows\CurrentVersion\ContentDeliveryManager" /v "SystemPaneSuggestionsEnabled" /t REG_DWORD /d 0 /f</Path>
</RunSynchronousCommand>
<RunSynchronousCommand wcm:action="add">
<Order>44</Order>
<Path>reg.exe unload "HKU\DefaultUser"</Path>
</RunSynchronousCommand>
<RunSynchronousCommand wcm:action="add">
<Order>45</Order>
<Path>reg.exe add "HKLM\Software\Policies\Microsoft\Windows\CloudContent" /v "DisableWindowsConsumerFeatures" /t REG_DWORD /d 0 /f</Path>
</RunSynchronousCommand>
<RunSynchronousCommand wcm:action="add">
<Order>46</Order>
<Path>reg.exe add "HKLM\SYSTEM\CurrentControlSet\Control\BitLocker" /v "PreventDeviceEncryption" /t REG_DWORD /d 1 /f</Path>
</RunSynchronousCommand>
<RunSynchronousCommand wcm:action="add">
<Order>47</Order>
<Path>reg.exe load "HKU\DefaultUser" "C:\Users\Default\NTUSER.DAT"</Path>
</RunSynchronousCommand>
<RunSynchronousCommand wcm:action="add">
<Order>48</Order>
<Path>reg.exe add "HKU\DefaultUser\Software\Microsoft\Windows\CurrentVersion\Runonce" /v "ClassicContextMenu" /t REG_SZ /d "reg.exe add \"HKCU\Software\Classes\CLSID\{86ca1aa0-34aa-4e8b-a509-50c905bae2a2}\InprocServer32\" /ve /f" /f</Path>
</RunSynchronousCommand>
<RunSynchronousCommand wcm:action="add">
<Order>49</Order>
<Path>reg.exe unload "HKU\DefaultUser"</Path>
</RunSynchronousCommand>
</RunSynchronous>
</component>
</settings>
'@
if ((Microwin-TestCompatibleImage $imgVersion $([System.Version]::new(10,0,22000,1))) -eq $false) {
# Replace the placeholder text with an empty string to make it valid for Windows 10 Setup
$unattend = $unattend.Replace("<#REPLACEME#>", "").Trim()
} else {
# Replace the placeholder text with the Specialize pass
$unattend = $unattend.Replace("<#REPLACEME#>", $specPass).Trim()
}
# User password in Base64. According to Microsoft, this is the way you can hide this sensitive information.
# More information can be found here: https://learn.microsoft.com/en-us/windows-hardware/customize/desktop/wsim/hide-sensitive-data-in-an-answer-file
# Yeah, I know this is not the best way to protect this kind of data, but we all know how Microsoft is - "the Apple of security" (in a sense, it takes them
# an eternity to implement basic security features right. Just look at the NTLM and Kerberos situation!)
$b64pass = ""
# Replace default User and Password values with the provided parameters
$unattend = $unattend.Replace("USER-REPLACEME", $userName).Trim()
try {
# I want to play it safe here - I don't want encoding mismatch problems like last time
# NOTE: "Password" needs to be appended to the password specified by the user. Otherwise, a parse error will occur when processing oobeSystem.
# This will not be added to the actual password stored in the target system's SAM file - only the provided password
$b64pass = [Convert]::ToBase64String([System.Text.Encoding]::Unicode.GetBytes("$($userPassword)Password"))
} catch {
$b64pass = ""
}
if ($b64pass -ne "") {
# If we could encode the password with Base64, put it in the answer file and indicate that it's NOT in plain text
$unattend = $unattend.Replace("PW-REPLACEME", $b64pass).Trim()
$unattend = $unattend.Replace("PT-STATUS", "false").Trim()
$b64pass = ""
} else {
$unattend = $unattend.Replace("PW-REPLACEME", $userPassword).Trim()
$unattend = $unattend.Replace("PT-STATUS", "true").Trim()
}
# Save unattended answer file with UTF-8 encoding
$unattend | Out-File -FilePath "$env:temp\unattend.xml" -Force -Encoding utf8
}

View File

@@ -1,82 +0,0 @@
function Microwin-RemoveFeatures() {
<#
.SYNOPSIS
Removes certain features from ISO image
.PARAMETER UseCmdlets
Determines whether or not to use the DISM cmdlets for processing.
- If true, DISM cmdlets will be used
- If false, calls to the DISM executable will be made whilst selecting bits and pieces from the output as a string (that was how MicroWin worked before
the DISM conversion to cmdlets)
.EXAMPLE
Microwin-RemoveFeatures -UseCmdlets $true
#>
param (
[Parameter(Mandatory = $true, Position = 0)] [bool]$UseCmdlets
)
try {
if ($UseCmdlets) {
$featlist = (Get-WindowsOptionalFeature -Path "$scratchDir")
$featlist = $featlist | Where-Object {
$_.FeatureName -NotLike "*Defender*" -AND
$_.FeatureName -NotLike "*Printing*" -AND
$_.FeatureName -NotLike "*TelnetClient*" -AND
$_.FeatureName -NotLike "*PowerShell*" -AND
$_.FeatureName -NotLike "*NetFx*" -AND
$_.FeatureName -NotLike "*Media*" -AND
$_.FeatureName -NotLike "*NFS*" -AND
$_.FeatureName -NotLike "*SearchEngine*" -AND
$_.FeatureName -NotLike "*RemoteDesktop*" -AND
$_.State -ne "Disabled"
}
} else {
$featList = dism /english /image="$scratchDir" /get-features | Select-String -Pattern "Feature Name : " -CaseSensitive -SimpleMatch
if ($?) {
$featList = $featList -split "Feature Name : " | Where-Object {$_}
# Exclude the same items. Note: for now, this doesn't exclude those features that are disabled.
# This will appear in the future
$featList = $featList | Where-Object {
$_ -NotLike "*Defender*" -AND
$_ -NotLike "*Printing*" -AND
$_ -NotLike "*TelnetClient*" -AND
$_ -NotLike "*PowerShell*" -AND
$_ -NotLike "*NetFx*" -AND
$_ -NotLike "*Media*" -AND
$_ -NotLike "*NFS*" -AND
$_ -NotLike "*SearchEngine*" -AND
$_ -NotLike "*RemoteDesktop*"
}
} else {
Write-Host "Features could not be obtained with DISM. MicroWin processing will continue, but features will be skipped."
return
}
}
if ($UseCmdlets) {
foreach ($feature in $featList) {
$status = "Removing feature $($feature.FeatureName)"
Write-Progress -Activity "Removing features" -Status $status -PercentComplete ($counter++/$featlist.Count*100)
Write-Debug "Removing feature $($feature.FeatureName)"
Disable-WindowsOptionalFeature -Path "$scratchDir" -FeatureName $($feature.FeatureName) -Remove -ErrorAction SilentlyContinue -NoRestart
}
} else {
foreach ($feature in $featList) {
$status = "Removing feature $feature"
Write-Progress -Activity "Removing features" -Status $status -PercentComplete ($counter++/$featlist.Count*100)
Write-Debug "Removing feature $feature"
dism /english /image="$scratchDir" /disable-feature /featurename=$feature /remove /quiet /norestart | Out-Null
if ($? -eq $false) {
Write-Host "Feature $feature could not be disabled."
}
}
}
Write-Progress -Activity "Removing features" -Status "Ready" -Completed
Write-Host "You can re-enable the disabled features at any time, using either Windows Update or the SxS folder in <installation media>\Sources."
} catch {
Write-Host "Unable to get information about the features. A fallback will be used..."
Write-Host "Error information: $($_.Exception.Message)" -ForegroundColor Yellow
Microwin-RemoveFeatures -UseCmdlets $false
}
}

View File

@@ -1,46 +0,0 @@
function Microwin-RemoveFileOrDirectory([string]$pathToDelete, [string]$mask = "", [switch]$Directory = $false) {
if(([string]::IsNullOrEmpty($pathToDelete))) { return }
if (-not (Test-Path -Path "$($pathToDelete)")) { return }
$yesNo = Get-LocalizedYesNo
Write-Host "[INFO] In Your local takeown expects '$($yesNo[0])' as a Yes answer."
$itemsToDelete = [System.Collections.ArrayList]::new()
if ($mask -eq "") {
Write-Debug "Adding $($pathToDelete) to array."
[void]$itemsToDelete.Add($pathToDelete)
} else {
Write-Debug "Adding $($pathToDelete) to array and mask is $($mask)"
if ($Directory) {
$itemsToDelete = Get-ChildItem $pathToDelete -Include $mask -Recurse -Directory
} else {
$itemsToDelete = Get-ChildItem $pathToDelete -Include $mask -Recurse
}
}
foreach($itemToDelete in $itemsToDelete) {
$status = "Deleting $($itemToDelete)"
Write-Progress -Activity "Removing Items" -Status $status -PercentComplete ($counter++/$itemsToDelete.Count*100)
if (Test-Path -Path "$($itemToDelete)" -PathType Container) {
$status = "Deleting directory: $($itemToDelete)"
takeown /r /d $yesNo[0] /a /f "$($itemToDelete)"
icacls "$($itemToDelete)" /q /c /t /reset
icacls $itemToDelete /setowner "*S-1-5-32-544"
icacls $itemToDelete /grant "*S-1-5-32-544:(OI)(CI)F" /t /c /q
Remove-Item -Force -Recurse "$($itemToDelete)"
}
elseif (Test-Path -Path "$($itemToDelete)" -PathType Leaf) {
$status = "Deleting file: $($itemToDelete)"
takeown /a /f "$($itemToDelete)"
icacls "$($itemToDelete)" /q /c /t /reset
icacls "$($itemToDelete)" /setowner "*S-1-5-32-544"
icacls "$($itemToDelete)" /grant "*S-1-5-32-544:(OI)(CI)F" /t /c /q
Remove-Item -Force "$($itemToDelete)"
}
}
Write-Progress -Activity "Removing Items" -Status "Ready" -Completed
}

View File

@@ -1,129 +0,0 @@
function Microwin-RemovePackages {
<#
.SYNOPSIS
Removes certain packages from ISO image
.PARAMETER UseCmdlets
Determines whether or not to use the DISM cmdlets for processing.
- If true, DISM cmdlets will be used
- If false, calls to the DISM executable will be made whilst selecting bits and pieces from the output as a string (that was how MicroWin worked before
the DISM conversion to cmdlets)
.EXAMPLE
Microwin-RemovePackages -UseCmdlets $true
#>
param (
[Parameter(Mandatory = $true, Position = 0)] [bool]$UseCmdlets
)
try {
if ($useCmdlets) {
$pkglist = (Get-WindowsPackage -Path "$scratchDir").PackageName
$pkglist = $pkglist | Where-Object {
$_ -NotLike "*ApplicationModel*" -AND
$_ -NotLike "*indows-Client-LanguagePack*" -AND
$_ -NotLike "*LanguageFeatures-Basic*" -AND
$_ -NotLike "*Package_for_ServicingStack*" -AND
$_ -NotLike "*DotNet*" -AND
$_ -NotLike "*Notepad*" -AND
$_ -NotLike "*WMIC*" -AND
$_ -NotLike "*Ethernet*" -AND
$_ -NotLike "*Wifi*" -AND
$_ -NotLike "*FodMetadata*" -AND
$_ -NotLike "*Foundation*" -AND
$_ -NotLike "*LanguageFeatures*" -AND
$_ -NotLike "*VBSCRIPT*" -AND
$_ -NotLike "*License*" -AND
$_ -NotLike "*Hello-Face*" -AND
$_ -NotLike "*ISE*" -AND
$_ -NotLike "*OpenSSH*"
}
} else {
$pkgList = dism /english /image="$scratchDir" /get-packages | Select-String -Pattern "Package Identity : " -CaseSensitive -SimpleMatch
if ($?) {
$pkgList = $pkgList -split "Package Identity : " | Where-Object {$_}
# Exclude the same items.
$pkgList = $pkgList | Where-Object {
$_ -NotLike "*ApplicationModel*" -AND
$_ -NotLike "*indows-Client-LanguagePack*" -AND
$_ -NotLike "*LanguageFeatures-Basic*" -AND
$_ -NotLike "*Package_for_ServicingStack*" -AND
$_ -NotLike "*DotNet*" -AND
$_ -NotLike "*Notepad*" -AND
$_ -NotLike "*WMIC*" -AND
$_ -NotLike "*Ethernet*" -AND
$_ -NotLike "*Wifi*" -AND
$_ -NotLike "*FodMetadata*" -AND
$_ -NotLike "*Foundation*" -AND
$_ -NotLike "*LanguageFeatures*" -AND
$_ -NotLike "*VBSCRIPT*" -AND
$_ -NotLike "*License*" -AND
$_ -NotLike "*Hello-Face*" -AND
$_ -NotLike "*ISE*" -AND
$_ -NotLike "*OpenSSH*"
}
} else {
Write-Host "Packages could not be obtained with DISM. MicroWin processing will continue, but packages will be skipped."
return
}
}
if ($UseCmdlets) {
$failedCount = 0
$erroredPackages = [System.Collections.Generic.List[ErroredPackage]]::new()
foreach ($pkg in $pkglist) {
try {
$status = "Removing $pkg"
Write-Progress -Activity "Removing Packages" -Status $status -PercentComplete ($counter++/$pkglist.Count*100)
Remove-WindowsPackage -Path "$scratchDir" -PackageName $pkg -NoRestart -ErrorAction SilentlyContinue
} catch {
# This can happen if the package that is being removed is a permanent one
$erroredPackages.Add([ErroredPackage]::new($pkg, $_.Exception.Message))
$failedCount += 1
continue
}
}
} else {
foreach ($package in $pkgList) {
$status = "Removing package $package"
Write-Progress -Activity "Removing Packages" -Status $status -PercentComplete ($counter++/$pkglist.Count*100)
Write-Debug "Removing package $package"
dism /english /image="$scratchDir" /remove-package /packagename=$package /quiet /norestart | Out-Null
if ($? -eq $false) {
Write-Host "Package $package could not be removed."
}
}
}
Write-Progress -Activity "Removing Packages" -Status "Ready" -Completed
if ($UseCmdlets -and $failedCount -gt 0)
{
Write-Host "$failedCount package(s) could not be removed. Your image will still work fine, however. Below is information on what packages failed to be removed and why."
if ($erroredPackages.Count -gt 0)
{
$erroredPackages = $erroredPackages | Sort-Object -Property ErrorMessage
$previousErroredPackage = $erroredPackages[0]
$counter = 0
Write-Host ""
Write-Host "- $($previousErroredPackage.ErrorMessage)"
foreach ($erroredPackage in $erroredPackages) {
if ($erroredPackage.ErrorMessage -ne $previousErroredPackage.ErrorMessage) {
Write-Host ""
$counter = 0
Write-Host "- $($erroredPackage.ErrorMessage)"
}
$counter += 1
Write-Host " $counter) $($erroredPackage.PackageName)"
$previousErroredPackage = $erroredPackage
}
Write-Host ""
}
}
} catch {
Write-Host "Unable to get information about the packages. A fallback will be used..."
Write-Host "Error information: $($_.Exception.Message)" -ForegroundColor Yellow
Microwin-RemovePackages -UseCmdlets $false
}
}

View File

@@ -1,96 +0,0 @@
function Microwin-RemoveProvisionedPackages() {
<#
.SYNOPSIS
Removes AppX packages from a Windows image during MicroWin processing
.PARAMETER UseCmdlets
Determines whether or not to use the DISM cmdlets for processing.
- If true, DISM cmdlets will be used
- If false, calls to the DISM executable will be made whilst selecting bits and pieces from the output as a string (that was how MicroWin worked before
the DISM conversion to cmdlets)
.EXAMPLE
Microwin-RemoveProvisionedPackages
#>
param (
[Parameter(Mandatory = $true, Position = 0)] [bool]$UseCmdlets
)
try
{
if ($UseCmdlets) {
$appxProvisionedPackages = Get-AppxProvisionedPackage -Path "$($scratchDir)" | Where-Object {
$_.PackageName -NotLike "*AppInstaller*" -AND
$_.PackageName -NotLike "*Store*" -and
$_.PackageName -NotLike "*Notepad*" -and
$_.PackageName -NotLike "*Printing*" -and
$_.PackageName -NotLike "*YourPhone*" -and
$_.PackageName -NotLike "*Xbox*" -and
$_.PackageName -NotLike "*WindowsTerminal*" -and
$_.PackageName -NotLike "*Calculator*" -and
$_.PackageName -NotLike "*Photos*" -and
$_.PackageName -NotLike "*VCLibs*" -and
$_.PackageName -NotLike "*Paint*" -and
$_.PackageName -NotLike "*Gaming*" -and
$_.PackageName -NotLike "*Extension*" -and
$_.PackageName -NotLike "*SecHealthUI*" -and
$_.PackageName -NotLike "*ScreenSketch*"
}
} else {
$appxProvisionedPackages = dism /english /image="$scratchDir" /get-provisionedappxpackages | Select-String -Pattern "PackageName : " -CaseSensitive -SimpleMatch
if ($?) {
$appxProvisionedPackages = $appxProvisionedPackages -split "PackageName : " | Where-Object {$_}
# Exclude the same items.
$appxProvisionedPackages = $appxProvisionedPackages | Where-Object {
$_ -NotLike "*AppInstaller*" -AND
$_ -NotLike "*Store*" -and
$_ -NotLike "*Notepad*" -and
$_ -NotLike "*Printing*" -and
$_ -NotLike "*YourPhone*" -and
$_ -NotLike "*Xbox*" -and
$_ -NotLike "*WindowsTerminal*" -and
$_ -NotLike "*Calculator*" -and
$_ -NotLike "*Photos*" -and
$_ -NotLike "*VCLibs*" -and
$_ -NotLike "*Paint*" -and
$_ -NotLike "*Gaming*" -and
$_ -NotLike "*Extension*" -and
$_ -NotLike "*SecHealthUI*" -and
$_ -NotLike "*ScreenSketch*"
}
} else {
Write-Host "AppX packages could not be obtained with DISM. MicroWin processing will continue, but AppX packages will be skipped."
return
}
}
$counter = 0
if ($UseCmdlets) {
foreach ($appx in $appxProvisionedPackages) {
$status = "Removing Provisioned $($appx.PackageName)"
Write-Progress -Activity "Removing Provisioned Apps" -Status $status -PercentComplete ($counter++/$appxProvisionedPackages.Count*100)
try {
Remove-AppxProvisionedPackage -Path "$scratchDir" -PackageName $appx.PackageName -ErrorAction SilentlyContinue
} catch {
Write-Host "Application $($appx.PackageName) could not be removed"
continue
}
}
} else {
foreach ($appx in $appxProvisionedPackages) {
$status = "Removing Provisioned $appx"
Write-Progress -Activity "Removing Provisioned Apps" -Status $status -PercentComplete ($counter++/$appxProvisionedPackages.Count*100)
dism /english /image="$scratchDir" /remove-provisionedappxpackage /packagename=$appx /quiet /norestart | Out-Null
if ($? -eq $false) {
Write-Host "AppX package $appx could not be removed."
}
}
}
Write-Progress -Activity "Removing Provisioned Apps" -Status "Ready" -Completed
}
catch
{
Write-Host "Unable to get information about the AppX packages. A fallback will be used..."
Write-Host "Error information: $($_.Exception.Message)" -ForegroundColor Yellow
Microwin-RemoveProvisionedPackages -UseCmdlets $false
}
}

View File

@@ -1,26 +0,0 @@
function Microwin-TestCompatibleImage() {
<#
.SYNOPSIS
Checks the version of a Windows image and determines whether or not it is compatible with a specific feature depending on a desired version
.PARAMETER Name
imgVersion - The version of the Windows image
desiredVersion - The version to compare the image version with
#>
param
(
[Parameter(Mandatory, position=0)]
[string]$imgVersion,
[Parameter(Mandatory, position=1)]
[Version]$desiredVersion
)
try {
$version = [Version]$imgVersion
return $version -ge $desiredVersion
} catch {
return $False
}
}

View File

@@ -1,11 +0,0 @@
function Microwin-TestKitsRootPaths {
param (
[Parameter(Mandatory = $true, Position = 0)] [string]$adkKitsRootPath,
[Parameter(Mandatory = $true, Position = 1)] [string]$adkKitsRootPath_WOW64Environ
)
if (Test-Path "$adkKitsRootPath") { return $true }
if (Test-Path "$adkKitsRootPath_WOW64Environ") { return $true }
return $false
}

View File

@@ -1,28 +0,0 @@
function Toggle-MicrowinPanel {
<#
.SYNOPSIS
Toggles the visibility of the Microwin options and ISO panels in the GUI.
.DESCRIPTION
This function toggles the visibility of the Microwin options and ISO panels in the GUI.
.PARAMETER MicrowinOptionsPanel
The panel containing Microwin options.
.PARAMETER MicrowinISOPanel
The panel containing the Microwin ISO options.
.EXAMPLE
Toggle-MicrowinPanel 1
#>
param (
[Parameter(Mandatory = $true, Position = 0)]
[ValidateSet(1, 2)]
[int]$PanelNumber
)
if ($PanelNumber -eq 1) {
$sync.MicrowinISOPanel.Visibility = 'Visible'
$sync.MicrowinOptionsPanel.Visibility = 'Collapsed'
} elseif ($PanelNumber -eq 2) {
$sync.MicrowinOptionsPanel.Visibility = 'Visible'
$sync.MicrowinISOPanel.Visibility = 'Collapsed'
}
}

View File

@@ -53,7 +53,6 @@ function Invoke-WinUtilFontScaling {
"CustomDialogWidth",
"CustomDialogHeight",
"CustomDialogLogoSize",
"MicroWinLogoSize",
"ToolTipWidth"
)

View File

@@ -1,10 +1,8 @@
function Invoke-AutoConfigDialog {
<#
.SYNOPSIS
Sets the automatic configuration file based on a specified JSON file
#>
[System.Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms") | Out-Null
@@ -12,13 +10,11 @@ function Invoke-AutoConfigDialog {
$OFD.Filter = "JSON Files (*.json)|*.json"
$OFD.ShowDialog()
if (($OFD.FileName -eq "") -and ($sync.MicrowinAutoConfigBox.Text -eq ""))
if ($OFD.FileName -eq "")
{
Write-Host "No automatic config file has been selected. Continuing without one..."
return
}
elseif ($OFD.FileName -ne "")
{
$sync.MicrowinAutoConfigBox.Text = "$($OFD.FileName)"
}
return $OFD.FileName
}

View File

@@ -58,14 +58,10 @@ function Invoke-WPFButton {
"WPFWinUtilShortcut" {Invoke-WPFShortcut -ShortcutToAdd "WinUtil" -RunAsAdmin $true}
"WPFGetInstalled" {Invoke-WPFGetInstalled -CheckBox "winget"}
"WPFGetInstalledTweaks" {Invoke-WPFGetInstalled -CheckBox "tweaks"}
"WPFGetIso" {Invoke-MicrowinGetIso}
"WPFMicrowin" {Invoke-Microwin}
"WPFCloseButton" {Invoke-WPFCloseButton}
"WPFWinUtilInstallPSProfile" {Invoke-WinUtilInstallPSProfile}
"WPFWinUtilUninstallPSProfile" {Invoke-WinUtilUninstallPSProfile}
"WPFWinUtilSSHServer" {Invoke-WPFSSHServer}
"WPFselectedAppsButton" {$sync.selectedAppsPopup.IsOpen = -not $sync.selectedAppsPopup.IsOpen}
"WPFMicrowinPanelBack" {Toggle-MicrowinPanel 1}
"MicrowinAutoConfigBtn" {Invoke-AutoConfigDialog}
}
}