mirror of
https://github.com/ChrisTitusTech/winutil.git
synced 2026-08-09 09:31:15 +10:00
Clean up analyzer warnings across app search and ISO workflows (#4794)
* Clean up analyzer warnings * Align analyzer warning cleanup policy * Run PSScriptAnalyzer directly in unittests workflow * Bind lazy-rendered buttons to click handlers * Remove WinUtil performance tracing * Fix Win11 ISO creator temp directory reuse
This commit is contained in:
@@ -9,14 +9,22 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v7
|
||||
- name: lint
|
||||
uses: devblackops/github-action-psscriptanalyzer@master
|
||||
with:
|
||||
sendComment: false
|
||||
settingsPath: lint/PSScriptAnalyser.ps1
|
||||
failOnErrors: false
|
||||
failOnWarnings: false
|
||||
failOnInfos: false
|
||||
- name: Install PSScriptAnalyzer
|
||||
run: |
|
||||
Set-PSRepository -Name PSGallery -InstallationPolicy Trusted
|
||||
Install-Module -Name PSScriptAnalyzer -RequiredVersion 1.20.0 -Scope CurrentUser -Force
|
||||
Import-Module PSScriptAnalyzer -RequiredVersion 1.20.0 -Force
|
||||
Get-Module PSScriptAnalyzer | Select-Object Name, Version, Path
|
||||
shell: pwsh
|
||||
- name: Run PSScriptAnalyzer
|
||||
run: |
|
||||
$results = Invoke-ScriptAnalyzer -Path . -Settings ./lint/PSScriptAnalyser.ps1 -Recurse
|
||||
if ($results) {
|
||||
$results | Format-Table -AutoSize | Out-String -Width 4096 | Write-Host
|
||||
} else {
|
||||
Write-Host "PSScriptAnalyzer found no diagnostics."
|
||||
}
|
||||
shell: pwsh
|
||||
test:
|
||||
runs-on: windows-latest
|
||||
|
||||
|
||||
@@ -188,4 +188,5 @@ When the user corrects an agent approach, add or tighten one concrete rule here
|
||||
- Keep package install/uninstall process launches simple unless explicitly requested; do not add a separate stdout/stderr process logging helper for winget or Chocolatey.
|
||||
- When the active log file is owned by `Start-Transcript`, do not call `Add-Content` against that file; write to host output so the transcript captures the line in the same log file without recording a terminating-error diagnostic.
|
||||
- Log install/uninstall package names and package-manager IDs before queuing background runspace work; do not rely on runspace host output for the package identity.
|
||||
- Keep performance tracing helpers under `tools/perf`; include them in generated output only through `Compile.ps1 -Trace`.
|
||||
- For Win11 Creator, start each new ISO modification in a fresh `WinUtil_Win11ISO_*` temp directory; existing-work detection is only for resuming/exporting already modified media.
|
||||
- For Script Analyzer cleanup, fix actionable source warnings first and do not globally suppress accepted convention warnings such as plural names, `ShouldProcess` on UI helpers, `$global:sync`, or compile-time cross-file false positives.
|
||||
|
||||
+3
-38
@@ -1,27 +1,9 @@
|
||||
param (
|
||||
[switch]$Run,
|
||||
[switch]$Trace
|
||||
[switch]$Run
|
||||
)
|
||||
|
||||
$OFS = "`r`n"
|
||||
|
||||
function Get-WinUtilTraceStrippedContent {
|
||||
param(
|
||||
[Parameter(Mandatory = $true)]
|
||||
[string]$Content
|
||||
)
|
||||
|
||||
if ($Trace) {
|
||||
return $Content
|
||||
}
|
||||
|
||||
$filteredLines = $Content -split "`r?`n" | Where-Object {
|
||||
$_ -notmatch '^\s*(Start-WinUtilPerformanceTrace|Stop-WinUtilPerformanceTrace|Write-WinUtilPerformanceCheckpoint)\b'
|
||||
}
|
||||
|
||||
$filteredLines -join "`r`n"
|
||||
}
|
||||
|
||||
# Variable to sync between runspaces
|
||||
$sync = [Hashtable]::Synchronized(@{})
|
||||
$sync.configs = @{}
|
||||
@@ -29,17 +11,7 @@ $sync.configs = @{}
|
||||
$script = (Get-Content -Path scripts\start.ps1) -replace '#{replaceme}', (Get-Date -Format 'yy.MM.dd')
|
||||
|
||||
$script += Get-ChildItem -Path functions -Recurse -File | ForEach-Object {
|
||||
Get-WinUtilTraceStrippedContent -Content (Get-Content -Path $_.FullName -Raw)
|
||||
}
|
||||
|
||||
if ($Trace) {
|
||||
$script += Get-ChildItem -Path tools\perf -Filter *.ps1 -File | Get-Content -Raw
|
||||
|
||||
$script += @'
|
||||
$sync.PerformanceTraceEnabled = $true
|
||||
Start-WinUtilPerformanceTrace
|
||||
Write-WinUtilPerformanceCheckpoint -Name "Config load start"
|
||||
'@
|
||||
Get-Content -Path $_.FullName -Raw
|
||||
}
|
||||
|
||||
Get-ChildItem config | ForEach-Object {
|
||||
@@ -57,13 +29,6 @@ Get-ChildItem config | ForEach-Object {
|
||||
|
||||
$sync.configs[$_.BaseName] = $obj
|
||||
$script += "`$sync.configs.$($_.BaseName) = @'`r`n$json`r`n'@ | ConvertFrom-Json"
|
||||
if ($Trace) {
|
||||
$script += "`r`nWrite-WinUtilPerformanceCheckpoint -Name `"Config $($_.BaseName) loaded`""
|
||||
}
|
||||
}
|
||||
|
||||
if ($Trace) {
|
||||
$script += "`r`nWrite-WinUtilPerformanceCheckpoint -Name `"Config load complete`""
|
||||
}
|
||||
|
||||
$xaml = Get-Content -Path xaml\inputXML.xaml -Raw
|
||||
@@ -72,7 +37,7 @@ $script += "`$inputXML = @'`r`n$xaml`r`n'@"
|
||||
$autounattendXml = Get-Content -Path tools\autounattend.xml -Raw
|
||||
$script += "`$WinUtilAutounattendXml = @'`r`n$autounattendXml`r`n'@"
|
||||
|
||||
$script += Get-WinUtilTraceStrippedContent -Content (Get-Content -Path scripts\main.ps1 -Raw)
|
||||
$script += Get-Content -Path scripts\main.ps1 -Raw
|
||||
|
||||
Set-Content -Path winutil.ps1 -Value $script
|
||||
|
||||
|
||||
@@ -83,9 +83,9 @@ function Find-AppsByNameOrDescription {
|
||||
$categoryLabel.Visibility = [Windows.Visibility]::Visible
|
||||
|
||||
# Search through apps in this category
|
||||
$wrapPanel.Children | ForEach-Object {
|
||||
foreach ($appControl in $wrapPanel.Children) {
|
||||
# Safely retrieve app entry from hashtable
|
||||
$appTag = $_.Tag
|
||||
$appTag = $appControl.Tag
|
||||
$appEntry = $null
|
||||
|
||||
if (-not [string]::IsNullOrWhiteSpace($appTag) -and $sync.configs.applicationsHashtable.ContainsKey($appTag)) {
|
||||
@@ -99,16 +99,16 @@ function Find-AppsByNameOrDescription {
|
||||
|
||||
if ($contentMatch -or $descriptionMatch) {
|
||||
# Show the App and mark that this category has a match
|
||||
$_.Visibility = [Windows.Visibility]::Visible
|
||||
$appControl.Visibility = [Windows.Visibility]::Visible
|
||||
$categoryHasMatch = $true
|
||||
}
|
||||
else {
|
||||
$_.Visibility = [Windows.Visibility]::Collapsed
|
||||
$appControl.Visibility = [Windows.Visibility]::Collapsed
|
||||
}
|
||||
}
|
||||
else {
|
||||
# Hide app if no entry found (data integrity issue)
|
||||
$_.Visibility = [Windows.Visibility]::Collapsed
|
||||
$appControl.Visibility = [Windows.Visibility]::Collapsed
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -114,6 +114,7 @@ function Find-TweaksByNameOrDescription {
|
||||
}
|
||||
catch {
|
||||
# Silent catch - UI element may be disposed
|
||||
$null = $_
|
||||
}
|
||||
|
||||
return
|
||||
@@ -303,5 +304,6 @@ function Find-TweaksByNameOrDescription {
|
||||
catch {
|
||||
# Silent catch - UI elements may be disposed or in unexpected state
|
||||
# Do not log to terminal as this function is called on every keystroke
|
||||
$null = $_
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,12 +14,12 @@ function Get-WinUtilSelectedPackages {
|
||||
Invoke-WPFUIThread -ScriptBlock { Set-WinUtilTaskbaritem -state "Normal" -value 0.01 -overlay "logo" }
|
||||
}
|
||||
|
||||
$packages = [System.Collections.Hashtable]::new()
|
||||
$packagesWinget = [System.Collections.ArrayList]::new()
|
||||
$packagesChoco = [System.Collections.ArrayList]::new()
|
||||
|
||||
$packages[[PackageManagers]::Winget] = $packagesWinget
|
||||
$packages[[PackageManagers]::Choco] = $packagesChoco
|
||||
$packages = @{
|
||||
([PackageManagers]::Winget) = $packagesWinget
|
||||
([PackageManagers]::Choco) = $packagesChoco
|
||||
}
|
||||
|
||||
function Add-PackageId {
|
||||
param(
|
||||
|
||||
@@ -19,8 +19,9 @@ function Get-WinUtilVariables {
|
||||
if ($Type -contains $objType) {
|
||||
Write-Output $psitem
|
||||
}
|
||||
} catch {
|
||||
<#I am here so errors don't get outputted for a couple variables that don't have the .GetType() attribute#>
|
||||
}
|
||||
catch {
|
||||
$null = $_
|
||||
}
|
||||
}
|
||||
return $output
|
||||
|
||||
@@ -34,6 +34,5 @@ function Initialize-WinUtilRunspacePool {
|
||||
)
|
||||
|
||||
$sync.runspace.Open()
|
||||
Write-WinUtilPerformanceCheckpoint -Name "Runspace pool initialized"
|
||||
return $sync.runspace
|
||||
}
|
||||
|
||||
@@ -16,28 +16,22 @@ function Initialize-WinUtilTabContent {
|
||||
"Install" {
|
||||
Invoke-WPFUIElements -configVariable $sync.configs.appnavigation -targetGridName "appscategory" -columncount 1
|
||||
Initialize-WPFUI -targetGridName "appscategory"
|
||||
Write-WinUtilPerformanceCheckpoint -Name "App navigation UI created"
|
||||
|
||||
Initialize-WPFUI -targetGridName "appspanel"
|
||||
Write-WinUtilPerformanceCheckpoint -Name "Install UI created"
|
||||
}
|
||||
"Tweaks" {
|
||||
Invoke-WPFUIElements -configVariable $sync.configs.tweaks -targetGridName "tweakspanel" -columncount 2
|
||||
Write-WinUtilPerformanceCheckpoint -Name "Tweaks UI created"
|
||||
}
|
||||
"Config" {
|
||||
Invoke-WPFUIElements -configVariable $sync.configs.feature -targetGridName "featurespanel" -columncount 2
|
||||
Write-WinUtilPerformanceCheckpoint -Name "Features UI created"
|
||||
}
|
||||
"AppX" {
|
||||
Invoke-WPFUIElements -configVariable $sync.configs.appx -targetGridName "appxpanel" -columncount 2
|
||||
Write-WinUtilPerformanceCheckpoint -Name "AppX UI created"
|
||||
}
|
||||
"Win11 Creator" {
|
||||
if ($sync.Form -and $sync.Form.Dispatcher) {
|
||||
$sync.Form.Dispatcher.BeginInvoke([System.Windows.Threading.DispatcherPriority]::Background, [action]{ Invoke-WinUtilISOCheckExistingWork }) | Out-Null
|
||||
}
|
||||
Write-WinUtilPerformanceCheckpoint -Name "Win11 ISO tab initialized"
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -6,16 +6,13 @@ function Initialize-WinUtilTaskbarOverlayAssets {
|
||||
|
||||
if ($IncludeLogo -and -not $sync["logorender"]) {
|
||||
$sync["logorender"] = (Invoke-WinUtilAssets -Type "Logo" -Size 90 -Render)
|
||||
Write-WinUtilPerformanceCheckpoint -Name "Taskbar logo asset rendered"
|
||||
}
|
||||
|
||||
if ($IncludeStatusAssets -and -not $sync["checkmarkrender"]) {
|
||||
$sync["checkmarkrender"] = (Invoke-WinUtilAssets -Type "checkmark" -Size 512 -Render)
|
||||
Write-WinUtilPerformanceCheckpoint -Name "Taskbar checkmark asset rendered"
|
||||
}
|
||||
|
||||
if ($IncludeStatusAssets -and -not $sync["warningrender"]) {
|
||||
$sync["warningrender"] = (Invoke-WinUtilAssets -Type "warning" -Size 512 -Render)
|
||||
Write-WinUtilPerformanceCheckpoint -Name "Taskbar warning asset rendered"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,5 +11,6 @@ function Install-WinUtilChoco {
|
||||
}
|
||||
|
||||
Write-Host "Chocolatey is not installed. Installing now..."
|
||||
Invoke-WebRequest -Uri https://community.chocolatey.org/install.ps1 -UseBasicParsing | Invoke-Expression
|
||||
$installScript = Invoke-WebRequest -Uri https://community.chocolatey.org/install.ps1 -UseBasicParsing
|
||||
Invoke-Command -ScriptBlock ([scriptblock]::Create($installScript.Content))
|
||||
}
|
||||
|
||||
@@ -55,8 +55,6 @@ Function Invoke-WinUtilCurrentSystem {
|
||||
$entry = $sync.configs.tweaks.$Config
|
||||
$registryKeys = $entry.registry
|
||||
$serviceKeys = $entry.service
|
||||
$appxKeys = $entry.appx
|
||||
$invokeScript = $entry.InvokeScript
|
||||
$entryType = $entry.Type
|
||||
|
||||
if ($registryKeys -or $serviceKeys) {
|
||||
|
||||
@@ -1,12 +1,13 @@
|
||||
function Write-Win11ISOLog {
|
||||
param([string]$Message)
|
||||
$ts = (Get-Date).ToString("HH:mm:ss")
|
||||
$logLine = "[$ts] $Message"
|
||||
$sync["WPFWin11ISOStatusLog"].Dispatcher.Invoke([action]{
|
||||
$current = $sync["WPFWin11ISOStatusLog"].Text
|
||||
if ($current -eq "Ready. Please select a Windows 11 ISO to begin.") {
|
||||
$sync["WPFWin11ISOStatusLog"].Text = "[$ts] $Message"
|
||||
$sync["WPFWin11ISOStatusLog"].Text = $logLine
|
||||
} else {
|
||||
$sync["WPFWin11ISOStatusLog"].Text += "`n[$ts] $Message"
|
||||
$sync["WPFWin11ISOStatusLog"].Text += "`n$logLine"
|
||||
}
|
||||
$sync["WPFWin11ISOStatusLog"].CaretIndex = $sync["WPFWin11ISOStatusLog"].Text.Length
|
||||
$sync["WPFWin11ISOStatusLog"].ScrollToEnd()
|
||||
@@ -151,14 +152,9 @@ function Invoke-WinUtilISOModify {
|
||||
$sync["WPFWin11ISOModifyButton"].IsEnabled = $false
|
||||
$sync["Win11ISOModifying"] = $true
|
||||
|
||||
$existingWorkDir = Get-Item -Path (Join-Path $env:TEMP "WinUtil_Win11ISO*") |
|
||||
Where-Object { $_.PSIsContainer } | Sort-Object LastWriteTime -Descending | Select-Object -First 1
|
||||
|
||||
$workDir = if ($existingWorkDir) {
|
||||
Write-Win11ISOLog "Reusing existing temp directory: $($existingWorkDir.FullName)"
|
||||
$existingWorkDir.FullName
|
||||
} else {
|
||||
Join-Path $env:TEMP "WinUtil_Win11ISO_$(Get-Date -Format 'yyyyMMdd_HHmmss')"
|
||||
$workDir = Join-Path $env:TEMP "WinUtil_Win11ISO_$(Get-Date -Format 'yyyyMMdd_HHmmss')"
|
||||
if (Test-Path $workDir) {
|
||||
$workDir = Join-Path $env:TEMP "WinUtil_Win11ISO_$(Get-Date -Format 'yyyyMMdd_HHmmss')_$(([guid]::NewGuid()).ToString('N').Substring(0, 8))"
|
||||
}
|
||||
|
||||
$autounattendContent = if ($WinUtilAutounattendXml) {
|
||||
@@ -293,9 +289,11 @@ function Invoke-WinUtilISOModify {
|
||||
[scriptblock]$Logger
|
||||
)
|
||||
|
||||
$metadataLogger = $Logger
|
||||
|
||||
function LogMeta([string]$Message) {
|
||||
if ($Logger) {
|
||||
$null = $Logger.Invoke($Message)
|
||||
if ($metadataLogger) {
|
||||
$null = $metadataLogger.Invoke($Message)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -368,8 +366,11 @@ function Invoke-WinUtilISOModify {
|
||||
Log "ISO contents copied."
|
||||
SetProgress "Mounting install.wim..." 25
|
||||
|
||||
$localWim = Join-Path $isoContents "sources\install.wim"
|
||||
if (-not (Test-Path $localWim)) { $localWim = Join-Path $isoContents "sources\install.esd" }
|
||||
$sourceImageFileName = Split-Path $wimPath -Leaf
|
||||
$localWim = Join-Path $isoContents "sources\$sourceImageFileName"
|
||||
if (-not (Test-Path $localWim)) {
|
||||
throw "Copied ISO image file not found: sources\$sourceImageFileName"
|
||||
}
|
||||
Set-ItemProperty -Path $localWim -Name IsReadOnly -Value $false
|
||||
|
||||
Log "Mounting install.wim (Index ${selectedWimIndex}: $selectedEditionName) at $mountDir..."
|
||||
@@ -590,10 +591,10 @@ function Invoke-WinUtilISOCleanAndReset {
|
||||
}
|
||||
|
||||
foreach ($d in $allDirs) {
|
||||
try { Remove-Item -Path $d.FullName -Force } catch {}
|
||||
try { Remove-Item -Path $d.FullName -Force } catch { Log "WARNING: could not delete $($d.FullName): $_" }
|
||||
}
|
||||
|
||||
try { Remove-Item -Path $workDir -Recurse -Force } catch {}
|
||||
try { Remove-Item -Path $workDir -Recurse -Force } catch { Log "WARNING: could not delete temp directory ${workDir}: $_" }
|
||||
|
||||
if (Test-Path $workDir) {
|
||||
Log "WARNING: some items could not be deleted in $workDir"
|
||||
|
||||
@@ -70,15 +70,11 @@ function Invoke-WinUtilISOScript {
|
||||
[int]$InstallImageIndex = 1,
|
||||
[scriptblock]$Log = { param($m) Write-Output $m }
|
||||
)
|
||||
|
||||
$adminSID = New-Object System.Security.Principal.SecurityIdentifier('S-1-5-32-544')
|
||||
$adminGroup = $adminSID.Translate([System.Security.Principal.NTAccount])
|
||||
|
||||
function Set-ISOScriptReg {
|
||||
param ([string]$path, [string]$name, [string]$type, [string]$value)
|
||||
param ([string]$Path, [string]$Name, [string]$Type, [string]$Value)
|
||||
try {
|
||||
& reg add $path /v $name /t $type /d $value /f
|
||||
& $Log "Set registry value: $path\$name"
|
||||
& reg add $Path /v $Name /t $Type /d $Value /f
|
||||
& $Log "Set registry value: $Path\$Name"
|
||||
} catch {
|
||||
& $Log "Error setting registry value: $_"
|
||||
}
|
||||
@@ -114,7 +110,7 @@ function Invoke-WinUtilISOScript {
|
||||
& $Logger "boot.wim driver injection complete."
|
||||
} catch {
|
||||
& $Logger "Warning: boot.wim driver injection failed: $_"
|
||||
try { Dismount-WindowsImage -Path $mountDir -Discard } catch {}
|
||||
try { Dismount-WindowsImage -Path $mountDir -Discard } catch { & $Logger "Warning: could not discard boot.wim mount: $_" }
|
||||
} finally {
|
||||
Remove-Item -Path $mountDir -Recurse -Force
|
||||
}
|
||||
@@ -330,44 +326,44 @@ Retail
|
||||
reg load HKLM\zSYSTEM "$ScratchDir\Windows\System32\config\SYSTEM"
|
||||
|
||||
& $Log "Bypassing system requirements..."
|
||||
Set-ISOScriptReg 'HKLM\zDEFAULT\Control Panel\UnsupportedHardwareNotificationCache' 'SV1' 'REG_DWORD' '0'
|
||||
Set-ISOScriptReg 'HKLM\zDEFAULT\Control Panel\UnsupportedHardwareNotificationCache' 'SV2' 'REG_DWORD' '0'
|
||||
Set-ISOScriptReg 'HKLM\zNTUSER\Control Panel\UnsupportedHardwareNotificationCache' 'SV1' 'REG_DWORD' '0'
|
||||
Set-ISOScriptReg 'HKLM\zNTUSER\Control Panel\UnsupportedHardwareNotificationCache' 'SV2' 'REG_DWORD' '0'
|
||||
Set-ISOScriptReg 'HKLM\zSYSTEM\Setup\LabConfig' 'BypassCPUCheck' 'REG_DWORD' '1'
|
||||
Set-ISOScriptReg 'HKLM\zSYSTEM\Setup\LabConfig' 'BypassRAMCheck' 'REG_DWORD' '1'
|
||||
Set-ISOScriptReg 'HKLM\zSYSTEM\Setup\LabConfig' 'BypassSecureBootCheck' 'REG_DWORD' '1'
|
||||
Set-ISOScriptReg 'HKLM\zSYSTEM\Setup\LabConfig' 'BypassStorageCheck' 'REG_DWORD' '1'
|
||||
Set-ISOScriptReg 'HKLM\zSYSTEM\Setup\LabConfig' 'BypassTPMCheck' 'REG_DWORD' '1'
|
||||
Set-ISOScriptReg 'HKLM\zSYSTEM\Setup\MoSetup' 'AllowUpgradesWithUnsupportedTPMOrCPU' 'REG_DWORD' '1'
|
||||
Set-ISOScriptReg -Path 'HKLM\zDEFAULT\Control Panel\UnsupportedHardwareNotificationCache' -Name 'SV1' -Type 'REG_DWORD' -Value '0'
|
||||
Set-ISOScriptReg -Path 'HKLM\zDEFAULT\Control Panel\UnsupportedHardwareNotificationCache' -Name 'SV2' -Type 'REG_DWORD' -Value '0'
|
||||
Set-ISOScriptReg -Path 'HKLM\zNTUSER\Control Panel\UnsupportedHardwareNotificationCache' -Name 'SV1' -Type 'REG_DWORD' -Value '0'
|
||||
Set-ISOScriptReg -Path 'HKLM\zNTUSER\Control Panel\UnsupportedHardwareNotificationCache' -Name 'SV2' -Type 'REG_DWORD' -Value '0'
|
||||
Set-ISOScriptReg -Path 'HKLM\zSYSTEM\Setup\LabConfig' -Name 'BypassCPUCheck' -Type 'REG_DWORD' -Value '1'
|
||||
Set-ISOScriptReg -Path 'HKLM\zSYSTEM\Setup\LabConfig' -Name 'BypassRAMCheck' -Type 'REG_DWORD' -Value '1'
|
||||
Set-ISOScriptReg -Path 'HKLM\zSYSTEM\Setup\LabConfig' -Name 'BypassSecureBootCheck' -Type 'REG_DWORD' -Value '1'
|
||||
Set-ISOScriptReg -Path 'HKLM\zSYSTEM\Setup\LabConfig' -Name 'BypassStorageCheck' -Type 'REG_DWORD' -Value '1'
|
||||
Set-ISOScriptReg -Path 'HKLM\zSYSTEM\Setup\LabConfig' -Name 'BypassTPMCheck' -Type 'REG_DWORD' -Value '1'
|
||||
Set-ISOScriptReg -Path 'HKLM\zSYSTEM\Setup\MoSetup' -Name 'AllowUpgradesWithUnsupportedTPMOrCPU' -Type 'REG_DWORD' -Value '1'
|
||||
|
||||
& $Log "Disabling sponsored apps..."
|
||||
Set-ISOScriptReg 'HKLM\zNTUSER\SOFTWARE\Microsoft\Windows\CurrentVersion\ContentDeliveryManager' 'OemPreInstalledAppsEnabled' 'REG_DWORD' '0'
|
||||
Set-ISOScriptReg 'HKLM\zNTUSER\SOFTWARE\Microsoft\Windows\CurrentVersion\ContentDeliveryManager' 'PreInstalledAppsEnabled' 'REG_DWORD' '0'
|
||||
Set-ISOScriptReg 'HKLM\zNTUSER\SOFTWARE\Microsoft\Windows\CurrentVersion\ContentDeliveryManager' 'SilentInstalledAppsEnabled' 'REG_DWORD' '0'
|
||||
Set-ISOScriptReg 'HKLM\zSOFTWARE\Policies\Microsoft\Windows\CloudContent' 'DisableWindowsConsumerFeatures' 'REG_DWORD' '1'
|
||||
Set-ISOScriptReg 'HKLM\zNTUSER\Software\Microsoft\Windows\CurrentVersion\ContentDeliveryManager' 'ContentDeliveryAllowed' 'REG_DWORD' '0'
|
||||
Set-ISOScriptReg 'HKLM\zSOFTWARE\Microsoft\PolicyManager\current\device\Start' 'ConfigureStartPins' 'REG_SZ' '{"pinnedList": [{}]}'
|
||||
Set-ISOScriptReg 'HKLM\zNTUSER\Software\Microsoft\Windows\CurrentVersion\ContentDeliveryManager' 'FeatureManagementEnabled' 'REG_DWORD' '0'
|
||||
Set-ISOScriptReg 'HKLM\zNTUSER\Software\Microsoft\Windows\CurrentVersion\ContentDeliveryManager' 'PreInstalledAppsEverEnabled' 'REG_DWORD' '0'
|
||||
Set-ISOScriptReg 'HKLM\zNTUSER\Software\Microsoft\Windows\CurrentVersion\ContentDeliveryManager' 'SoftLandingEnabled' 'REG_DWORD' '0'
|
||||
Set-ISOScriptReg 'HKLM\zNTUSER\Software\Microsoft\Windows\CurrentVersion\ContentDeliveryManager' 'SubscribedContentEnabled' 'REG_DWORD' '0'
|
||||
Set-ISOScriptReg 'HKLM\zNTUSER\Software\Microsoft\Windows\CurrentVersion\ContentDeliveryManager' 'SubscribedContent-310093Enabled' 'REG_DWORD' '0'
|
||||
Set-ISOScriptReg 'HKLM\zNTUSER\Software\Microsoft\Windows\CurrentVersion\ContentDeliveryManager' 'SubscribedContent-338388Enabled' 'REG_DWORD' '0'
|
||||
Set-ISOScriptReg 'HKLM\zNTUSER\Software\Microsoft\Windows\CurrentVersion\ContentDeliveryManager' 'SubscribedContent-338389Enabled' 'REG_DWORD' '0'
|
||||
Set-ISOScriptReg 'HKLM\zNTUSER\Software\Microsoft\Windows\CurrentVersion\ContentDeliveryManager' 'SubscribedContent-338393Enabled' 'REG_DWORD' '0'
|
||||
Set-ISOScriptReg 'HKLM\zNTUSER\Software\Microsoft\Windows\CurrentVersion\ContentDeliveryManager' 'SubscribedContent-353694Enabled' 'REG_DWORD' '0'
|
||||
Set-ISOScriptReg 'HKLM\zNTUSER\Software\Microsoft\Windows\CurrentVersion\ContentDeliveryManager' 'SubscribedContent-353696Enabled' 'REG_DWORD' '0'
|
||||
Set-ISOScriptReg 'HKLM\zNTUSER\Software\Microsoft\Windows\CurrentVersion\ContentDeliveryManager' 'SystemPaneSuggestionsEnabled' 'REG_DWORD' '0'
|
||||
Set-ISOScriptReg 'HKLM\zSOFTWARE\Policies\Microsoft\PushToInstall' 'DisablePushToInstall' 'REG_DWORD' '1'
|
||||
Set-ISOScriptReg 'HKLM\zSOFTWARE\Policies\Microsoft\MRT' 'DontOfferThroughWUAU' 'REG_DWORD' '1'
|
||||
Set-ISOScriptReg -Path 'HKLM\zNTUSER\SOFTWARE\Microsoft\Windows\CurrentVersion\ContentDeliveryManager' -Name 'OemPreInstalledAppsEnabled' -Type 'REG_DWORD' -Value '0'
|
||||
Set-ISOScriptReg -Path 'HKLM\zNTUSER\SOFTWARE\Microsoft\Windows\CurrentVersion\ContentDeliveryManager' -Name 'PreInstalledAppsEnabled' -Type 'REG_DWORD' -Value '0'
|
||||
Set-ISOScriptReg -Path 'HKLM\zNTUSER\SOFTWARE\Microsoft\Windows\CurrentVersion\ContentDeliveryManager' -Name 'SilentInstalledAppsEnabled' -Type 'REG_DWORD' -Value '0'
|
||||
Set-ISOScriptReg -Path 'HKLM\zSOFTWARE\Policies\Microsoft\Windows\CloudContent' -Name 'DisableWindowsConsumerFeatures' -Type 'REG_DWORD' -Value '1'
|
||||
Set-ISOScriptReg -Path 'HKLM\zNTUSER\Software\Microsoft\Windows\CurrentVersion\ContentDeliveryManager' -Name 'ContentDeliveryAllowed' -Type 'REG_DWORD' -Value '0'
|
||||
Set-ISOScriptReg -Path 'HKLM\zSOFTWARE\Microsoft\PolicyManager\current\device\Start' -Name 'ConfigureStartPins' -Type 'REG_SZ' -Value '{"pinnedList": [{}]}'
|
||||
Set-ISOScriptReg -Path 'HKLM\zNTUSER\Software\Microsoft\Windows\CurrentVersion\ContentDeliveryManager' -Name 'FeatureManagementEnabled' -Type 'REG_DWORD' -Value '0'
|
||||
Set-ISOScriptReg -Path 'HKLM\zNTUSER\Software\Microsoft\Windows\CurrentVersion\ContentDeliveryManager' -Name 'PreInstalledAppsEverEnabled' -Type 'REG_DWORD' -Value '0'
|
||||
Set-ISOScriptReg -Path 'HKLM\zNTUSER\Software\Microsoft\Windows\CurrentVersion\ContentDeliveryManager' -Name 'SoftLandingEnabled' -Type 'REG_DWORD' -Value '0'
|
||||
Set-ISOScriptReg -Path 'HKLM\zNTUSER\Software\Microsoft\Windows\CurrentVersion\ContentDeliveryManager' -Name 'SubscribedContentEnabled' -Type 'REG_DWORD' -Value '0'
|
||||
Set-ISOScriptReg -Path 'HKLM\zNTUSER\Software\Microsoft\Windows\CurrentVersion\ContentDeliveryManager' -Name 'SubscribedContent-310093Enabled' -Type 'REG_DWORD' -Value '0'
|
||||
Set-ISOScriptReg -Path 'HKLM\zNTUSER\Software\Microsoft\Windows\CurrentVersion\ContentDeliveryManager' -Name 'SubscribedContent-338388Enabled' -Type 'REG_DWORD' -Value '0'
|
||||
Set-ISOScriptReg -Path 'HKLM\zNTUSER\Software\Microsoft\Windows\CurrentVersion\ContentDeliveryManager' -Name 'SubscribedContent-338389Enabled' -Type 'REG_DWORD' -Value '0'
|
||||
Set-ISOScriptReg -Path 'HKLM\zNTUSER\Software\Microsoft\Windows\CurrentVersion\ContentDeliveryManager' -Name 'SubscribedContent-338393Enabled' -Type 'REG_DWORD' -Value '0'
|
||||
Set-ISOScriptReg -Path 'HKLM\zNTUSER\Software\Microsoft\Windows\CurrentVersion\ContentDeliveryManager' -Name 'SubscribedContent-353694Enabled' -Type 'REG_DWORD' -Value '0'
|
||||
Set-ISOScriptReg -Path 'HKLM\zNTUSER\Software\Microsoft\Windows\CurrentVersion\ContentDeliveryManager' -Name 'SubscribedContent-353696Enabled' -Type 'REG_DWORD' -Value '0'
|
||||
Set-ISOScriptReg -Path 'HKLM\zNTUSER\Software\Microsoft\Windows\CurrentVersion\ContentDeliveryManager' -Name 'SystemPaneSuggestionsEnabled' -Type 'REG_DWORD' -Value '0'
|
||||
Set-ISOScriptReg -Path 'HKLM\zSOFTWARE\Policies\Microsoft\PushToInstall' -Name 'DisablePushToInstall' -Type 'REG_DWORD' -Value '1'
|
||||
Set-ISOScriptReg -Path 'HKLM\zSOFTWARE\Policies\Microsoft\MRT' -Name 'DontOfferThroughWUAU' -Type 'REG_DWORD' -Value '1'
|
||||
Remove-ISOScriptReg 'HKLM\zNTUSER\Software\Microsoft\Windows\CurrentVersion\ContentDeliveryManager\Subscriptions'
|
||||
Remove-ISOScriptReg 'HKLM\zNTUSER\Software\Microsoft\Windows\CurrentVersion\ContentDeliveryManager\SuggestedApps'
|
||||
Set-ISOScriptReg 'HKLM\zSOFTWARE\Policies\Microsoft\Windows\CloudContent' 'DisableConsumerAccountStateContent' 'REG_DWORD' '1'
|
||||
Set-ISOScriptReg 'HKLM\zSOFTWARE\Policies\Microsoft\Windows\CloudContent' 'DisableCloudOptimizedContent' 'REG_DWORD' '1'
|
||||
Set-ISOScriptReg -Path 'HKLM\zSOFTWARE\Policies\Microsoft\Windows\CloudContent' -Name 'DisableConsumerAccountStateContent' -Type 'REG_DWORD' -Value '1'
|
||||
Set-ISOScriptReg -Path 'HKLM\zSOFTWARE\Policies\Microsoft\Windows\CloudContent' -Name 'DisableCloudOptimizedContent' -Type 'REG_DWORD' -Value '1'
|
||||
|
||||
& $Log "Enabling local accounts on OOBE..."
|
||||
Set-ISOScriptReg 'HKLM\zSOFTWARE\Microsoft\Windows\CurrentVersion\OOBE' 'BypassNRO' 'REG_DWORD' '1'
|
||||
Set-ISOScriptReg -Path 'HKLM\zSOFTWARE\Microsoft\Windows\CurrentVersion\OOBE' -Name 'BypassNRO' -Type 'REG_DWORD' -Value '1'
|
||||
|
||||
if ($AutoUnattendXml) {
|
||||
$preparedAutoUnattendXml = $AutoUnattendXml
|
||||
@@ -423,62 +419,62 @@ Retail
|
||||
}
|
||||
|
||||
& $Log "Disabling reserved storage..."
|
||||
Set-ISOScriptReg 'HKLM\zSOFTWARE\Microsoft\Windows\CurrentVersion\ReserveManager' 'ShippedWithReserves' 'REG_DWORD' '0'
|
||||
Set-ISOScriptReg -Path 'HKLM\zSOFTWARE\Microsoft\Windows\CurrentVersion\ReserveManager' -Name 'ShippedWithReserves' -Type 'REG_DWORD' -Value '0'
|
||||
|
||||
& $Log "Disabling BitLocker device encryption..."
|
||||
Set-ISOScriptReg 'HKLM\zSYSTEM\ControlSet001\Control\BitLocker' 'PreventDeviceEncryption' 'REG_DWORD' '1'
|
||||
Set-ISOScriptReg -Path 'HKLM\zSYSTEM\ControlSet001\Control\BitLocker' -Name 'PreventDeviceEncryption' -Type 'REG_DWORD' -Value '1'
|
||||
|
||||
& $Log "Disabling Chat icon..."
|
||||
Set-ISOScriptReg 'HKLM\zSOFTWARE\Policies\Microsoft\Windows\Windows Chat' 'ChatIcon' 'REG_DWORD' '3'
|
||||
Set-ISOScriptReg 'HKLM\zNTUSER\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\Advanced' 'TaskbarMn' 'REG_DWORD' '0'
|
||||
Set-ISOScriptReg -Path 'HKLM\zSOFTWARE\Policies\Microsoft\Windows\Windows Chat' -Name 'ChatIcon' -Type 'REG_DWORD' -Value '3'
|
||||
Set-ISOScriptReg -Path 'HKLM\zNTUSER\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\Advanced' -Name 'TaskbarMn' -Type 'REG_DWORD' -Value '0'
|
||||
|
||||
& $Log "Disabling OneDrive folder backup..."
|
||||
Set-ISOScriptReg 'HKLM\zSOFTWARE\Policies\Microsoft\Windows\OneDrive' 'DisableFileSyncNGSC' 'REG_DWORD' '1'
|
||||
Set-ISOScriptReg -Path 'HKLM\zSOFTWARE\Policies\Microsoft\Windows\OneDrive' -Name 'DisableFileSyncNGSC' -Type 'REG_DWORD' -Value '1'
|
||||
|
||||
& $Log "Disabling telemetry..."
|
||||
Set-ISOScriptReg 'HKLM\zNTUSER\Software\Microsoft\Windows\CurrentVersion\AdvertisingInfo' 'Enabled' 'REG_DWORD' '0'
|
||||
Set-ISOScriptReg 'HKLM\zNTUSER\Software\Microsoft\Windows\CurrentVersion\Privacy' 'TailoredExperiencesWithDiagnosticDataEnabled' 'REG_DWORD' '0'
|
||||
Set-ISOScriptReg 'HKLM\zNTUSER\Software\Microsoft\Speech_OneCore\Settings\OnlineSpeechPrivacy' 'HasAccepted' 'REG_DWORD' '0'
|
||||
Set-ISOScriptReg 'HKLM\zNTUSER\Software\Microsoft\Input\TIPC' 'Enabled' 'REG_DWORD' '0'
|
||||
Set-ISOScriptReg 'HKLM\zNTUSER\Software\Microsoft\InputPersonalization' 'RestrictImplicitInkCollection' 'REG_DWORD' '1'
|
||||
Set-ISOScriptReg 'HKLM\zNTUSER\Software\Microsoft\InputPersonalization' 'RestrictImplicitTextCollection' 'REG_DWORD' '1'
|
||||
Set-ISOScriptReg 'HKLM\zNTUSER\Software\Microsoft\InputPersonalization\TrainedDataStore' 'HarvestContacts' 'REG_DWORD' '0'
|
||||
Set-ISOScriptReg 'HKLM\zNTUSER\Software\Microsoft\Personalization\Settings' 'AcceptedPrivacyPolicy' 'REG_DWORD' '0'
|
||||
Set-ISOScriptReg 'HKLM\zSOFTWARE\Policies\Microsoft\Windows\DataCollection' 'AllowTelemetry' 'REG_DWORD' '0'
|
||||
Set-ISOScriptReg 'HKLM\zSYSTEM\ControlSet001\Services\dmwappushservice' 'Start' 'REG_DWORD' '4'
|
||||
Set-ISOScriptReg -Path 'HKLM\zNTUSER\Software\Microsoft\Windows\CurrentVersion\AdvertisingInfo' -Name 'Enabled' -Type 'REG_DWORD' -Value '0'
|
||||
Set-ISOScriptReg -Path 'HKLM\zNTUSER\Software\Microsoft\Windows\CurrentVersion\Privacy' -Name 'TailoredExperiencesWithDiagnosticDataEnabled' -Type 'REG_DWORD' -Value '0'
|
||||
Set-ISOScriptReg -Path 'HKLM\zNTUSER\Software\Microsoft\Speech_OneCore\Settings\OnlineSpeechPrivacy' -Name 'HasAccepted' -Type 'REG_DWORD' -Value '0'
|
||||
Set-ISOScriptReg -Path 'HKLM\zNTUSER\Software\Microsoft\Input\TIPC' -Name 'Enabled' -Type 'REG_DWORD' -Value '0'
|
||||
Set-ISOScriptReg -Path 'HKLM\zNTUSER\Software\Microsoft\InputPersonalization' -Name 'RestrictImplicitInkCollection' -Type 'REG_DWORD' -Value '1'
|
||||
Set-ISOScriptReg -Path 'HKLM\zNTUSER\Software\Microsoft\InputPersonalization' -Name 'RestrictImplicitTextCollection' -Type 'REG_DWORD' -Value '1'
|
||||
Set-ISOScriptReg -Path 'HKLM\zNTUSER\Software\Microsoft\InputPersonalization\TrainedDataStore' -Name 'HarvestContacts' -Type 'REG_DWORD' -Value '0'
|
||||
Set-ISOScriptReg -Path 'HKLM\zNTUSER\Software\Microsoft\Personalization\Settings' -Name 'AcceptedPrivacyPolicy' -Type 'REG_DWORD' -Value '0'
|
||||
Set-ISOScriptReg -Path 'HKLM\zSOFTWARE\Policies\Microsoft\Windows\DataCollection' -Name 'AllowTelemetry' -Type 'REG_DWORD' -Value '0'
|
||||
Set-ISOScriptReg -Path 'HKLM\zSYSTEM\ControlSet001\Services\dmwappushservice' -Name 'Start' -Type 'REG_DWORD' -Value '4'
|
||||
|
||||
& $Log "Preventing installation of DevHome and Outlook..."
|
||||
Set-ISOScriptReg 'HKLM\zSOFTWARE\Microsoft\Windows\CurrentVersion\WindowsUpdate\Orchestrator\UScheduler_Oobe\OutlookUpdate' 'workCompleted' 'REG_DWORD' '1'
|
||||
Set-ISOScriptReg 'HKLM\zSOFTWARE\Microsoft\Windows\CurrentVersion\WindowsUpdate\Orchestrator\UScheduler\OutlookUpdate' 'workCompleted' 'REG_DWORD' '1'
|
||||
Set-ISOScriptReg 'HKLM\zSOFTWARE\Microsoft\Windows\CurrentVersion\WindowsUpdate\Orchestrator\UScheduler\DevHomeUpdate' 'workCompleted' 'REG_DWORD' '1'
|
||||
Set-ISOScriptReg -Path 'HKLM\zSOFTWARE\Microsoft\Windows\CurrentVersion\WindowsUpdate\Orchestrator\UScheduler_Oobe\OutlookUpdate' -Name 'workCompleted' -Type 'REG_DWORD' -Value '1'
|
||||
Set-ISOScriptReg -Path 'HKLM\zSOFTWARE\Microsoft\Windows\CurrentVersion\WindowsUpdate\Orchestrator\UScheduler\OutlookUpdate' -Name 'workCompleted' -Type 'REG_DWORD' -Value '1'
|
||||
Set-ISOScriptReg -Path 'HKLM\zSOFTWARE\Microsoft\Windows\CurrentVersion\WindowsUpdate\Orchestrator\UScheduler\DevHomeUpdate' -Name 'workCompleted' -Type 'REG_DWORD' -Value '1'
|
||||
Remove-ISOScriptReg 'HKLM\zSOFTWARE\Microsoft\WindowsUpdate\Orchestrator\UScheduler_Oobe\OutlookUpdate'
|
||||
Remove-ISOScriptReg 'HKLM\zSOFTWARE\Microsoft\WindowsUpdate\Orchestrator\UScheduler_Oobe\DevHomeUpdate'
|
||||
|
||||
& $Log "Disabling Copilot..."
|
||||
Set-ISOScriptReg 'HKLM\zSOFTWARE\Policies\Microsoft\Windows\WindowsCopilot' 'TurnOffWindowsCopilot' 'REG_DWORD' '1'
|
||||
Set-ISOScriptReg 'HKLM\zSOFTWARE\Policies\Microsoft\Edge' 'HubsSidebarEnabled' 'REG_DWORD' '0'
|
||||
Set-ISOScriptReg 'HKLM\zSOFTWARE\Policies\Microsoft\Windows\Explorer' 'DisableSearchBoxSuggestions' 'REG_DWORD' '1'
|
||||
Set-ISOScriptReg -Path 'HKLM\zSOFTWARE\Policies\Microsoft\Windows\WindowsCopilot' -Name 'TurnOffWindowsCopilot' -Type 'REG_DWORD' -Value '1'
|
||||
Set-ISOScriptReg -Path 'HKLM\zSOFTWARE\Policies\Microsoft\Edge' -Name 'HubsSidebarEnabled' -Type 'REG_DWORD' -Value '0'
|
||||
Set-ISOScriptReg -Path 'HKLM\zSOFTWARE\Policies\Microsoft\Windows\Explorer' -Name 'DisableSearchBoxSuggestions' -Type 'REG_DWORD' -Value '1'
|
||||
|
||||
& $Log "Disabling Windows Update during OOBE (re-enabled on first logon via FirstLogon.ps1)..."
|
||||
Set-ISOScriptReg 'HKLM\zSOFTWARE\Policies\Microsoft\Windows\WindowsUpdate\AU' 'NoAutoUpdate' 'REG_DWORD' '1'
|
||||
Set-ISOScriptReg 'HKLM\zSOFTWARE\Policies\Microsoft\Windows\WindowsUpdate\AU' 'AUOptions' 'REG_DWORD' '1'
|
||||
Set-ISOScriptReg 'HKLM\zSOFTWARE\Policies\Microsoft\Windows\WindowsUpdate\AU' 'UseWUServer' 'REG_DWORD' '1'
|
||||
Set-ISOScriptReg 'HKLM\zSOFTWARE\Policies\Microsoft\Windows\WindowsUpdate' 'DisableWindowsUpdateAccess' 'REG_DWORD' '1'
|
||||
Set-ISOScriptReg 'HKLM\zSOFTWARE\Policies\Microsoft\Windows\WindowsUpdate' 'WUServer' 'REG_SZ' 'http://localhost:8080'
|
||||
Set-ISOScriptReg 'HKLM\zSOFTWARE\Policies\Microsoft\Windows\WindowsUpdate' 'WUStatusServer' 'REG_SZ' 'http://localhost:8080'
|
||||
Set-ISOScriptReg 'HKLM\zSOFTWARE\Microsoft\Windows\CurrentVersion\WindowsUpdate\Orchestrator\UScheduler_Oobe\WindowsUpdate' 'workCompleted' 'REG_DWORD' '1'
|
||||
Set-ISOScriptReg -Path 'HKLM\zSOFTWARE\Policies\Microsoft\Windows\WindowsUpdate\AU' -Name 'NoAutoUpdate' -Type 'REG_DWORD' -Value '1'
|
||||
Set-ISOScriptReg -Path 'HKLM\zSOFTWARE\Policies\Microsoft\Windows\WindowsUpdate\AU' -Name 'AUOptions' -Type 'REG_DWORD' -Value '1'
|
||||
Set-ISOScriptReg -Path 'HKLM\zSOFTWARE\Policies\Microsoft\Windows\WindowsUpdate\AU' -Name 'UseWUServer' -Type 'REG_DWORD' -Value '1'
|
||||
Set-ISOScriptReg -Path 'HKLM\zSOFTWARE\Policies\Microsoft\Windows\WindowsUpdate' -Name 'DisableWindowsUpdateAccess' -Type 'REG_DWORD' -Value '1'
|
||||
Set-ISOScriptReg -Path 'HKLM\zSOFTWARE\Policies\Microsoft\Windows\WindowsUpdate' -Name 'WUServer' -Type 'REG_SZ' -Value 'http://localhost:8080'
|
||||
Set-ISOScriptReg -Path 'HKLM\zSOFTWARE\Policies\Microsoft\Windows\WindowsUpdate' -Name 'WUStatusServer' -Type 'REG_SZ' -Value 'http://localhost:8080'
|
||||
Set-ISOScriptReg -Path 'HKLM\zSOFTWARE\Microsoft\Windows\CurrentVersion\WindowsUpdate\Orchestrator\UScheduler_Oobe\WindowsUpdate' -Name 'workCompleted' -Type 'REG_DWORD' -Value '1'
|
||||
Remove-ISOScriptReg 'HKLM\zSOFTWARE\Microsoft\WindowsUpdate\Orchestrator\UScheduler_Oobe\WindowsUpdate'
|
||||
Set-ISOScriptReg 'HKLM\zSOFTWARE\Microsoft\Windows\CurrentVersion\DeliveryOptimization\Config' 'DODownloadMode' 'REG_DWORD' '0'
|
||||
Set-ISOScriptReg 'HKLM\zSYSTEM\ControlSet001\Services\BITS' 'Start' 'REG_DWORD' '4'
|
||||
Set-ISOScriptReg 'HKLM\zSYSTEM\ControlSet001\Services\wuauserv' 'Start' 'REG_DWORD' '4'
|
||||
Set-ISOScriptReg 'HKLM\zSYSTEM\ControlSet001\Services\UsoSvc' 'Start' 'REG_DWORD' '4'
|
||||
Set-ISOScriptReg 'HKLM\zSYSTEM\ControlSet001\Services\WaaSMedicSvc' 'Start' 'REG_DWORD' '4'
|
||||
Set-ISOScriptReg -Path 'HKLM\zSOFTWARE\Microsoft\Windows\CurrentVersion\DeliveryOptimization\Config' -Name 'DODownloadMode' -Type 'REG_DWORD' -Value '0'
|
||||
Set-ISOScriptReg -Path 'HKLM\zSYSTEM\ControlSet001\Services\BITS' -Name 'Start' -Type 'REG_DWORD' -Value '4'
|
||||
Set-ISOScriptReg -Path 'HKLM\zSYSTEM\ControlSet001\Services\wuauserv' -Name 'Start' -Type 'REG_DWORD' -Value '4'
|
||||
Set-ISOScriptReg -Path 'HKLM\zSYSTEM\ControlSet001\Services\UsoSvc' -Name 'Start' -Type 'REG_DWORD' -Value '4'
|
||||
Set-ISOScriptReg -Path 'HKLM\zSYSTEM\ControlSet001\Services\WaaSMedicSvc' -Name 'Start' -Type 'REG_DWORD' -Value '4'
|
||||
|
||||
& $Log "Preventing installation of Teams..."
|
||||
Set-ISOScriptReg 'HKLM\zSOFTWARE\Policies\Microsoft\Teams' 'DisableInstallation' 'REG_DWORD' '1'
|
||||
Set-ISOScriptReg -Path 'HKLM\zSOFTWARE\Policies\Microsoft\Teams' -Name 'DisableInstallation' -Type 'REG_DWORD' -Value '1'
|
||||
|
||||
& $Log "Preventing installation of new Outlook..."
|
||||
Set-ISOScriptReg 'HKLM\zSOFTWARE\Policies\Microsoft\Windows\Windows Mail' 'PreventRun' 'REG_DWORD' '1'
|
||||
Set-ISOScriptReg -Path 'HKLM\zSOFTWARE\Policies\Microsoft\Windows\Windows Mail' -Name 'PreventRun' -Type 'REG_DWORD' -Value '1'
|
||||
|
||||
& $Log "Unloading offline registry hives..."
|
||||
reg unload HKLM\zCOMPONENTS
|
||||
|
||||
@@ -180,7 +180,7 @@ function Invoke-WinUtilISOWriteUSB {
|
||||
Start-Sleep -Seconds 2
|
||||
Update-Disk -Number $diskNum
|
||||
|
||||
try { Remove-PartitionAccessPath -DiskNumber $diskNum -PartitionNumber $winpePart.PartitionNumber -AccessPath "$($winpePart.DriveLetter):" } catch {}
|
||||
try { Remove-PartitionAccessPath -DiskNumber $diskNum -PartitionNumber $winpePart.PartitionNumber -AccessPath "$($winpePart.DriveLetter):" } catch { Log "Warning: could not remove existing partition access path: $_" }
|
||||
$usbLetter = Get-FreeDriveLetter
|
||||
if (-not $usbLetter) { throw "No free drive letters (D-Z) available to assign to the USB data partition." }
|
||||
Set-Partition -DiskNumber $diskNum -PartitionNumber $winpePart.PartitionNumber -NewDriveLetter $usbLetter
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
Function Invoke-WinUtilSponsors {
|
||||
$sponsors = ([regex]::Matches(([regex]::Match((irm https://github.com/sponsors/ChrisTitusTech),'(?s)(?<=Current sponsors).*?(?=Past sponsors)')).Value,'(?<=alt="@)[^"]+')).Value | Where-Object {$_ -ne "ChrisTitusTech"}
|
||||
$sponsors = ([regex]::Matches(([regex]::Match((Invoke-RestMethod https://github.com/sponsors/ChrisTitusTech),'(?s)(?<=Current sponsors).*?(?=Past sponsors)')).Value,'(?<=alt="@)[^"]+')).Value | Where-Object {$_ -ne "ChrisTitusTech"}
|
||||
return $sponsors
|
||||
}
|
||||
|
||||
@@ -91,34 +91,34 @@ function Invoke-WinutilThemeChange {
|
||||
|
||||
# Retrieve all theme properties from the theme configuration
|
||||
$themeProperties = $sync.configs.themes.$currentTheme.PSObject.Properties
|
||||
foreach ($_ in $themeProperties) {
|
||||
foreach ($themeProperty in $themeProperties) {
|
||||
# Apply properties that deal with colors
|
||||
if ($_.Name -like "*color*") {
|
||||
Set-ThemeResourceProperty -Name $_.Name -Value $_.Value -Type "ColorBrush"
|
||||
if ($themeProperty.Name -like "*color*") {
|
||||
Set-ThemeResourceProperty -Name $themeProperty.Name -Value $themeProperty.Value -Type "ColorBrush"
|
||||
# For certain color properties, also set complementary values (e.g., BorderColor -> CBorderColor) This is required because e.g DropShadowEffect requires a <Color> and not a <SolidColorBrush> object
|
||||
if ($_.Name -in @("BorderColor", "ButtonBackgroundMouseoverColor")) {
|
||||
Set-ThemeResourceProperty -Name "C$($_.Name)" -Value $_.Value -Type "Color"
|
||||
if ($themeProperty.Name -in @("BorderColor", "ButtonBackgroundMouseoverColor")) {
|
||||
Set-ThemeResourceProperty -Name "C$($themeProperty.Name)" -Value $themeProperty.Value -Type "Color"
|
||||
}
|
||||
}
|
||||
# Apply corner radius properties
|
||||
elseif ($_.Name -like "*Radius*") {
|
||||
Set-ThemeResourceProperty -Name $_.Name -Value $_.Value -Type "CornerRadius"
|
||||
elseif ($themeProperty.Name -like "*Radius*") {
|
||||
Set-ThemeResourceProperty -Name $themeProperty.Name -Value $themeProperty.Value -Type "CornerRadius"
|
||||
}
|
||||
# Apply row height properties
|
||||
elseif ($_.Name -like "*RowHeight*") {
|
||||
Set-ThemeResourceProperty -Name $_.Name -Value $_.Value -Type "GridLength"
|
||||
elseif ($themeProperty.Name -like "*RowHeight*") {
|
||||
Set-ThemeResourceProperty -Name $themeProperty.Name -Value $themeProperty.Value -Type "GridLength"
|
||||
}
|
||||
# Apply thickness or margin properties
|
||||
elseif (($_.Name -like "*Thickness*") -or ($_.Name -like "*margin")) {
|
||||
Set-ThemeResourceProperty -Name $_.Name -Value $_.Value -Type "Thickness"
|
||||
elseif (($themeProperty.Name -like "*Thickness*") -or ($themeProperty.Name -like "*margin")) {
|
||||
Set-ThemeResourceProperty -Name $themeProperty.Name -Value $themeProperty.Value -Type "Thickness"
|
||||
}
|
||||
# Apply font family properties
|
||||
elseif ($_.Name -like "*FontFamily*") {
|
||||
Set-ThemeResourceProperty -Name $_.Name -Value $_.Value -Type "FontFamily"
|
||||
elseif ($themeProperty.Name -like "*FontFamily*") {
|
||||
Set-ThemeResourceProperty -Name $themeProperty.Name -Value $themeProperty.Value -Type "FontFamily"
|
||||
}
|
||||
# Apply any other properties as doubles (numerical values)
|
||||
else {
|
||||
Set-ThemeResourceProperty -Name $_.Name -Value $_.Value -Type "Double"
|
||||
Set-ThemeResourceProperty -Name $themeProperty.Name -Value $themeProperty.Value -Type "Double"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,7 +22,11 @@ function Reset-WPFCheckBoxes {
|
||||
)
|
||||
|
||||
$CheckBoxesToCheck = $sync.selectedApps + $sync.selectedTweaks + $sync.selectedFeatures + $sync.selectedAppx
|
||||
$CheckBoxes = ($sync.GetEnumerator()).where{ $_.Value -is [System.Windows.Controls.CheckBox] -and $_.Name -notlike "WPFToggle*" -and $_.Name -like "$checkboxfilterpattern"}
|
||||
$CheckBoxes = foreach ($syncEntry in $sync.GetEnumerator()) {
|
||||
if ($syncEntry.Value -is [System.Windows.Controls.CheckBox] -and $syncEntry.Name -notlike "WPFToggle*" -and $syncEntry.Name -like $checkboxfilterpattern) {
|
||||
$syncEntry
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($CheckBox in $CheckBoxes) {
|
||||
$checkboxName = $CheckBox.Key
|
||||
|
||||
@@ -14,11 +14,13 @@ function Set-WinUtilProgressbar{
|
||||
[int]$Percent
|
||||
)
|
||||
|
||||
Invoke-WPFUIThread -ScriptBlock {$sync.progressBarTextBlock.Text = $label}
|
||||
Invoke-WPFUIThread -ScriptBlock {$sync.progressBarTextBlock.ToolTip = $label}
|
||||
if ($percent -lt 5 ) {
|
||||
$percent = 5 # Ensure the progress bar is not empty, as it looks weird
|
||||
$progressLabel = $Label
|
||||
|
||||
Invoke-WPFUIThread -ScriptBlock {$sync.progressBarTextBlock.Text = $progressLabel}
|
||||
Invoke-WPFUIThread -ScriptBlock {$sync.progressBarTextBlock.ToolTip = $progressLabel}
|
||||
if ($Percent -lt 5 ) {
|
||||
$Percent = 5 # Ensure the progress bar is not empty, as it looks weird
|
||||
}
|
||||
Invoke-WPFUIThread -ScriptBlock { $sync.ProgressBar.Value = $percent}
|
||||
Invoke-WPFUIThread -ScriptBlock { $sync.ProgressBar.Value = $Percent}
|
||||
|
||||
}
|
||||
|
||||
@@ -193,6 +193,7 @@ function Show-CustomDialog {
|
||||
# Define the Regex to find hyperlinks formatted as HTML <a> tags
|
||||
$regex = [regex]::new('<a href="([^"]+)">([^<]+)</a>')
|
||||
$lastPos = 0
|
||||
$linkHoverBrush = $LinkHoverForegroundColor
|
||||
|
||||
# Iterate through each match and add regular text and hyperlinks
|
||||
foreach ($match in $regex.Matches($Message)) {
|
||||
@@ -210,20 +211,23 @@ function Show-CustomDialog {
|
||||
$hyperlink.Foreground = $LinkForegroundColor
|
||||
|
||||
$hyperlink.Add_Click({
|
||||
param($sender, $args)
|
||||
Start-Process $sender.NavigateUri.AbsoluteUri
|
||||
param($eventSender, $routedEvent)
|
||||
$null = $routedEvent
|
||||
Start-Process $eventSender.NavigateUri.AbsoluteUri
|
||||
})
|
||||
$hyperlink.Add_MouseEnter({
|
||||
param($sender, $args)
|
||||
$sender.Foreground = $LinkHoverForegroundColor
|
||||
$sender.FontSize = ($FontSize + ($FontSize / 4))
|
||||
$sender.FontWeight = "SemiBold"
|
||||
param($eventSender, $routedEvent)
|
||||
$null = $routedEvent
|
||||
$eventSender.Foreground = $linkHoverBrush
|
||||
$eventSender.FontSize = ($FontSize + ($FontSize / 4))
|
||||
$eventSender.FontWeight = "SemiBold"
|
||||
})
|
||||
$hyperlink.Add_MouseLeave({
|
||||
param($sender, $args)
|
||||
$sender.Foreground = $LinkForegroundColor
|
||||
$sender.FontSize = $FontSize
|
||||
$sender.FontWeight = "Normal"
|
||||
param($eventSender, $routedEvent)
|
||||
$null = $routedEvent
|
||||
$eventSender.Foreground = $LinkForegroundColor
|
||||
$eventSender.FontSize = $FontSize
|
||||
$eventSender.FontWeight = "Normal"
|
||||
})
|
||||
|
||||
$messageTextBlock.Inlines.Add($hyperlink)
|
||||
|
||||
@@ -10,11 +10,13 @@ function Show-WPFInstallAppBusy {
|
||||
param (
|
||||
$text = "Installing apps..."
|
||||
)
|
||||
$overlayText = $text
|
||||
|
||||
Invoke-WPFUIThread -ScriptBlock {
|
||||
$sync.InstallAppAreaOverlay.Visibility = [Windows.Visibility]::Visible
|
||||
$sync.InstallAppAreaOverlay.Width = $($sync.InstallAppAreaScrollViewer.ActualWidth * 0.4)
|
||||
$sync.InstallAppAreaOverlay.Height = $($sync.InstallAppAreaScrollViewer.ActualWidth * 0.4)
|
||||
$sync.InstallAppAreaOverlayText.Text = $text
|
||||
$sync.InstallAppAreaOverlayText.Text = $overlayText
|
||||
$sync.InstallAppAreaBorder.IsEnabled = $false
|
||||
$sync.InstallAppAreaScrollViewer.Effect.Radius = 5
|
||||
}
|
||||
|
||||
@@ -15,7 +15,6 @@ function Invoke-WinUtilInstallAppRenderBatch {
|
||||
|
||||
function Complete-WinUtilInstallAppRendering {
|
||||
$sync.InstallAppEntriesRendered = $true
|
||||
Write-WinUtilPerformanceCheckpoint -Name "Install app entries rendered"
|
||||
}
|
||||
|
||||
function Invoke-WinUtilInstallAppRenderNextBatch {
|
||||
|
||||
@@ -7,7 +7,7 @@ function Invoke-WPFAppxRemoval {
|
||||
$selected = $sync.selectedAppx
|
||||
$apps = $sync.configs.appxHashtable
|
||||
|
||||
$handle = Invoke-WPFRunspace -ParameterList @(("selected", $selected), ("apps", $apps)) -ScriptBlock {
|
||||
Invoke-WPFRunspace -ParameterList @(("selected", $selected), ("apps", $apps)) -ScriptBlock {
|
||||
param($selected, $apps)
|
||||
|
||||
$sync.ProcessRunning = $true
|
||||
|
||||
@@ -35,7 +35,7 @@ function Invoke-WPFButton {
|
||||
if ($buttonConfig.InvokeScript -and $buttonConfig.InvokeScript.Count -gt 0) {
|
||||
foreach ($script in $buttonConfig.InvokeScript) {
|
||||
if (-not [string]::IsNullOrWhiteSpace($script)) {
|
||||
Invoke-Expression $script
|
||||
Invoke-Command -ScriptBlock ([scriptblock]::Create($script)) -ErrorAction Stop
|
||||
}
|
||||
}
|
||||
return
|
||||
|
||||
@@ -12,7 +12,7 @@ function Invoke-WPFFeatureInstall {
|
||||
return
|
||||
}
|
||||
|
||||
$handle = Invoke-WPFRunspace -ScriptBlock {
|
||||
Invoke-WPFRunspace -ScriptBlock {
|
||||
$Features = $sync.selectedFeatures
|
||||
$sync.ProcessRunning = $true
|
||||
if ($Features.count -eq 1) {
|
||||
@@ -26,7 +26,7 @@ function Invoke-WPFFeatureInstall {
|
||||
$Features | ForEach-Object {
|
||||
Invoke-WinUtilFeatureInstall $_
|
||||
$X++
|
||||
Invoke-WPFUIThread -ScriptBlock { Set-WinUtilTaskbaritem -value ($x/$CheckBox.Count) }
|
||||
Invoke-WPFUIThread -ScriptBlock { Set-WinUtilTaskbaritem -value ($x/$Features.Count) }
|
||||
}
|
||||
|
||||
$sync.ProcessRunning = $false
|
||||
|
||||
@@ -24,7 +24,7 @@ function Invoke-WPFInstall {
|
||||
$packageSummary = Get-WinUtilPackageLogSummary -Packages $PackagesToInstall -Preference $ManagerPreference
|
||||
Write-WinUtilLog -Component "Install" -Message "Install selected package(s): $($packageSummary -join '; ')"
|
||||
|
||||
$handle = Invoke-WPFRunspace -ParameterList @(("PackagesToInstall", $PackagesToInstall),("ManagerPreference", $ManagerPreference)) -ScriptBlock {
|
||||
Invoke-WPFRunspace -ParameterList @(("PackagesToInstall", $PackagesToInstall),("ManagerPreference", $ManagerPreference)) -ScriptBlock {
|
||||
param($PackagesToInstall, $ManagerPreference)
|
||||
|
||||
$packagesSorted = Get-WinUtilSelectedPackages -PackageList $PackagesToInstall -Preference $ManagerPreference
|
||||
|
||||
@@ -24,6 +24,7 @@ function Invoke-WPFRunspace {
|
||||
#>
|
||||
|
||||
[CmdletBinding()]
|
||||
[OutputType([System.IAsyncResult])]
|
||||
Param (
|
||||
$ScriptBlock,
|
||||
$ArgumentList,
|
||||
|
||||
@@ -223,6 +223,18 @@ function Invoke-WPFUIElements {
|
||||
$sync[$entryInfo.Name].Add_Unchecked({
|
||||
$this.Content = $this.Tag.contentOff
|
||||
})
|
||||
|
||||
if ($null -eq $sync.Buttons) {
|
||||
$sync.Buttons = [System.Collections.Generic.List[PSObject]]::new()
|
||||
}
|
||||
|
||||
if ($sync.Buttons -notcontains $toggleButton.Name) {
|
||||
$toggleButton.Add_Click({
|
||||
[System.Object]$Sender = $args[0]
|
||||
Invoke-WPFButton $Sender.name
|
||||
})
|
||||
$sync.Buttons.Add($toggleButton.Name) | Out-Null
|
||||
}
|
||||
}
|
||||
|
||||
"Combobox" {
|
||||
@@ -294,6 +306,18 @@ function Invoke-WPFUIElements {
|
||||
$itemsControl.Items.Add($button) | Out-Null
|
||||
|
||||
$sync[$entryInfo.Name] = $button
|
||||
|
||||
if ($null -eq $sync.Buttons) {
|
||||
$sync.Buttons = [System.Collections.Generic.List[PSObject]]::new()
|
||||
}
|
||||
|
||||
if ($sync.Buttons -notcontains $button.Name) {
|
||||
$button.Add_Click({
|
||||
[System.Object]$Sender = $args[0]
|
||||
Invoke-WPFButton $Sender.name
|
||||
})
|
||||
$sync.Buttons.Add($button.Name) | Out-Null
|
||||
}
|
||||
}
|
||||
|
||||
"RadioButton" {
|
||||
|
||||
@@ -57,7 +57,7 @@ function Invoke-WPFtweaksbutton {
|
||||
}
|
||||
|
||||
# The leading "," in the ParameterList is necessary because we only provide one argument and powershell cannot be convinced that we want a nested loop with only one argument otherwise
|
||||
$handle = Invoke-WPFRunspace -ParameterList @(("tweaks", $tweaksToRun), ("dnsProvider", $dnsProvider), ("completedSteps", $completedSteps), ("totalSteps", $totalSteps)) -ScriptBlock {
|
||||
Invoke-WPFRunspace -ParameterList @(("tweaks", $tweaksToRun), ("dnsProvider", $dnsProvider), ("completedSteps", $completedSteps), ("totalSteps", $totalSteps)) -ScriptBlock {
|
||||
param($tweaks, $dnsProvider, $completedSteps, $totalSteps)
|
||||
|
||||
$sync.ProcessRunning = $true
|
||||
|
||||
@@ -39,9 +39,11 @@ BeforeAll {
|
||||
process { }
|
||||
}
|
||||
function Get-Package {
|
||||
[System.Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSAvoidOverwritingBuiltInCmdlets', '', Justification='Test shim is intentionally mocked by Pester.')]
|
||||
param($Name, $ErrorAction)
|
||||
}
|
||||
function Uninstall-Package {
|
||||
[System.Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSAvoidOverwritingBuiltInCmdlets', '', Justification='Test shim is intentionally mocked by Pester.')]
|
||||
param(
|
||||
[Parameter(ValueFromPipeline = $true)]
|
||||
$InputObject,
|
||||
|
||||
@@ -32,11 +32,4 @@ Describe "Rendered asset caching" {
|
||||
$taskbarScript | Should -Match 'Initialize-WinUtilTaskbarOverlayAssets -IncludeLogo \$false -IncludeStatusAssets \$true'
|
||||
}
|
||||
|
||||
It "records individual taskbar overlay render checkpoints" {
|
||||
$overlayScript = Get-Content -Path (Join-Path $script:repoRoot "functions\private\Initialize-WinUtilTaskbarOverlayAssets.ps1") -Raw
|
||||
|
||||
$overlayScript | Should -Match 'Taskbar logo asset rendered'
|
||||
$overlayScript | Should -Match 'Taskbar checkmark asset rendered'
|
||||
$overlayScript | Should -Match 'Taskbar warning asset rendered'
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,7 +21,7 @@ Describe "Install app rendering startup contract" {
|
||||
$renderScript | Should -Match 'Dispatcher\.BeginInvoke'
|
||||
$renderScript | Should -Match 'Invoke-WinUtilInstallAppRenderNextBatch'
|
||||
$renderScript | Should -Match 'Initialize-InstallAppEntry'
|
||||
$renderScript | Should -Match 'Install app entries rendered'
|
||||
$renderScript | Should -Match '\$sync\.InstallAppEntriesRendered = \$true'
|
||||
}
|
||||
|
||||
It "does not use dispatcher timers for deferred install rendering" {
|
||||
@@ -41,7 +41,6 @@ Describe "Install app rendering startup contract" {
|
||||
$previousSync = Get-Variable -Name sync -Scope Global -ErrorAction SilentlyContinue
|
||||
$previousInitializeAppEntry = Get-Item -Path Function:\Initialize-InstallAppEntry -ErrorAction SilentlyContinue
|
||||
$previousSearch = Get-Item -Path Function:\Find-AppsByNameOrDescription -ErrorAction SilentlyContinue
|
||||
$previousCheckpoint = Get-Item -Path Function:\Write-WinUtilPerformanceCheckpoint -ErrorAction SilentlyContinue
|
||||
$errorCountBefore = $global:Error.Count
|
||||
|
||||
try {
|
||||
@@ -52,7 +51,6 @@ Describe "Install app rendering startup contract" {
|
||||
$global:sync.InstallAppRenderQueue = [System.Collections.Queue]::new()
|
||||
|
||||
$renderedApps = [System.Collections.Generic.List[string]]::new()
|
||||
$checkpoints = [System.Collections.Generic.List[string]]::new()
|
||||
|
||||
function global:Initialize-InstallAppEntry {
|
||||
param($TargetElement, $AppKey)
|
||||
@@ -65,11 +63,6 @@ Describe "Install app rendering startup contract" {
|
||||
throw "Search should not run for an empty search box in this test."
|
||||
}
|
||||
|
||||
function global:Write-WinUtilPerformanceCheckpoint {
|
||||
param([string]$Name)
|
||||
$checkpoints.Add($Name)
|
||||
}
|
||||
|
||||
$global:sync.InstallAppRenderQueue.Enqueue([pscustomobject]@{ TargetElement = [pscustomobject]@{}; AppKeys = @("AppA", "AppB") })
|
||||
$global:sync.InstallAppRenderQueue.Enqueue([pscustomobject]@{ TargetElement = [pscustomobject]@{}; AppKeys = @("AppC") })
|
||||
|
||||
@@ -80,8 +73,8 @@ Describe "Install app rendering startup contract" {
|
||||
$closeTimer = New-Object System.Windows.Threading.DispatcherTimer
|
||||
$closeTimer.Interval = [TimeSpan]::FromMilliseconds(25)
|
||||
$closeTimer.Add_Tick({
|
||||
param($sender)
|
||||
$timer = [System.Windows.Threading.DispatcherTimer]$sender
|
||||
param($eventSender)
|
||||
$timer = [System.Windows.Threading.DispatcherTimer]$eventSender
|
||||
|
||||
if ($global:sync.InstallAppEntriesRendered -or $timeout.Elapsed.TotalSeconds -gt 5) {
|
||||
$timer.Stop()
|
||||
@@ -95,7 +88,6 @@ Describe "Install app rendering startup contract" {
|
||||
$global:sync.InstallAppEntriesRendered | Should -BeTrue
|
||||
$global:sync.InstallAppRenderQueue.Count | Should -Be 0
|
||||
@($renderedApps) | Should -Be @("AppA", "AppB", "AppC")
|
||||
@($checkpoints) | Should -Contain "Install app entries rendered"
|
||||
$global:Error.Count | Should -Be $errorCountBefore
|
||||
} finally {
|
||||
if ($previousSync) {
|
||||
@@ -106,8 +98,7 @@ Describe "Install app rendering startup contract" {
|
||||
|
||||
foreach ($functionBackup in @(
|
||||
@{ Name = "Initialize-InstallAppEntry"; Backup = $previousInitializeAppEntry },
|
||||
@{ Name = "Find-AppsByNameOrDescription"; Backup = $previousSearch },
|
||||
@{ Name = "Write-WinUtilPerformanceCheckpoint"; Backup = $previousCheckpoint }
|
||||
@{ Name = "Find-AppsByNameOrDescription"; Backup = $previousSearch }
|
||||
)) {
|
||||
if ($functionBackup.Backup) {
|
||||
Set-Item -Path "Function:\$($functionBackup.Name)" -Value $functionBackup.Backup.ScriptBlock
|
||||
|
||||
@@ -11,9 +11,6 @@ BeforeAll {
|
||||
function Initialize-WPFUI {
|
||||
param([string]$TargetGridName)
|
||||
}
|
||||
function Write-WinUtilPerformanceCheckpoint {
|
||||
param([string]$Name)
|
||||
}
|
||||
function Invoke-WinUtilISOCheckExistingWork { }
|
||||
|
||||
. (Join-Path $script:repoRoot "functions\private\Initialize-WinUtilTabContent.ps1")
|
||||
@@ -32,7 +29,6 @@ Describe "Initialize-WinUtilTabContent" {
|
||||
|
||||
Mock Invoke-WPFUIElements { }
|
||||
Mock Initialize-WPFUI { }
|
||||
Mock Write-WinUtilPerformanceCheckpoint { }
|
||||
}
|
||||
|
||||
AfterEach {
|
||||
@@ -91,4 +87,13 @@ Describe "Startup lazy tab wiring" {
|
||||
|
||||
$tabScript | Should -Match 'Initialize-WinUtilTabContent -TabName \$sync\.currentTab'
|
||||
}
|
||||
|
||||
It "binds generated button clicks when lazy panels are rendered" {
|
||||
$rendererScript = Get-Content -Path (Join-Path $script:repoRoot "functions\public\Invoke-WPFUIElements.ps1") -Raw
|
||||
$mainScript = Get-Content -Path (Join-Path $script:repoRoot "scripts\main.ps1") -Raw
|
||||
|
||||
$rendererScript | Should -Match '(?s)"Button"\s*\{.*\$button\.Add_Click\(\{.*Invoke-WPFButton \$Sender\.name'
|
||||
$rendererScript | Should -Match '\$sync\.Buttons\.Add\(\$button\.Name\)'
|
||||
$mainScript | Should -Match '\$sync\.Buttons -notcontains \$psitem'
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,116 +0,0 @@
|
||||
#===========================================================================
|
||||
# Tests - Performance tracing
|
||||
#===========================================================================
|
||||
|
||||
BeforeAll {
|
||||
$script:repoRoot = (Resolve-Path (Join-Path $PSScriptRoot "..")).Path
|
||||
|
||||
. (Join-Path $script:repoRoot "functions\private\Write-WinUtilLog.ps1")
|
||||
. (Join-Path $script:repoRoot "tools\perf\Test-WinUtilPerformanceTrace.ps1")
|
||||
. (Join-Path $script:repoRoot "tools\perf\Write-WinUtilPerformanceCheckpoint.ps1")
|
||||
. (Join-Path $script:repoRoot "tools\perf\Start-WinUtilPerformanceTrace.ps1")
|
||||
. (Join-Path $script:repoRoot "tools\perf\Stop-WinUtilPerformanceTrace.ps1")
|
||||
}
|
||||
|
||||
AfterAll {
|
||||
& (Join-Path $script:repoRoot "Compile.ps1")
|
||||
}
|
||||
|
||||
Describe "WinUtil performance tracing helpers" {
|
||||
BeforeEach {
|
||||
$script:originalPerfEnv = $env:WINUTIL_PERF_LOG
|
||||
Remove-Item Env:\WINUTIL_PERF_LOG -ErrorAction SilentlyContinue
|
||||
$script:sync = [Hashtable]::Synchronized(@{})
|
||||
}
|
||||
|
||||
AfterEach {
|
||||
if ($null -eq $script:originalPerfEnv) {
|
||||
Remove-Item Env:\WINUTIL_PERF_LOG -ErrorAction SilentlyContinue
|
||||
} else {
|
||||
$env:WINUTIL_PERF_LOG = $script:originalPerfEnv
|
||||
}
|
||||
|
||||
Remove-Variable -Name sync -Scope Script -ErrorAction SilentlyContinue
|
||||
Remove-Variable -Name originalPerfEnv -Scope Script -ErrorAction SilentlyContinue
|
||||
}
|
||||
|
||||
It "is disabled by default" {
|
||||
Test-WinUtilPerformanceTrace | Should -BeFalse
|
||||
}
|
||||
|
||||
It "can be enabled by environment variable" {
|
||||
$env:WINUTIL_PERF_LOG = "1"
|
||||
|
||||
Test-WinUtilPerformanceTrace | Should -BeTrue
|
||||
}
|
||||
|
||||
It "writes startup checkpoints through the normal WinUtil log helper" {
|
||||
$env:WINUTIL_PERF_LOG = "1"
|
||||
Mock Write-WinUtilLog { }
|
||||
|
||||
Start-WinUtilPerformanceTrace
|
||||
Write-WinUtilPerformanceCheckpoint -Name "XAML loaded"
|
||||
Stop-WinUtilPerformanceTrace
|
||||
|
||||
Should -Invoke -CommandName Write-WinUtilLog -Times 3 -Exactly -ParameterFilter {
|
||||
$Component -eq "StartupPerf" -and $Level -eq "DEBUG"
|
||||
}
|
||||
Should -Invoke -CommandName Write-WinUtilLog -Times 1 -Exactly -ParameterFilter {
|
||||
$Message -like "XAML loaded:*"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Describe "Startup performance checkpoints" {
|
||||
It "keeps performance tracing out of normal compiled output" {
|
||||
& (Join-Path $script:repoRoot "Compile.ps1")
|
||||
|
||||
$compiledScript = Get-Content -Path (Join-Path $script:repoRoot "winutil.ps1") -Raw
|
||||
|
||||
$compiledScript | Should -Not -Match "Test-WinUtilPerformanceTrace"
|
||||
$compiledScript | Should -Not -Match "Start-WinUtilPerformanceTrace"
|
||||
$compiledScript | Should -Not -Match "Write-WinUtilPerformanceCheckpoint"
|
||||
$compiledScript | Should -Not -Match "Stop-WinUtilPerformanceTrace"
|
||||
$compiledScript | Should -Not -Match "PerformanceTraceEnabled"
|
||||
}
|
||||
|
||||
It "adds config-load checkpoints only to trace compiled output" {
|
||||
$compileScript = Get-Content -Path (Join-Path $script:repoRoot "Compile.ps1") -Raw
|
||||
|
||||
$compileScript | Should -Match '\[switch\]\$Trace'
|
||||
$compileScript | Should -Match "Start-WinUtilPerformanceTrace"
|
||||
$compileScript | Should -Match "Config load start"
|
||||
$compileScript | Should -Match "Config load complete"
|
||||
$compileScript | Should -Match "Config .* loaded"
|
||||
|
||||
& (Join-Path $script:repoRoot "Compile.ps1") -Trace
|
||||
$compiledScript = Get-Content -Path (Join-Path $script:repoRoot "winutil.ps1") -Raw
|
||||
|
||||
$compiledScript | Should -Match "function Test-WinUtilPerformanceTrace"
|
||||
$compiledScript | Should -Match '\$sync\.PerformanceTraceEnabled = \$true'
|
||||
$compiledScript | Should -Match "Config load start"
|
||||
$compiledScript | Should -Match "Config load complete"
|
||||
}
|
||||
|
||||
It "adds runtime checkpoints for startup hotspots" {
|
||||
$mainScript = Get-Content -Path (Join-Path $script:repoRoot "scripts\main.ps1") -Raw
|
||||
$lazyTabScript = Get-Content -Path (Join-Path $script:repoRoot "functions\private\Initialize-WinUtilTabContent.ps1") -Raw
|
||||
$runspaceScript = Get-Content -Path (Join-Path $script:repoRoot "functions\private\Initialize-WinUtilRunspacePool.ps1") -Raw
|
||||
$overlayScript = Get-Content -Path (Join-Path $script:repoRoot "functions\private\Initialize-WinUtilTaskbarOverlayAssets.ps1") -Raw
|
||||
$startupText = "$mainScript`n$lazyTabScript`n$runspaceScript`n$overlayScript"
|
||||
|
||||
foreach ($checkpoint in @(
|
||||
"Runspace pool initialized",
|
||||
"XAML loaded",
|
||||
"Theme applied",
|
||||
"Install UI created",
|
||||
"Tweaks UI created",
|
||||
"Features UI created",
|
||||
"AppX UI created",
|
||||
"Taskbar logo asset rendered",
|
||||
"First content rendered"
|
||||
)) {
|
||||
$startupText | Should -Match ([regex]::Escape($checkpoint))
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -12,9 +12,6 @@ Describe "Initialize-WinUtilRunspacePool" {
|
||||
BeforeEach {
|
||||
$script:sync = [Hashtable]::Synchronized(@{})
|
||||
$script:PARAM_OFFLINE = $false
|
||||
|
||||
function Write-WinUtilPerformanceCheckpoint { param($Name) }
|
||||
Mock Write-WinUtilPerformanceCheckpoint { }
|
||||
}
|
||||
|
||||
AfterEach {
|
||||
@@ -29,9 +26,6 @@ Describe "Initialize-WinUtilRunspacePool" {
|
||||
|
||||
$firstPool.RunspacePoolStateInfo.State | Should -Be ([System.Management.Automation.Runspaces.RunspacePoolState]::Opened)
|
||||
[object]::ReferenceEquals($firstPool, $secondPool) | Should -BeTrue
|
||||
Should -Invoke -CommandName Write-WinUtilPerformanceCheckpoint -Times 1 -Exactly -ParameterFilter {
|
||||
$Name -eq "Runspace pool initialized"
|
||||
}
|
||||
}
|
||||
|
||||
It "closes and removes the active runspace pool" {
|
||||
|
||||
@@ -20,8 +20,6 @@ BeforeAll {
|
||||
$initialSessionState.Variables.Add($syncVariable)
|
||||
$script:sync.runspace = [runspacefactory]::CreateRunspacePool(1, 2, $initialSessionState, $Host)
|
||||
$script:sync.runspace.Open()
|
||||
|
||||
function Write-WinUtilPerformanceCheckpoint { param($Name) }
|
||||
}
|
||||
|
||||
function script:Clear-WinUtilRunspaceTestContext {
|
||||
|
||||
@@ -208,8 +208,6 @@ Describe "Runspace sanity" {
|
||||
. (Join-Path $script:repoRoot "functions\public\Invoke-WPFRunspace.ps1")
|
||||
. (Join-Path $script:repoRoot "functions\private\Close-WinUtilRunspacePool.ps1")
|
||||
. (Join-Path $script:repoRoot "functions\private\Initialize-WinUtilRunspacePool.ps1")
|
||||
|
||||
function Write-WinUtilPerformanceCheckpoint { param($Name) }
|
||||
}
|
||||
|
||||
It "returns a single async handle and runs a scriptblock with arguments in the shared runspace pool" {
|
||||
|
||||
@@ -35,6 +35,7 @@ Describe "Win11 Creator setup media" {
|
||||
return $functionAst.Extent.Text
|
||||
}
|
||||
|
||||
$script:modifyFunction = Get-WinUtilFunctionText -Path $script:isoWorkflowPath -FunctionName "Invoke-WinUtilISOModify"
|
||||
$script:editionIdFunction = Get-WinUtilFunctionText -Path $script:isoWorkflowPath -FunctionName "Get-WinUtilEditionIdFromName"
|
||||
$script:addDriversFunction = Get-WinUtilFunctionText -Path $script:isoScriptPath -FunctionName "Add-DriversToImage"
|
||||
$script:answerFileChildElementFunction = Get-WinUtilFunctionText -Path $script:isoScriptPath -FunctionName "Get-WinUtilISOScriptChildElement"
|
||||
@@ -69,6 +70,27 @@ Describe "Win11 Creator setup media" {
|
||||
}
|
||||
}
|
||||
|
||||
It "starts each new ISO modification in a fresh working directory" {
|
||||
foreach ($expectedText in @(
|
||||
'$workDir = Join-Path $env:TEMP "WinUtil_Win11ISO_$(Get-Date -Format ''yyyyMMdd_HHmmss'')"',
|
||||
'$workDir = Join-Path $env:TEMP "WinUtil_Win11ISO_$(Get-Date -Format ''yyyyMMdd_HHmmss'')_$(([guid]::NewGuid()).ToString(''N'').Substring(0, 8))"'
|
||||
)) {
|
||||
$script:modifyFunction | Should -Match ([regex]::Escape($expectedText))
|
||||
}
|
||||
|
||||
$script:modifyFunction | Should -Not -Match ([regex]::Escape("Reusing existing temp directory"))
|
||||
}
|
||||
|
||||
It "mounts the copied image file that was verified from the ISO" {
|
||||
foreach ($expectedText in @(
|
||||
'$sourceImageFileName = Split-Path $wimPath -Leaf',
|
||||
'$localWim = Join-Path $isoContents "sources\$sourceImageFileName"',
|
||||
'Copied ISO image file not found: sources\$sourceImageFileName'
|
||||
)) {
|
||||
$script:modifyFunction | Should -Match ([regex]::Escape($expectedText))
|
||||
}
|
||||
}
|
||||
|
||||
It "maps Windows edition names to setup edition IDs" {
|
||||
. ([scriptblock]::Create($script:editionIdFunction))
|
||||
|
||||
|
||||
+16
-14
@@ -57,10 +57,8 @@ $sync.configs.appxHashtable = @{}
|
||||
$sync.configs.appx.PSObject.Properties | ForEach-Object {
|
||||
$sync.configs.appxHashtable[$_.Name] = $_.Value
|
||||
}
|
||||
Write-WinUtilPerformanceCheckpoint -Name "Config hashtables initialized"
|
||||
|
||||
Set-Preferences
|
||||
Write-WinUtilPerformanceCheckpoint -Name "Preferences loaded"
|
||||
|
||||
if ($Preset) {
|
||||
Initialize-WinUtilRunspacePool | Out-Null
|
||||
@@ -101,7 +99,6 @@ $reader = (New-Object System.Xml.XmlNodeReader $xaml)
|
||||
try {
|
||||
$sync["Form"] = [Windows.Markup.XamlReader]::Load( $reader )
|
||||
$readerOperationSuccessful = $true
|
||||
Write-WinUtilPerformanceCheckpoint -Name "XAML loaded"
|
||||
} catch [System.Management.Automation.MethodInvocationException] {
|
||||
Write-Host "We ran into a problem with the XAML code. Check the syntax for this control..." -ForegroundColor Red
|
||||
Write-Host $error[0].Exception.Message -ForegroundColor Red
|
||||
@@ -136,6 +133,7 @@ $sync.Form.Add_Loaded({
|
||||
[System.IntPtr]$lParam,
|
||||
[ref]$handled
|
||||
)
|
||||
$null = $hwnd, $wParam, $lParam
|
||||
# Check for the Event WM_SETTINGCHANGE (0x1001A) and validate that Button shows the icon for "Auto" => [char]0xF08C
|
||||
if (($msg -eq 0x001A) -and $sync.ThemeButton.Content -eq [char]0xF08C) {
|
||||
$currentTime = [datetime]::Now
|
||||
@@ -150,7 +148,6 @@ $sync.Form.Add_Loaded({
|
||||
})
|
||||
|
||||
Invoke-WinutilThemeChange -theme $sync.preferences.theme
|
||||
Write-WinUtilPerformanceCheckpoint -Name "Theme applied"
|
||||
|
||||
|
||||
# Build only the default tab before first paint; other tabs initialize on first activation.
|
||||
@@ -184,17 +181,23 @@ switch ($sync.preferences.packagemanager) {
|
||||
$sync.keys | ForEach-Object {
|
||||
if($sync.$psitem) {
|
||||
if($($sync["$psitem"].GetType() | Select-Object -ExpandProperty Name) -eq "ToggleButton") {
|
||||
$sync["$psitem"].Add_Click({
|
||||
[System.Object]$Sender = $args[0]
|
||||
Invoke-WPFButton $Sender.name
|
||||
})
|
||||
if ($sync.Buttons -notcontains $psitem) {
|
||||
$sync["$psitem"].Add_Click({
|
||||
[System.Object]$Sender = $args[0]
|
||||
Invoke-WPFButton $Sender.name
|
||||
})
|
||||
$sync.Buttons.Add($psitem) | Out-Null
|
||||
}
|
||||
}
|
||||
|
||||
if($($sync["$psitem"].GetType() | Select-Object -ExpandProperty Name) -eq "Button") {
|
||||
$sync["$psitem"].Add_Click({
|
||||
[System.Object]$Sender = $args[0]
|
||||
Invoke-WPFButton $Sender.name
|
||||
})
|
||||
if ($sync.Buttons -notcontains $psitem) {
|
||||
$sync["$psitem"].Add_Click({
|
||||
[System.Object]$Sender = $args[0]
|
||||
Invoke-WPFButton $Sender.name
|
||||
})
|
||||
$sync.Buttons.Add($psitem) | Out-Null
|
||||
}
|
||||
}
|
||||
|
||||
if ($($sync["$psitem"].GetType() | Select-Object -ExpandProperty Name) -eq "TextBlock") {
|
||||
@@ -221,7 +224,6 @@ Set-WinUtilTaskbaritem -state "None"
|
||||
$sync["Form"].title = $sync["Form"].title + " " + $sync.version
|
||||
# Set the commands that will run when the form is closed
|
||||
$sync["Form"].Add_Closing({
|
||||
Stop-WinUtilPerformanceTrace -Name "Window closing"
|
||||
Close-WinUtilRunspacePool
|
||||
[System.GC]::Collect()
|
||||
})
|
||||
@@ -290,7 +292,6 @@ $sync["Form"].Add_Deactivated({
|
||||
})
|
||||
|
||||
$sync["Form"].Add_ContentRendered({
|
||||
Write-WinUtilPerformanceCheckpoint -Name "First content rendered"
|
||||
# Load the Windows Forms assembly
|
||||
Add-Type -AssemblyName System.Windows.Forms
|
||||
$primaryScreen = [System.Windows.Forms.Screen]::PrimaryScreen
|
||||
@@ -378,6 +379,7 @@ $sync["SearchBar"].Add_TextChanged({
|
||||
|
||||
$sync["Form"].Add_Loaded({
|
||||
param($e)
|
||||
$null = $e
|
||||
$sync.Form.MinWidth = "1000"
|
||||
$sync["Form"].MaxWidth = [Double]::PositiveInfinity
|
||||
$sync["Form"].MaxHeight = [Double]::PositiveInfinity
|
||||
|
||||
@@ -27,12 +27,10 @@ function Get-RawJsonBlock {
|
||||
|
||||
$escapedName = [regex]::Escape($ItemName)
|
||||
$startIndex = -1
|
||||
$startIndent = ""
|
||||
|
||||
for ($i = 0; $i -lt $JsonLines.Count; $i++) {
|
||||
if ($JsonLines[$i] -match "^(\s*)`"$escapedName`"\s*:\s*\{") {
|
||||
$startIndex = $i
|
||||
$startIndent = $matches[1]
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,14 +0,0 @@
|
||||
function Start-WinUtilPerformanceTrace {
|
||||
if (-not (Test-WinUtilPerformanceTrace) -or $null -eq $sync) {
|
||||
return
|
||||
}
|
||||
|
||||
if (-not $sync.ContainsKey("PerformanceTrace")) {
|
||||
$sync.PerformanceTrace = @{
|
||||
Stopwatch = [System.Diagnostics.Stopwatch]::StartNew()
|
||||
LastElapsedMs = 0.0
|
||||
}
|
||||
}
|
||||
|
||||
Write-WinUtilPerformanceCheckpoint -Name "Startup trace started"
|
||||
}
|
||||
@@ -1,15 +0,0 @@
|
||||
function Stop-WinUtilPerformanceTrace {
|
||||
param(
|
||||
[string]$Name = "Startup trace complete"
|
||||
)
|
||||
|
||||
if (-not (Test-WinUtilPerformanceTrace) -or $null -eq $sync -or -not $sync.ContainsKey("PerformanceTrace")) {
|
||||
return
|
||||
}
|
||||
|
||||
Write-WinUtilPerformanceCheckpoint -Name $Name
|
||||
|
||||
if ($null -ne $sync.PerformanceTrace.Stopwatch) {
|
||||
$sync.PerformanceTrace.Stopwatch.Stop()
|
||||
}
|
||||
}
|
||||
@@ -1,12 +0,0 @@
|
||||
function Test-WinUtilPerformanceTrace {
|
||||
$enabledValue = ([string]$env:WINUTIL_PERF_LOG).ToLowerInvariant()
|
||||
if ($enabledValue -in @("1", "true", "yes", "on")) {
|
||||
return $true
|
||||
}
|
||||
|
||||
if ($null -ne $sync -and $sync.ContainsKey("PerformanceTraceEnabled")) {
|
||||
return [bool]$sync.PerformanceTraceEnabled
|
||||
}
|
||||
|
||||
return $false
|
||||
}
|
||||
@@ -1,23 +0,0 @@
|
||||
function Write-WinUtilPerformanceCheckpoint {
|
||||
param(
|
||||
[Parameter(Mandatory = $true)]
|
||||
[string]$Name
|
||||
)
|
||||
|
||||
if (-not (Test-WinUtilPerformanceTrace) -or $null -eq $sync) {
|
||||
return
|
||||
}
|
||||
|
||||
if (-not $sync.ContainsKey("PerformanceTrace") -or $null -eq $sync.PerformanceTrace.Stopwatch) {
|
||||
$sync.PerformanceTrace = @{
|
||||
Stopwatch = [System.Diagnostics.Stopwatch]::StartNew()
|
||||
LastElapsedMs = 0.0
|
||||
}
|
||||
}
|
||||
|
||||
$elapsedMs = [math]::Round($sync.PerformanceTrace.Stopwatch.Elapsed.TotalMilliseconds, 2)
|
||||
$deltaMs = [math]::Round($elapsedMs - [double]$sync.PerformanceTrace.LastElapsedMs, 2)
|
||||
$sync.PerformanceTrace.LastElapsedMs = $elapsedMs
|
||||
|
||||
Write-WinUtilLog -Level "DEBUG" -Component "StartupPerf" -Message ("{0}: {1:N2} ms (+{2:N2} ms)" -f $Name, $elapsedMs, $deltaMs)
|
||||
}
|
||||
+2
-1
@@ -1,4 +1,5 @@
|
||||
# Runs the pre-release version of winutil
|
||||
|
||||
$latestTag = (Invoke-RestMethod https://api.github.com/repos/ChrisTitusTech/winutil/tags).Name | Select-Object -First 1
|
||||
Invoke-RestMethod -Uri https://github.com/ChrisTitusTech/winutil/releases/download/$latestTag/winutil.ps1 | Invoke-Expression
|
||||
$script = Invoke-RestMethod -Uri https://github.com/ChrisTitusTech/winutil/releases/download/$latestTag/winutil.ps1
|
||||
Invoke-Command -ScriptBlock ([scriptblock]::Create($script)) -ErrorAction Stop
|
||||
|
||||
Reference in New Issue
Block a user