Fix false OrphanTreeEntry findings from ignorable chars in TaskCache Ids #6

Merged
hannah-vernon merged 1 commit from fix/guid-canonicalization-ignorable-chars into dev 2026-07-02 11:05:00 -05:00

What does this PR do?

Fixes a false-positive bug where Test-ScheduledTaskHealth.ps1 and Get-TaskCacheSummary.ps1
reported a large batch of OrphanTreeEntry findings on hosts whose tasks are actually healthy.

Root cause: some TaskCache\Tree "Id" values carry a stray ignorable character (for
example a zero-width space) after the GUID. The registry and PowerShell hashtables
(culture-aware) ignore such characters, but a .NET HashSet keyed with OrdinalIgnoreCase
treats them as significant. GUID comparison through that HashSet therefore failed to match
the clean TaskCache\Tasks\{GUID} subkey names.

On the machine that surfaced this, Get-TaskCacheSummary reported 197 of 213 Tree nodes as
orphaned, but a direct Test-Path check confirmed 187 of them do have their Tasks key -
the tasks were healthy; the comparison was wrong.

Fix: normalize GUIDs by extracting the canonical 8-4-4-4-12 hex pattern with a regex, which
discards any surrounding or embedded stray characters before comparison.

  • Get-TaskCacheSummary.ps1 - Format-Guid now regex-extracts the canonical GUID.
  • Test-ScheduledTaskHealth.ps1 - adds ConvertTo-CanonicalGuid and applies it when reading
    Tree Id values and Tasks subkey names. OrphanTaskEntry findings keep the real subkey name
    for the backup/removal registry paths.

How was this tested?

  • Parser validation - 0 errors for both scripts
  • Reproduced the bug with a fixture whose Tree Ids carry a trailing zero-width space:
    before the fix the string comparison failed; after the fix both scripts report zero false
    orphans.
  • Regression: genuinely orphaned Tree entries (no Tasks key) and orphaned Tasks entries
    (no Tree node) are still detected.

Checklist

  • I have read the Contributing Guide
  • Changes are focused - one logical change per PR
  • Comment-based help updated for any changed parameters or behavior
  • Documentation updated (if user-visible behavior changed)
  • No commented-out code or debug leftovers
## What does this PR do? Fixes a false-positive bug where `Test-ScheduledTaskHealth.ps1` and `Get-TaskCacheSummary.ps1` reported a large batch of `OrphanTreeEntry` findings on hosts whose tasks are actually healthy. Root cause: some `TaskCache\Tree` "Id" values carry a stray **ignorable character** (for example a zero-width space) after the GUID. The registry and PowerShell hashtables (culture-aware) ignore such characters, but a .NET `HashSet` keyed with `OrdinalIgnoreCase` treats them as significant. GUID comparison through that `HashSet` therefore failed to match the clean `TaskCache\Tasks\{GUID}` subkey names. On the machine that surfaced this, `Get-TaskCacheSummary` reported 197 of 213 Tree nodes as orphaned, but a direct `Test-Path` check confirmed 187 of them **do** have their Tasks key - the tasks were healthy; the comparison was wrong. Fix: normalize GUIDs by extracting the canonical 8-4-4-4-12 hex pattern with a regex, which discards any surrounding or embedded stray characters before comparison. - `Get-TaskCacheSummary.ps1` - `Format-Guid` now regex-extracts the canonical GUID. - `Test-ScheduledTaskHealth.ps1` - adds `ConvertTo-CanonicalGuid` and applies it when reading Tree Id values and Tasks subkey names. `OrphanTaskEntry` findings keep the real subkey name for the backup/removal registry paths. ## How was this tested? - [x] Parser validation - 0 errors for both scripts - [x] Reproduced the bug with a fixture whose Tree Ids carry a trailing zero-width space: before the fix the string comparison failed; after the fix both scripts report zero false orphans. - [x] Regression: genuinely orphaned Tree entries (no Tasks key) and orphaned Tasks entries (no Tree node) are still detected. ## Checklist - [x] I have read the [Contributing Guide](../CONTRIBUTING.md) - [x] Changes are focused - one logical change per PR - [x] Comment-based help updated for any changed parameters or behavior - [x] Documentation updated (if user-visible behavior changed) - [x] No commented-out code or debug leftovers
Some TaskCache\Tree 'Id' values carry a stray ignorable character (e.g. a zero-width
space) after the GUID. The registry and PowerShell hashtables (culture-aware) ignore
such characters, but a .NET HashSet keyed with OrdinalIgnoreCase treats them as
significant. GUID comparison via that HashSet therefore failed to match the clean
TaskCache\Tasks\{GUID} subkey names, producing a large batch of false OrphanTreeEntry
findings (observed: 197 of 213 on a host whose tasks were actually healthy).

Normalize GUIDs by extracting the canonical 8-4-4-4-12 hex pattern with a regex, which
discards any surrounding or embedded stray characters before comparison:

- Get-TaskCacheSummary.ps1: Format-Guid now regex-extracts the canonical GUID.
- Test-ScheduledTaskHealth.ps1: add ConvertTo-CanonicalGuid and apply it when reading
  Tree Id values and Tasks subkey names. OrphanTaskEntry findings keep the real subkey
  name for backup/removal paths.

Verified against fixtures: a host with zero-width-space Tree Ids now reports zero false
orphans, while genuinely orphaned Tree and Tasks entries are still detected.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
hannah-vernon/GmsaScheduledTaskTools!6
No description provided.