diff --git a/playbook/shopfloor-setup/Standard/Restore-UDCData.ps1 b/playbook/shopfloor-setup/Standard/Restore-UDCData.ps1 index 30650e2..12aff62 100644 --- a/playbook/shopfloor-setup/Standard/Restore-UDCData.ps1 +++ b/playbook/shopfloor-setup/Standard/Restore-UDCData.ps1 @@ -126,32 +126,42 @@ if (-not $mn -or $mn -eq '9999' -or $mn -notmatch '^\d+$') { exit 0 } -# -- Wait for the share to be reachable --------------------------------- -# When this script runs early in a logon (e.g. via GE-Enforce on autologon), -# the SFLD share via the SMB redirector can take 20-60 seconds to become -# reachable, especially in SYSTEM context where the credential is the -# computer account. Poll until reachable or timeout before deciding "no backup". -Log "Polling share root for reachability: $BackupShareRoot" -$shareReachable = $false +# -- Mount share with SFLD user creds ----------------------------------- +# This script runs as NT AUTHORITY\SYSTEM (manifest engine on logon, or +# scheduled task). SYSTEM authenticates to remote SMB as the COMPUTER +# ACCOUNT (DOMAIN\HOSTNAME$), not as a user. The SFLD share's ACLs grant +# top-level enumeration to authenticated computers but file-level read +# only to a specific SFLD user. Without explicit user creds, Test-Path +# on bay-level files returns False (access denied = same return as not- +# found), making the script silently log "absent" when the files in fact +# exist. Symptom: Restore-UDCData.log shows endless "no work this cycle" +# while another PC (or a user-context invocation) successfully consumes +# the backup. Fix: mount the share with explicit SFLD creds from +# HKLM:\SOFTWARE\GE\SFLD\Credentials and probe via the drive letter. +. (Join-Path $PSScriptRoot '..\Shopfloor\lib\Restore-EDncReg.ps1') + +Log "Mounting share with SFLD creds: $BackupShareRoot -> W:" +$shareMounted = $false $sw = [Diagnostics.Stopwatch]::StartNew() while ($sw.Elapsed.TotalSeconds -lt $ShareTimeoutSec) { - if (Test-Path -LiteralPath $BackupShareRoot) { - $shareReachable = $true + if (Mount-SFLDShare -SharePath $BackupShareRoot -DriveLetter 'W:') { + $shareMounted = $true break } Start-Sleep -Seconds $SharePollSec } $sw.Stop() -if ($shareReachable) { - Log ("Share reachable after {0:N1} s" -f $sw.Elapsed.TotalSeconds) +if ($shareMounted) { + Log ("Share mounted as W: after {0:N1} s" -f $sw.Elapsed.TotalSeconds) } else { - Log "Share NOT reachable after $ShareTimeoutSec s. Cannot probe for backup. Exiting non-zero so the dispatcher logs a failure." 'ERROR' + Log "Mount-SFLDShare failed after $ShareTimeoutSec s. SFLD creds may be missing in HKLM:\SOFTWARE\GE\SFLD\Credentials, or the share is unreachable. Exiting non-zero so the dispatcher logs a failure." 'ERROR' Log 'Exit 1.' exit 1 } -# -- Probe for a waiting backup ------------------------------------------ -$bayDir = Join-Path $BackupShareRoot $mn +# All bay-level paths now go through W: (authenticated as SFLD user) so +# Test-Path returns the truth, not access-denied-False. +$bayDir = Join-Path 'W:\' $mn $srcCur = Join-Path $bayDir 'CurrentData.json' $srcArc = Join-Path $bayDir 'ArchivedData' Log "Probing backup paths for bay $mn" @@ -165,6 +175,7 @@ Log " ArchivedData/ src: $(if ($srcArcExists) { 'present' } else { 'absent' if (-not $srcCurExists -and -not $srcArcExists) { Log "No backup waiting for bay $mn (neither CurrentData.json nor ArchivedData\ at bay root) - no work to do this cycle." + & net use W: /delete /y 2>$null | Out-Null Log 'Exit 0.' exit 0 } @@ -202,6 +213,7 @@ if (-not (Test-Path -LiteralPath $UdcDataDir)) { } catch { Log "Failed to create $UdcDataDir - cannot continue" 'ERROR' LogErr $_ + & net use W: /delete /y 2>$null | Out-Null Log 'Exit 1.' exit 1 } @@ -325,6 +337,9 @@ if ((Test-Path -LiteralPath $UdcExePath) -and ($copiedCur -or $copiedArc)) { } } +# Unmount the SFLD-creds-mounted drive so we don't leave a stale net-use entry +& net use W: /delete /y 2>$null | Out-Null + Log 'Exit 0.' Log '===============================================' exit 0