Public Access
Add report.bat to collect diagnostics, and a VERSION.txt stamp
Nothing in this repo ever updated Melissa's PC, so "it isn't working" could not be told apart from "she is running last month's copy" - which is what it turned out to be today. report.bat writes one text file to the Desktop with the installed version, which files are present, whether WinSCPnet.dll loads or is blocked, every entity.json (passwords masked to ********), what is actually sitting in today's date folders, and the tail of the last log. A missing VERSION.txt is itself the answer: it means the copy predates 2026-08-26 and has no setup wizard.
This commit is contained in:
@@ -11,3 +11,6 @@ WinSCP/
|
||||
# Keep example templates
|
||||
!Entities/EXAMPLE/entity.json
|
||||
!Entities/EXAMPLE/Export1/PRACTICE_NAME/practice.json
|
||||
|
||||
# Version stamp - report.bat uses this to tell which build is installed
|
||||
!VERSION.txt
|
||||
|
||||
+173
@@ -0,0 +1,173 @@
|
||||
# Collects everything needed to diagnose "it isn't working" into one text file
|
||||
# on the Desktop. Passwords are masked. Called by report.bat.
|
||||
|
||||
$scriptRoot = Split-Path -Parent $PSCommandPath
|
||||
$stamp = Get-Date -Format "yyyyMMdd-HHmm"
|
||||
$desktop = [Environment]::GetFolderPath("Desktop")
|
||||
if (-not $desktop) { $desktop = $scriptRoot }
|
||||
$outFile = Join-Path $desktop "MelissaUploader-Report-$stamp.txt"
|
||||
|
||||
$lines = New-Object System.Collections.ArrayList
|
||||
function Add-Line($text) { [void]$lines.Add([string]$text) }
|
||||
function Add-Head($text) {
|
||||
Add-Line ""
|
||||
Add-Line ("=" * 60)
|
||||
Add-Line " $text"
|
||||
Add-Line ("=" * 60)
|
||||
}
|
||||
|
||||
Add-Line "Melissa Uploader report"
|
||||
Add-Line "Taken : $(Get-Date -Format 'yyyy-MM-dd HH:mm:ss')"
|
||||
Add-Line "PC : $env:COMPUTERNAME"
|
||||
Add-Line "User : $env:USERNAME"
|
||||
Add-Line "Folder : $scriptRoot"
|
||||
Add-Line "Windows : $([Environment]::OSVersion.VersionString)"
|
||||
Add-Line "PowerShell: $($PSVersionTable.PSVersion)"
|
||||
|
||||
# -- Which version of the tool is installed -----------------------------------
|
||||
Add-Head "Version"
|
||||
$versionFile = Join-Path $scriptRoot "VERSION.txt"
|
||||
if (Test-Path $versionFile) {
|
||||
Add-Line "VERSION.txt: $((Get-Content $versionFile -Raw).Trim())"
|
||||
} else {
|
||||
Add-Line "VERSION.txt: MISSING"
|
||||
Add-Line ">> This copy is older than 2026-08-26. It does not have the setup"
|
||||
Add-Line ">> wizard. Whoever maintains this needs to copy the new files over."
|
||||
}
|
||||
|
||||
# -- Which files are present --------------------------------------------------
|
||||
Add-Head "Files in the folder"
|
||||
$expected = @("engine.ps1", "run-all.bat", "run-all.ps1", "run.bat", "setup.bat",
|
||||
"setup-entity.bat", "Setup-Entity.ps1", "Get-WinSCP.ps1", "Get-Report.ps1")
|
||||
foreach ($name in $expected) {
|
||||
$path = Join-Path $scriptRoot $name
|
||||
if (Test-Path $path) {
|
||||
$item = Get-Item $path
|
||||
Add-Line (" {0,-20} {1} {2,8} bytes" -f $name, $item.LastWriteTime.ToString("yyyy-MM-dd HH:mm"), $item.Length)
|
||||
} else {
|
||||
Add-Line (" {0,-20} MISSING" -f $name)
|
||||
}
|
||||
}
|
||||
|
||||
# -- WinSCP -------------------------------------------------------------------
|
||||
Add-Head "WinSCP"
|
||||
$winscpDll = Join-Path $scriptRoot "WinSCP\WinSCPnet.dll"
|
||||
if (-not (Test-Path $winscpDll)) {
|
||||
Add-Line "WinSCPnet.dll MISSING - setup.bat has not been run (or it failed)."
|
||||
} else {
|
||||
$dll = Get-Item $winscpDll
|
||||
Add-Line "WinSCPnet.dll found: $($dll.Length) bytes, $($dll.LastWriteTime)"
|
||||
$zone = Get-Item $winscpDll -Stream Zone.Identifier -ErrorAction SilentlyContinue
|
||||
if ($zone) {
|
||||
Add-Line "BLOCKED by Windows (Mark of the Web) - engine.ps1 unblocks this itself on every run."
|
||||
} else {
|
||||
Add-Line "Not blocked."
|
||||
}
|
||||
try {
|
||||
Add-Type -Path $winscpDll -ErrorAction Stop
|
||||
Add-Line "Loads OK."
|
||||
} catch {
|
||||
Add-Line "WILL NOT LOAD: $($_.Exception.Message)"
|
||||
}
|
||||
}
|
||||
|
||||
# -- Entities -----------------------------------------------------------------
|
||||
Add-Head "Entities"
|
||||
$entitiesDir = Join-Path $scriptRoot "Entities"
|
||||
if (-not (Test-Path $entitiesDir)) {
|
||||
Add-Line "No Entities\ folder at all."
|
||||
} else {
|
||||
$entities = @(Get-ChildItem -Path $entitiesDir -Directory | Where-Object { $_.Name -ne "EXAMPLE" })
|
||||
if ($entities.Count -eq 0) { Add-Line "Entities\ exists but is empty." }
|
||||
|
||||
foreach ($entity in $entities) {
|
||||
Add-Line ""
|
||||
Add-Line ("-- $($entity.Name) " + ("-" * 40))
|
||||
$configFile = Join-Path $entity.FullName "entity.json"
|
||||
if (-not (Test-Path $configFile)) {
|
||||
Add-Line " entity.json MISSING - this entity is skipped by run-all."
|
||||
} else {
|
||||
$raw = Get-Content $configFile -Raw
|
||||
# Mask anything that looks like a password before this leaves the PC.
|
||||
$masked = $raw -replace '("password"\s*:\s*")[^"]*(")', '$1********$2'
|
||||
Add-Line " entity.json:"
|
||||
foreach ($l in ($masked -split "`r?`n")) { Add-Line " $l" }
|
||||
|
||||
try {
|
||||
$raw | ConvertFrom-Json | Out-Null
|
||||
Add-Line " Reads as valid JSON."
|
||||
} catch {
|
||||
Add-Line " *** THIS FILE IS NOT VALID JSON *** $($_.Exception.Message)"
|
||||
}
|
||||
}
|
||||
|
||||
$export1 = Join-Path $entity.FullName "Export1"
|
||||
if (-not (Test-Path $export1)) {
|
||||
Add-Line " No Export1\ folder."
|
||||
continue
|
||||
}
|
||||
|
||||
$today = Get-Date -Format "yyyyMMdd"
|
||||
foreach ($practice in (Get-ChildItem -Path $export1 -Directory)) {
|
||||
$dateDir = Join-Path $practice.FullName $today
|
||||
if (Test-Path $dateDir) {
|
||||
$files = @(Get-ChildItem -Path $dateDir -File)
|
||||
$byExt = ($files | Group-Object Extension |
|
||||
ForEach-Object { "$($_.Count)x $($_.Name)" }) -join ", "
|
||||
if (-not $byExt) { $byExt = "empty" }
|
||||
Add-Line " $($practice.Name): $today\ has $($files.Count) file(s) - $byExt"
|
||||
} else {
|
||||
Add-Line " $($practice.Name): no $today\ folder"
|
||||
}
|
||||
$pj = Join-Path $practice.FullName "practice.json"
|
||||
if (Test-Path $pj) {
|
||||
$pmasked = (Get-Content $pj -Raw) -replace '("password"\s*:\s*")[^"]*(")', '$1********$2'
|
||||
Add-Line " practice.json: $($pmasked -replace '\s+', ' ')"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# -- Logs ---------------------------------------------------------------------
|
||||
Add-Head "Most recent log"
|
||||
$logsDir = Join-Path $scriptRoot "Logs"
|
||||
if (-not (Test-Path $logsDir)) {
|
||||
Add-Line "No Logs\ folder - engine.ps1 has never completed a run here."
|
||||
} else {
|
||||
$log = Get-ChildItem -Path $logsDir -Filter "*.log" |
|
||||
Where-Object { $_.Name -notmatch "winscp_debug" } |
|
||||
Sort-Object LastWriteTime -Descending | Select-Object -First 1
|
||||
if (-not $log) {
|
||||
Add-Line "Logs\ is empty."
|
||||
} else {
|
||||
Add-Line "$($log.Name) (last written $($log.LastWriteTime))"
|
||||
Add-Line ""
|
||||
$content = Get-Content $log.FullName -Tail 120
|
||||
foreach ($l in $content) { Add-Line " $l" }
|
||||
}
|
||||
}
|
||||
|
||||
Add-Head "End of report"
|
||||
|
||||
# -- Write it out -------------------------------------------------------------
|
||||
$text = $lines -join "`r`n"
|
||||
try {
|
||||
Set-Content -Path $outFile -Value $text -Encoding UTF8
|
||||
$saved = $true
|
||||
} catch {
|
||||
$outFile = Join-Path $scriptRoot "MelissaUploader-Report-$stamp.txt"
|
||||
Set-Content -Path $outFile -Value $text -Encoding UTF8
|
||||
$saved = $true
|
||||
}
|
||||
|
||||
Write-Host $text
|
||||
Write-Host ""
|
||||
Write-Host ("=" * 60) -ForegroundColor Cyan
|
||||
if ($saved) {
|
||||
Write-Host "Report saved to:" -ForegroundColor Green
|
||||
Write-Host " $outFile" -ForegroundColor Green
|
||||
Write-Host ""
|
||||
Write-Host "Send that file to Brad - it has everything needed to work out" -ForegroundColor Cyan
|
||||
Write-Host "what went wrong. Passwords are replaced with ******** in it." -ForegroundColor Cyan
|
||||
}
|
||||
Write-Host ("=" * 60) -ForegroundColor Cyan
|
||||
@@ -0,0 +1 @@
|
||||
63ea071 2026-08-26 setup wizard
|
||||
@@ -0,0 +1,4 @@
|
||||
@echo off
|
||||
REM Collects what's needed to diagnose a problem into a text file on the Desktop.
|
||||
powershell.exe -ExecutionPolicy Bypass -File "%~dp0Get-Report.ps1"
|
||||
pause
|
||||
Reference in New Issue
Block a user