Skip to content

Conversation

@ZeusCraft10
Copy link
Contributor

@ZeusCraft10 ZeusCraft10 commented Oct 9, 2025

Type of Change

  • New feature
  • Bug fix
  • Documentation update
  • Refactoring
  • Hotfix
  • Security patch
  • UI/UX improvement

Description

This PR resolves issue #3602 by implementing an "Apply to All Users" feature for registry tweaks in the winutil tool.

What was changed:

  • Added a new checkbox control "Apply to all users" in the Tweaks tab UI (inputXML.xaml)
  • Modified Invoke-WinUtilTweaks.ps1 to accept an -ApplyToAllUsers parameter
  • Implemented per-user hive iteration logic that applies registry tweaks to all user profiles (HKEY_USERS) when the checkbox is enabled
  • Updated all tweak handler functions to pass the ApplyToAllUsers parameter:
    • Invoke-WPFtweaksbutton.ps1 (Run Tweaks button)
    • Invoke-WPFUIElements.ps1 (individual tweak checkboxes)
    • Invoke-WPFundoall.ps1 (Undo All button)

How it works:

  • When the checkbox is checked, registry tweaks targeting HKCU are also applied to all user hives under HKEY_USERS
  • The implementation filters out system SIDs (S-1-5-18, S-1-5-19, S-1-5-20, .DEFAULT) to avoid modifying system/service accounts
  • Requires elevated privileges to write to other user hives
  • Default behavior (unchecked) remains unchanged - tweaks only apply to the current user

Files modified:

  1. xaml/inputXML.xaml (+6/-0) - Added checkbox UI
  2. functions/public/Invoke-WPFtweaksbutton.ps1 (+10/-3) - Read checkbox state and pass to runspace
  3. functions/private/Invoke-WinUtilTweaks.ps1 (+28/-1) - Core per-user iteration logic
  4. functions/public/Invoke-WPFUIElements.ps1 (+6/-2) - Updated per-toggle handlers
  5. functions/public/Invoke-WPFundoall.ps1 (+7/-3) - Updated undo operations

Testing

Manual testing performed:

  • Created new branch from main
  • Applied all code changes with GitHub Copilot assistance
  • All files staged and committed successfully
  • Branch pushed to remote repository
  • No PowerShell syntax errors or linting issues detected

Testing recommendations for reviewers:

  1. Run winutil with elevated privileges
  2. Navigate to the Tweaks tab
  3. Verify the "Apply to all users" checkbox appears and has proper tooltip
  4. Test with checkbox unchecked (should work as before - current user only)
  5. Test with checkbox checked:
    • Select a registry tweak and apply it
    • Verify the tweak is applied to all loaded user hives in HKEY_USERS
    • Verify system SIDs are excluded
  6. Test the Undo All function with the checkbox enabled
  7. Test individual tweak toggles with the checkbox enabled

Impact

Positive impacts:

Performance considerations:

  • When "Apply to all users" is enabled, registry operations are multiplied by the number of loaded user profiles
  • Impact is minimal for typical systems (2-5 user profiles)
  • Operations are still sequential and use existing error handling

New dependencies:

  • None

Behavioral changes:

  • New optional feature - no changes to default behavior
  • Checkbox state is not persisted across sessions (could be added in future enhancement)

Issue related to PR

Additional Information

Edge cases and notes:

  • Requires elevated/administrator privileges to write to other user registry hives
  • Only affects loaded user profiles (HKEY_USERS subkeys) - not offline profiles
  • System accounts (LocalService, NetworkService, System) are explicitly excluded via SID filtering
  • The .DEFAULT user profile is also excluded
  • For offline/default profile modifications, existing autounattend mechanisms should be used
  • This implementation only affects registry tweaks - script-based tweaks remain user-specific

Future enhancements (not included in this PR):

  • Persist checkbox state across sessions
  • Add confirmation dialog when enabling "Apply to all users"
  • Support for loading/applying to offline user profiles (Default user)
  • Unit tests for the per-user iteration logic

Checklist

  • My code adheres to the coding and style guidelines of the project.
  • I have performed a self-review of my own code.
  • I have commented my code, particularly in hard-to-understand areas.
  • I have made corresponding changes to the documentation.
  • My changes generate no errors/warnings/merge conflicts.

Add checkbox UI to apply registry tweaks to all user profiles (HKEY_USERS)
when enabled. Implements per-user hive iteration in Invoke-WinUtilTweaks
with safety filters for system SIDs. Updates all tweak handlers to pass
the new ApplyToAllUsers parameter.

