From 18168b54f85ff972ffed69f73000ebdd9d13ef25 Mon Sep 17 00:00:00 2001 From: cproudlock Date: Tue, 25 Aug 2026 13:32:23 -0400 Subject: [PATCH] Say why a share write failed, because the symptom lies This runs as SYSTEM, which authenticates to the network as the machine account. A SYSTEM process reaching a UNC path without credentials gets an access-denied that Test-Path reports as "not found", so a permissions problem reads as a missing directory and sends the next person hunting the wrong thing. The backups registry already carries that warning; the client had not acted on it. On a write failure the log now names the likely cause, and the two conditions that make it work: the entry must run under the GE-Enforce cycle, since the share is mounted only for its duration and all SYSTEM processes share the logon session that holds the connection, and the share ACL has to admit computer accounts. Verified against an unreachable UNC on a bay with a real controller: capture succeeded, the write failed, the diagnostic was logged and the cycle was counted as a missed backup. --- .../common/scripts/Backup-PartMarker.ps1 | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/playbook/shopfloor-setup/common/scripts/Backup-PartMarker.ps1 b/playbook/shopfloor-setup/common/scripts/Backup-PartMarker.ps1 index 95f139a..957f3cd 100644 --- a/playbook/shopfloor-setup/common/scripts/Backup-PartMarker.ps1 +++ b/playbook/shopfloor-setup/common/scripts/Backup-PartMarker.ps1 @@ -390,6 +390,26 @@ try { # exactly the kind of quiet breakage this count exists to surface. Add-ShopdbBackupSkip -Kind $KIND -Reason 'could not write to the share' Write-ShopdbBackupLog -Kind $KIND -Message "Could not write $snapshotdir : $_" + + # Name the likely cause, because the symptom lies. This runs as SYSTEM, + # which authenticates to the network as the MACHINE account, and a SYSTEM + # process reaching a UNC path with no credentials gets an access-denied + # that Test-Path reports as "not found" - so a permissions problem looks + # like a missing directory and sends the next person hunting the wrong + # thing entirely. + # + # The share is mounted only during the GE-Enforce cycle, and all SYSTEM + # processes share one logon session, so a manifest entry inherits that + # connection. A scheduled task would not - it would run outside the cycle + # and find nothing there. + if (-not (Test-Path -LiteralPath $ShareRoot)) { + Write-ShopdbBackupLog -Kind $KIND -Message ( + "$ShareRoot is not reachable from this process. Running as SYSTEM, " + + 'so this is usually the machine account lacking rights on the share ' + + 'rather than a missing path - Test-Path cannot tell the two apart. ' + + 'Confirm this runs as a GE-Enforce manifest entry (the share is ' + + 'mounted only during the cycle) and that the ACL admits computer accounts.') + } exit 0 }