Repository navigation
Force a GC before unloading the target user hive - #61
Merged
Merged
Conversation
Invoke-WithTargetUserHive loaded a user's NTUSER.DAT, ran the apply, verification, or restore work against it, then called reg unload. But that work opens .NET RegistryKey handles into the hive through the registry provider, and reg unload fails while any handle is still open. The old code just warned and moved on, leaving the hive mounted, which can lock the target profile until reboot and break the next per-user run. Route the unload through Dismount-WinnowTargetUserHive, which forces a garbage collection to release the lingering handles, unloads, and retries once after a second collect. It only warns if the hive still will not unload. The unload itself is behind Invoke-WinnowRegHiveUnload so the retry logic is unit-tested (reg is native and cannot be mocked directly).
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The bug
Invoke-WithTargetUserHive(Scripts/Helpers/UserHiveHelpers.ps1) mounts a target user'sNTUSER.DAT, runs the caller's work against it, then unloads in afinally. The apply, verification (Test-WinnowCustomFeatureStateunder-Sysprep/-User), and restore-to-another-user paths all read or write the mounted hive through the registry provider /Microsoft.Win32.RegistryKey, which leaves handles open in our process.reg unloadfails while any handle into the hive is open (exit 1), and the old code onlyWrite-Warninged — leaving the hive mounted, which can lock the target profile until reboot and break the next per-user run.No garbage collection was performed anywhere before the unload (
git grepforGC]::Collectreturned nothing), which is the documented remedy for offline-hive scripts.The fix
Route the unload through
Dismount-WinnowTargetUserHive, which:[System.GC]::Collect()+WaitForPendingFinalizers()to release the lingeringRegistryKeyhandles,The actual
reg unloadis behindInvoke-WinnowRegHiveUnloadso the retry logic is unit-testable (reg.exe is native and cannot be mocked).Validation
Tests\Invoke-StaticValidation.ps1 -RequirePSScriptAnalyzerclean (126 files).Tests/Unit/Test-UserHiveHelpers.ps1(Pester 5.7.1): 3/3 — unloads first try, retries-then-succeeds, warns-and-fails-after-two. Wired into CI.The live offline-hive load/unload cycle is only reachable under
-Sysprep/-Useron a real machine; the retry logic is covered by the unit tests above.