Fixes ChrisTitusTech#3602
Comment on lines 82 to 112
# If the path targets HKCU and user requested ApplyToAllUsers, iterate through HKEY_USERS and apply to each user's hive
if ($ApplyToAllUsers -and ($psitem.Path -imatch "HKCU:" -or $psitem.Path -imatch "HKEY_CURRENT_USER")) {
try {
if(!(Test-Path 'HKU:\')) {New-PSDrive -PSProvider Registry -Name HKU -Root HKEY_USERS}
$users = Get-ChildItem -Path HKU:\ | Where-Object { $_.PSChildName -notin @('S-1-5-18','S-1-5-19','S-1-5-20','.DEFAULT') }
foreach ($user in $users) {
$userHive = $user.PSPath -replace '^Registry::',''
# Build a HKU path equivalent to the HKCU path
$relative = $psitem.Path -replace '^(HKCU:|HKEY_CURRENT_USER\\?)',''
$targetPath = "HKU:\$($user.PSChildName)\$relative"
try {
if (!(Test-Path $targetPath)) {
New-Item -Path $targetPath -Force | Out-Null
}
Set-WinUtilRegistry -Name $psitem.Name -Path $targetPath -Type $psitem.Type -Value $psitem.$($values.registry)
} catch {
Write-Warning "Failed to set $targetPath\$($psitem.Name): $_"
}
}
} catch {
Write-Warning "Failed enumerating user hives: $_"
}
}
else {
if (($psitem.Path -imatch "hku") -and !(Get-PSDrive -Name HKU -ErrorAction SilentlyContinue)) {
$null = (New-PSDrive -PSProvider Registry -Name HKU -Root HKEY_USERS)
if (Get-PSDrive -Name HKU -ErrorAction SilentlyContinue) {
Write-Debug "HKU drive created successfully"
} else {
Write-Debug "Failed to create HKU drive"
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh my god...

@gabrielsutton98
Copy link

gabrielsutton98 commented Oct 25, 2025

This was a godsend, since after installing windows 11, I wanted to have multiple accounts on the machine, to separate the levels of permissions. I was able to finally apply most of the tweaks to all the hives individually with this, which is great. One of the accounts is logged in with a Microsoft account, but I wish to disable one drive globally. This does not appear to work for me (which could be my own doing). The vanilla util applies it only to the main admin account even when ran from a different account using admin privileges. Using this branch the OneDrive tweak just exits immediately, so that code may need additional modifications to work on a multi-user workstation IE iterating through hives to make reg edits AND iterating through multiple users to move the files.

Copy link
Owner

@ChrisTitusTech ChrisTitusTech left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Clean up the if/else try/catch nesting. Its messy and it doesn't need to be that long.

Copy link

@TheBeardofKnowledge TheBeardofKnowledge left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks like it will not handle unloaded registry hives, leaving profiles for accounts that are not currently logged on without the tweaks.
I would recommend these changes:

:: Ensure HKU drive exists if needed
if ($ApplyToAllUsers -and $psitem.Path -match "^(HKCU:|HKEY_CURRENT_USER)") {
    if (!(Get-PSDrive -Name HKU -ErrorAction SilentlyContinue)) {
        New-PSDrive -PSProvider Registry -Name HKU -Root HKEY_USERS | Out-Null
    }
    
    $relativePath = $psitem.Path -replace '^(HKCU:|HKEY_CURRENT_USER\\?)', ''
    $excludedSIDs = @('S-1-5-18', 'S-1-5-19', 'S-1-5-20', '.DEFAULT')
    
    Get-ItemProperty "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList\*" -ErrorAction SilentlyContinue |
        Where-Object { $_.PSChildName -notin $excludedSIDs -and $_.ProfileImagePath } |
        ForEach-Object {
            $sid = $_.PSChildName
            $ntUserPath = Join-Path $_.ProfileImagePath "NTUSER.DAT"
            $needsUnload = !(Test-Path "HKU:\$sid")
            
            if ($needsUnload -and (Test-Path $ntUserPath)) {
                reg load "HKU\$sid" "$ntUserPath" 2>&1 | Out-Null
                Start-Sleep -Milliseconds 100
            }
            
            try {
                $targetPath = "HKU:\$sid\$relativePath"
                if (!(Test-Path $targetPath)) { New-Item -Path $targetPath -Force | Out-Null }
                Set-WinUtilRegistry -Name $psitem.Name -Path $targetPath -Type $psitem.Type -Value $psitem.$($values.registry)
            } catch {
                Write-Warning "Failed to set registry for SID $sid : $_"
            }
            
            if ($needsUnload) {
                [System.GC]::Collect()
                reg unload "HKU\$sid" 2>&1 | Out-Null
            }
        }
}

or I'm delulu and need more coffee... could be that one.

This commit addresses review feedback regarding the 'Apply to All Users' functionality and code structure in Invoke-WinUtilTweaks.ps1.

Changes:
- Refactored nested if/else logic to reduce complexity and improve readability.
- Updated registry tweak logic to correctly handle offline user profiles when 'Apply to All Users' is selected.
- Implemented `reg load` and `reg unload` for `NTUSER.DAT`, ensuring tweaks are applied even if the user is not currently logged in.
- Added safety checks to ensure the HKU drive is mounted before attempting operations.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Apply tweaks to all users instead of only current user by using a for-each loop

5 participants