Repository navigation
Uninstall PowerShell 7 modules from the scope they were installed in - #5494
Merged
Merged
Conversation
Contributor
There was a problem hiding this comment.
🟡 Changes recommended
Brokered PowerShell 7 operations bypass the new scope handling, leaving the reported failure unresolved when Agent Broker is enabled.
1 open finding
What changed in this PR
Fixes PowerShell 7 uninstall and post-update cleanup to respect installation scope.
Changes:
- Adds detected-scope uninstall parameters and elevation retry handling.
- Makes previous-version cleanup scope-aware.
- Adds regression tests for scope and failure classification.
| File | Description |
|---|---|
PowerShell7ManagerTests.cs |
Tests scoped uninstall behavior and retries. |
PackageOperationsTests.cs |
Tests scope-aware version cleanup. |
PackageOperations.cs |
Filters cleanup candidates by scope. |
PowerShell7.cs |
Updates scope capability documentation. |
PowerShell7PkgOperationHelper.cs |
Adds scope arguments and failure handling. |
🧠 Review effort: Balanced
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
Maxim Buisson (MaxBuisson)
approved these changes
Oct 9, 2026
4 tasks done
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.

Root cause
Uninstall-PSResourcewas invoked without-Scope. In PSResourceGet theScopeparameter is a non-nullableScopeType, so "unset" meansCurrentUserand the cmdlet only searches the CurrentUser module paths. A module installed for AllUsers could never be uninstalled:This broke both a plain uninstall from the Installed page and the "Uninstall previous versions when updated" post-update step (the reported path).
Fix
-Scopefrom the copy's detected scope (from the installed-packages listing). The options-dialog scope is deliberately not used: the scope selector is hidden for uninstall, and the post-update purge hands every old copy the update's options, so a dialog scope would point CurrentUser copies at AllUsers. With no detected scope it targets CurrentUser, matching the cmdlet's previous behaviour.Follow-ups needed once uninstalls can actually reach AllUsers:
IsEquivalentTo, which ignores scope, so updating one scope's copy would now genuinely delete older copies in the other scope, including machine-wide modules other accounts rely on. The purge now only queues copies in the scope the update installed into (the options-dialog scope when the manager honours one on update, else the detected scope). Copies or updates with no recorded scope still match everything, so managers that don't track scope are unchanged.'<path>' could not be deletedrecord, which never matched theAdminPrivilegesAreRequiredretry. Failures are classified from that message (hard-coded English in PSResourceGet, so not affected by localized .NET text):-Scope. Users who worked around this bug with-Scope AllUsersin custom arguments would otherwise get a parameter-binding error.-Scopeis not injected when custom arguments already carry it, including PowerShell's accepted prefixes (-Sc,-Scop,-Scope:…).Testing
-Scope, the retry / leftover / CurrentUser result classification, and the scope-aware purge (same scope, dialog-chosen scope, scope-less update).Uninstall-PSResource … -Version 1.0.4with no-Scope, both post-operations fail);Uninstall-PSResource … -Scope AllUsersfor both, leaving only 1.0.7;Reviewer note: the elevated-retry and leftover-only paths are covered by unit tests only. The test machine's AllUsers module folder is writable by the test account, so a real access-denied failure couldn't be produced; the message format is taken from PSResourceGet's
UninstallPSResource.cs.Out of scope:
IsEquivalentTo/GetHashstill ignore scope everywhere else (ignored updates, installed-tag lookups). Making identity scope-aware touches persisted keys across every manager, so only the destructive consumer (the purge) is changed here.Closes #5491