From 5eacd1d59695823eff60c097447ed983f0975d50 Mon Sep 17 00:00:00 2001 From: cproudlock Date: Thu, 9 Apr 2026 11:19:45 -0400 Subject: [PATCH] PreInstall runner: surface installer log on EXE failures (LogFile field) When the runner runs a Type:MSI install it injects /L*v and tails that log on failure to show what actually went wrong. Type:EXE installs had no equivalent - if Setup-OpenText.cmd or any other EXE wrapper failed, the installlog just showed "Exit code 1 - FAILED" with no clue what happened inside. Adds an optional LogFile field to JSON entries. When present on a Type:EXE entry, the runner: - Logs "Installer log: " before launching the installer - On failure, tails the last 30 lines of that file into the runner log (same pattern as the MSI verbose log scan) Wired up on the OpenText entry to point at C:\Logs\PreInstall\Setup- OpenText.log (which Setup-OpenText.ps1 already writes itself). Other EXE entries can opt in by adding their own LogFile field. Co-Authored-By: Claude Opus 4.6 (1M context) --- playbook/preinstall/preinstall.json | 1 + .../Shopfloor/00-PreInstall-MachineApps.ps1 | 21 +++++++++++++++++++ 2 files changed, 22 insertions(+) diff --git a/playbook/preinstall/preinstall.json b/playbook/preinstall/preinstall.json index 9c14904..5b8a004 100644 --- a/playbook/preinstall/preinstall.json +++ b/playbook/preinstall/preinstall.json @@ -96,6 +96,7 @@ "Installer": "opentext\\Setup-OpenText.cmd", "Type": "EXE", "InstallArgs": "", + "LogFile": "C:\\Logs\\PreInstall\\Setup-OpenText.log", "PCTypes": ["Standard"] }, { diff --git a/playbook/shopfloor-setup/Shopfloor/00-PreInstall-MachineApps.ps1 b/playbook/shopfloor-setup/Shopfloor/00-PreInstall-MachineApps.ps1 index de75a5d..88f6e6b 100644 --- a/playbook/shopfloor-setup/Shopfloor/00-PreInstall-MachineApps.ps1 +++ b/playbook/shopfloor-setup/Shopfloor/00-PreInstall-MachineApps.ps1 @@ -218,6 +218,14 @@ foreach ($app in $config.Applications) { if ($app.InstallArgs) { $psi.Arguments = $app.InstallArgs } + # If the JSON entry specifies a LogFile (per-installer log written by + # the EXE itself - e.g. Setup-OpenText.ps1 -> C:\Logs\PreInstall\Setup- + # OpenText.log), surface it on failure the same way we surface the + # msiexec /L*v verbose log for MSI installs. Lets EXE wrappers actually + # report what went wrong inside. + if ($app.LogFile) { + Write-PreInstallLog " Installer log: $($app.LogFile)" + } } else { Write-PreInstallLog " Unsupported Type: $($app.Type) - skipping" "ERROR" @@ -292,6 +300,19 @@ foreach ($app in $config.Applications) { } else { Write-PreInstallLog " Exit code $exitCode - FAILED" "ERROR" + + # If the JSON entry specifies a LogFile for an EXE install (e.g. + # Setup-OpenText.ps1 writes its own log at C:\Logs\PreInstall\Setup- + # OpenText.log), tail it here so the runner log surfaces the actual + # cause without us having to dig through C:\Logs manually. + if ($app.Type -eq "EXE" -and $app.LogFile -and (Test-Path $app.LogFile)) { + Write-PreInstallLog " --- last 30 lines of $($app.LogFile) ---" + Get-Content $app.LogFile -Tail 30 -ErrorAction SilentlyContinue | ForEach-Object { + Write-PreInstallLog " $_" + } + Write-PreInstallLog " --- end installer log tail ---" + } + # Surface the *meaningful* lines from the verbose msiexec log (not just # the tail, which is rollback/cleanup noise). The actual root-cause lines # are: MSI error notes (Note: 1: ), failed action returns (return