geenforce: the shadow task actually runs, and says so on disk
Registered fine and never fired once. Three faults, all found on the win11 VM. A `-Once -At (Get-Date)` trigger does NOT run immediately: its first run is the start boundary PLUS the repetition interval, 15 minutes out. This ships as a DetectionMethod=Always entry, so it ran every enforce cycle, 5 minutes apart, and each Register-ScheduledTask -Force reset the start boundary to "now" - pushing the first run back to +15 before the previous +15 could elapse. 5 < 15, so the task sat Ready at LastTaskResult 267011 (SCHED_S_TASK_HAS_NOT_RUN) forever. It now registers only when the task is missing or its arguments changed, and starts it once on first registration rather than waiting out the first interval. A bay provisioned by the broken version carries a task with correct arguments that has never run, so "leave it alone if it matches" would have stranded exactly the machines that hit the bug. If the task has never run it is kicked once; after that LastRunTime is set and the check is a no-op. None of this was visible. The engine records only "ps1: <path>" and an exit code for a PS1 entry, so Write-Host reached nothing, and with the fail-safe `exit 0` on every path a silent early-out was indistinguishable from success. It now also writes C:\Logs\Shopfloor\shadow-setup-<date>.log. Scope is no longer hardcoded either: this script is shipped by more than one scope now, and a wrong value would shadow the wrong manifest silently. It is derived from the script's own directory, the same way the share manifest path already was, so the two cannot disagree.
This commit is contained in:
@@ -20,12 +20,28 @@ $ErrorActionPreference = 'Continue'
|
||||
$TaskName = 'ShopDB GE-Enforce (shadow)'
|
||||
$InstallDir = 'C:\Program Files\GE\Shopfloor'
|
||||
$BaseUrl = 'https://tsgwp00525.wjs.geaerospace.net/shopdb'
|
||||
$Scope = 'gea-shopfloor-nocollections'
|
||||
# Scope is NOT hardcoded: this script is shipped by more than one scope
|
||||
# (collections and nocollections today), and a wrong value here would shadow the
|
||||
# wrong manifest silently. It runs from <drive>:\<scope>\shopdb-client, so the
|
||||
# directory it sits under IS the scope name - the same derivation used below for
|
||||
# the share manifest, so the two cannot disagree.
|
||||
$Scope = Split-Path -Leaf (Split-Path -Parent $PSScriptRoot)
|
||||
|
||||
function Write-ShadowLog {
|
||||
# Write-Host ALONE is not enough: the engine records only "ps1: <path>" and
|
||||
# the exit code for a PS1 entry, so nothing this script says reaches the
|
||||
# enforce log. Combined with the fail-safe `exit 0` on every path, a silent
|
||||
# early-out was indistinguishable from success - which is exactly how the
|
||||
# never-firing task went unnoticed. Write to a file as well so the next
|
||||
# failure is answerable from disk.
|
||||
param([string]$Message)
|
||||
$line = "[{0}] [shadow-setup] {1}" -f (Get-Date -Format 'yyyy-MM-dd HH:mm:ss'), $Message
|
||||
Write-Host $line
|
||||
try {
|
||||
$dir = 'C:\Logs\Shopfloor'
|
||||
if (-not (Test-Path $dir)) { New-Item -ItemType Directory -Path $dir -Force | Out-Null }
|
||||
Add-Content -LiteralPath (Join-Path $dir ('shadow-setup-{0}.log' -f (Get-Date -Format yyyyMMdd))) -Value $line
|
||||
} catch { }
|
||||
}
|
||||
|
||||
try {
|
||||
@@ -60,6 +76,37 @@ try {
|
||||
$arguments = '-NoProfile -ExecutionPolicy Bypass -File "{0}" -Scope "{1}" -EnginePath "{2}" -ShadowMode -ShareManifestPath "{3}"' `
|
||||
-f $runner, $Scope, $engine, $shareManifest
|
||||
|
||||
# ONLY register when it is missing or its arguments changed.
|
||||
#
|
||||
# Registering unconditionally is what stopped this working the first time.
|
||||
# A `-Once -At (Get-Date)` trigger does NOT fire immediately: the first run
|
||||
# is start-boundary PLUS the repetition interval, so 15 minutes out. This
|
||||
# entry is DetectionMethod=Always and runs every enforce cycle, 5 minutes
|
||||
# apart, and each Register-ScheduledTask -Force reset the start boundary to
|
||||
# "now" - pushing the first run back to +15 before the previous +15 could
|
||||
# elapse. 5 < 15, so the task sat at Ready with LastTaskResult 267011
|
||||
# (SCHED_S_TASK_HAS_NOT_RUN) indefinitely. Measured on the win11 VM.
|
||||
$existing = Get-ScheduledTask -TaskName $TaskName -ErrorAction SilentlyContinue
|
||||
if ($existing) {
|
||||
$currentArgs = ($existing.Actions | Select-Object -First 1).Arguments
|
||||
if ($currentArgs -eq $arguments) {
|
||||
# Correct arguments, but a bay provisioned by the BROKEN version of
|
||||
# this script carries a task that was reset every cycle and so has
|
||||
# never run. Leaving it alone would strand exactly the bays that hit
|
||||
# the bug. Kick it once; after that LastRunTime is set and this is a
|
||||
# no-op forever.
|
||||
$info = $existing | Get-ScheduledTaskInfo
|
||||
$neverran = ($null -eq $info.LastRunTime) -or
|
||||
($info.LastRunTime -lt (Get-Date '2000-01-01'))
|
||||
if ($neverran) {
|
||||
Write-ShadowLog ("task exists but has never run (LastTaskResult $($info.LastTaskResult)) - starting it once.")
|
||||
Start-ScheduledTask -TaskName $TaskName -ErrorAction SilentlyContinue
|
||||
}
|
||||
return # schedule is correct; do not reset the start boundary
|
||||
}
|
||||
Write-ShadowLog 'task arguments changed - re-registering.'
|
||||
}
|
||||
|
||||
$action = New-ScheduledTaskAction -Execute 'powershell.exe' -Argument $arguments
|
||||
# RepetitionInterval ALONE - passing RepetitionDuration serializes to a
|
||||
# Duration the Task Scheduler schema rejects.
|
||||
@@ -69,6 +116,9 @@ try {
|
||||
|
||||
Register-ScheduledTask -TaskName $TaskName -Action $action -Trigger $trigger `
|
||||
-Principal $principal -Settings $settings -Force | Out-Null
|
||||
# Kick it once rather than waiting out the first 15-minute interval, so a
|
||||
# freshly provisioned bay reports on this cycle instead of the next.
|
||||
Start-ScheduledTask -TaskName $TaskName -ErrorAction SilentlyContinue
|
||||
Write-ShadowLog "registered '$TaskName' (every 15 min), shadowing $shareManifest"
|
||||
exit 0
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user