CMM first-run-as-admin, controller credential user-context fix, IE compat hash

09-Setup-CMM: add Step 2.6 that launches each installed PC-DMIS
version once as admin before the PPKG locks the machine down. Also
adds PC-DMIS 2026.1 to the ACL directory list.

Controller credential: cmdkey /add under SYSTEM stored creds in the
wrong vault. Switch to a Register script (MarkerFile detection, runs
once) that creates an AtLogOn scheduled task under BUILTIN\Users so
cmdkey runs in the ShopFloor user's session.

IE compat: update test matrix hash for the new site list that adds
wjfms3.apps.wlm.geaerospace.net.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
cproudlock
2026-05-27 07:03:32 -04:00
parent 5c3db71879
commit 55c1ab4814
4 changed files with 141 additions and 8 deletions

View File

@@ -0,0 +1,98 @@
# Register-ControllerCredentialTask.ps1 - Register a user-context AtLogOn
# scheduled task that runs Set-ControllerCredential.ps1 as the logged-in
# user (ShopFloor). Credential Manager entries are per-user, so cmdkey /add
# must run in the user's session, not SYSTEM.
#
# GE-Enforce (SYSTEM) runs THIS script via the manifest. It registers the
# task once (MarkerFile detection prevents re-registration on subsequent
# enforce cycles). The task itself fires at every logon and re-applies the
# credential, covering Defender / Intune scrubs between sessions.
#
# Idempotent: safe to re-run. Existing task is overwritten via -Force.
$ErrorActionPreference = 'Continue'
$logDir = 'C:\Logs\Shopfloor'
if (-not (Test-Path $logDir)) {
try { New-Item -Path $logDir -ItemType Directory -Force | Out-Null } catch { $logDir = $env:TEMP }
}
$logFile = Join-Path $logDir 'register-controller-cred.log'
function Write-RegLog {
param([string]$Message, [string]$Level = 'INFO')
$line = '[{0}] [{1}] {2}' -f (Get-Date -Format 'yyyy-MM-dd HH:mm:ss'), $Level, $Message
Add-Content -Path $logFile -Value $line -ErrorAction SilentlyContinue
Write-Host $line
}
Write-RegLog '=== Register-ControllerCredentialTask start ==='
$taskName = 'Apply Controller Credential'
# The actual cmdkey script lives alongside this registration script on the
# SFLD share. GE-Enforce mounts the share as W:, so the script path is
# relative to the share root. At task-fire time, however, the share may not
# be mounted. Copy the script to a local path so the logon task always works.
$localDir = 'C:\Program Files\GE\Shopfloor\controller-cred'
$localScript = Join-Path $localDir 'Set-ControllerCredential.ps1'
# Resolve the source script. When GE-Enforce runs this, $PSScriptRoot
# points to the share-mounted dir (W:\gea-shopfloor-collections\apps\ or
# similar). Fall back to the same directory as this script.
$sourceScript = Join-Path $PSScriptRoot 'Set-ControllerCredential.ps1'
if (-not (Test-Path -LiteralPath $sourceScript)) {
Write-RegLog "Set-ControllerCredential.ps1 not found at $sourceScript" 'ERROR'
exit 1
}
# Stage the script locally.
if (-not (Test-Path $localDir)) {
New-Item -Path $localDir -ItemType Directory -Force | Out-Null
}
try {
Copy-Item -LiteralPath $sourceScript -Destination $localScript -Force -ErrorAction Stop
Write-RegLog "Staged $sourceScript -> $localScript"
} catch {
Write-RegLog "Failed to copy script locally: $_" 'ERROR'
exit 1
}
# Register the logon task for BUILTIN\Users (catches ShopFloor + any
# interactive user). RunLevel Limited -- no elevation needed for cmdkey.
try {
$action = New-ScheduledTaskAction `
-Execute 'powershell.exe' `
-Argument "-NoProfile -ExecutionPolicy Bypass -WindowStyle Hidden -File `"$localScript`""
$trigger = New-ScheduledTaskTrigger -AtLogOn
$principal = New-ScheduledTaskPrincipal -GroupId 'S-1-5-32-545' -RunLevel Limited
$settings = New-ScheduledTaskSettingsSet `
-AllowStartIfOnBatteries `
-DontStopIfGoingOnBatteries `
-StartWhenAvailable `
-ExecutionTimeLimit (New-TimeSpan -Minutes 2)
Register-ScheduledTask `
-TaskName $taskName `
-Action $action `
-Trigger $trigger `
-Principal $principal `
-Settings $settings `
-Force `
-ErrorAction Stop | Out-Null
Write-RegLog "Registered scheduled task '$taskName' (AtLogOn, BUILTIN\Users, Limited)"
} catch {
Write-RegLog "FAILED to register '$taskName': $_" 'ERROR'
exit 1
}
# Write marker file so the manifest's MarkerFile detection prevents
# re-running this registration on every enforce cycle.
$markerDir = 'C:\ProgramData\GE\Shopfloor\markers'
if (-not (Test-Path $markerDir)) {
New-Item -Path $markerDir -ItemType Directory -Force | Out-Null
}
$markerFile = Join-Path $markerDir 'controller-credential-task.marker'
Set-Content -Path $markerFile -Value (Get-Date -Format 'yyyy-MM-dd HH:mm:ss') -Force
Write-RegLog "Marker written: $markerFile"
Write-RegLog '=== Register-ControllerCredentialTask end ==='
exit 0

View File

@@ -1,8 +1,10 @@
{
"_comment": "Drop this entry into the SFLD share at \\tsgwp00525\\sfld$\\v2\\shared\\dt\\shopfloor\\gea-shopfloor-collections\\manifest.json (Applications array). Edit Set-ControllerCredential.ps1 first to fill in the real $Username + $Password before pushing the script + manifest. Detection is omitted on purpose: Install-FromManifest treats missing DetectionMethod as 'not installed' and runs the script every enforce cycle, which is exactly what we want (Defender / Intune occasionally scrubs the entry; we re-apply on each cycle). cmdkey /add is idempotent so re-running is harmless. TargetMachineNumbers is optional; remove it to apply to every collections bay, or list specific machine numbers to scope down.",
"Name": "Controller credential for Okuma LOC650 bays (192.168.1.1)",
"_comment": "Drop this entry into the SFLD share at \\tsgwp00525\\sfld$\\v2\\shared\\dt\\shopfloor\\gea-shopfloor-collections\\manifest.json (Applications array). Place both Register-ControllerCredentialTask.ps1 AND Set-ControllerCredential.ps1 in the apps/ dir on the share. Edit Set-ControllerCredential.ps1 to fill in the real $Username + $Password before pushing. The Register script runs once under SYSTEM (MarkerFile detection), copies Set-ControllerCredential.ps1 locally, and creates an AtLogOn scheduled task that runs cmdkey /add in the ShopFloor user's session. The task re-applies every logon, covering Defender / Intune credential scrubs.",
"Name": "Controller credential task for Okuma LOC650 bays (192.168.1.1)",
"PCTypes": ["gea-shopfloor-collections"],
"TargetMachineNumbers": ["3201", "3202", "3203", "3204", "3205", "3206", "3207", "3208", "3209", "3210", "3211", "3212"],
"Script": "apps/Set-ControllerCredential.ps1",
"Type": "PS1"
"Script": "apps/Register-ControllerCredentialTask.ps1",
"Type": "PS1",
"DetectionMethod": "MarkerFile",
"DetectionPath": "C:\\ProgramData\\GE\\Shopfloor\\markers\\controller-credential-task.marker"
}