fix(dsc): make PSResourceList test, set and what-if agree on desired state - #2048
Gijs Reijn (Gijsreyn) wants to merge 1 commit into
Conversation
|
Azure Pipelines: There may be pipelines that require an authorized user to comment /azp run to run. |
There was a problem hiding this comment.
Copilot review overview
🟡 Changes recommended
Unresolved issues affect scope-aware convergence, install deduplication, and test isolation.
Get a fresh assessment by requesting another Copilot review.
Review effort: Lite
Findings: 2
Open (2)
What changed in this PR
Unifies PSResourceList desired-state evaluation across test, set, and what-if.
Changes:
- Centralizes resource action pairing.
- Handles versions, scopes,
_exist, and error tracing. - Adds DSC regression coverage.
| File | Description |
|---|---|
test/DscResource/PSResourceGetDSCResource.Tests.ps1 |
Adds regression and scope-related tests. |
src/dsc/psresourceget.ps1 |
Implements shared desired-state actions and scope-aware operations. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
| else { | ||
| # No version constraint: any installed version means the resource exists. | ||
| # Only record the first match so that one input resource maps to one current resource. | ||
| Write-Trace -message "No version constraint for input: $($inputResource.Name). Treating installed version $($matchingResources[0].Version) as a match." -level debug | ||
| $preferred = $matchingResources | Select-Object -First 1 |
There was a problem hiding this comment.
Gijs Reijn (@Gijsreyn) - please take a look.
| # Install if resource should exist but doesn't, or exists but not in desired state | ||
| elseif ($resourceAction.action -eq 'Install') { | ||
| Write-Trace -message "Resource $name needs to be installed." -level debug | ||
| $key = $name.ToLowerInvariant() + '-' + $versionStr.ToLowerInvariant() |
| throw "Cannot pair the desired and current resources. Desired count: $($desiredResources.Count), current count: $($currentResources.Count)." | ||
| } | ||
|
|
||
| for ($i = 0; $i -lt $desiredResources.Count; $i++) { |
There was a problem hiding this comment.
When comparing we have to check every resource in the current state with the desired state. The order can be different. For example,
Current state: A, B, C
Desired state: B,A,C
If we just match in order, it will be marked as not in desired state. But, it actually is.

PR Summary
test,setandwhat-ifforpsresourcelisteach computed desired state on their own and disagreed. They now share one pairing step (GetPSResourceListActions) that matches every desired resource to its current resource by index and decidesNone,InstallorUninstall.PR Context
This PR fixes the following points:
testonly checked the first resource.A resource without
versionnever converged.setcompared every desired resource against every current one.All resources were installed or uninstalled with the last resource's scope.
_existis compared before version and repository, and those only apply when specified.Uninstall removes the resource from the scope it is installed in.
Before,
Uninstall-PSResourcereceived the desired scope, which defaults toCurrentUserwhen omitted. A resource installed inAllUserswas therefore never removed andsetnever converged.Note
scopeis still not a filter.GetPSResourceListmatches the current resource on name and version across both scopes, so an explicitscope: CurrentUserwith_exist: falsealso removes anAllUserscopy. I'll create another issue for it.Errors trace at
errorlevel, so the real message is visible without--trace-level debug.This PR also includes a couple of behavioral changes:
_exist: falsewith aversionremoves only that version (range); withoutversionall versions are removed.Would install, matching whatsetdoes.PR Checklist
.h,.cpp,.cs,.ps1and.psm1files have the correct copyright headerWIP:or[ WIP ]to the beginning of the title (theWIPbot will keep its status check atPendingwhile the prefix is present) and remove the prefix when the PR is ready.