Files
Mike Swanson e75ddfbc53 sync: auto-sync from DESKTOP-0O8A1RL at 2026-05-12 07:04:17
Author: Mike Swanson
Machine: DESKTOP-0O8A1RL
Timestamp: 2026-05-12 07:04:17
2026-05-12 07:04:18 -07:00

169 lines
6.1 KiB
PowerShell

# Dataforth Test Datasheet Uploader (daily)
$ErrorActionPreference = 'Stop'
$prod = 'C:\ProgramData\dataforth-uploader'
$logDir = Join-Path $prod 'logs'
$uploadLogDir = Join-Path $prod 'upload-logs'
$nodeExe = 'C:\Program Files\nodejs\node.exe'
New-Item -ItemType Directory -Force -Path $logDir | Out-Null
$stamp = Get-Date -Format 'yyyy-MM-dd_HH-mm-ss'
$log = Join-Path $logDir "pipeline-$stamp.log"
$graphCreds = $null
function Log([string]$m) {
$line = "[$(Get-Date -Format o)] $m"
Write-Host $line
Add-Content -Path $log -Value $line -Encoding utf8
}
function SendEmail([string]$Subject, [string]$Body) {
if ($null -eq $graphCreds) { return }
try {
# Acquire Graph token
$tokenBody = @{
grant_type = 'client_credentials'
client_id = $graphCreds.clientId
client_secret = $graphCreds.clientSecret
scope = 'https://graph.microsoft.com/.default'
}
$tokenResp = Invoke-RestMethod `
-Method Post `
-Uri "https://login.microsoftonline.com/$($graphCreds.tenantId)/oauth2/v2.0/token" `
-Body $tokenBody
$token = $tokenResp.access_token
# Send mail via Graph
$mailPayload = @{
message = @{
subject = $Subject
body = @{ contentType = 'Text'; content = $Body }
toRecipients = @(@{ emailAddress = @{ address = 'mike@azcomputerguru.com' } })
from = @{ emailAddress = @{ address = 'sysadmin@dataforth.com' } }
}
} | ConvertTo-Json -Depth 10
Invoke-RestMethod `
-Method Post `
-Uri 'https://graph.microsoft.com/v1.0/users/sysadmin@dataforth.com/sendMail' `
-Headers @{ Authorization = "Bearer $token"; 'Content-Type' = 'application/json' } `
-Body $mailPayload | Out-Null
Log "Email sent: $Subject"
} catch {
Log "WARNING: Email send failed: $_"
}
}
try {
Log "=== pipeline start (pid=$PID) ==="
# Load credentials
$creds = Get-Content (Join-Path $prod 'credentials.json') -Raw | ConvertFrom-Json
$env:CF_TOKEN_URL = $creds.CF_TOKEN_URL
$env:CF_API_BASE = $creds.CF_API_BASE
$env:CF_CLIENT_ID = $creds.CF_CLIENT_ID
$env:CF_CLIENT_SECRET = $creds.CF_CLIENT_SECRET
$env:CF_SCOPE = $creds.CF_SCOPE
if ($creds.GRAPH_TENANT_ID -and $creds.GRAPH_CLIENT_ID -and $creds.GRAPH_CLIENT_SECRET) {
$graphCreds = [PSCustomObject]@{
tenantId = $creds.GRAPH_TENANT_ID
clientId = $creds.GRAPH_CLIENT_ID
clientSecret = $creds.GRAPH_CLIENT_SECRET
}
Log "Graph credentials loaded (app $($creds.GRAPH_CLIENT_ID))"
} else {
Log "WARNING: GRAPH_TENANT_ID/CLIENT_ID/CLIENT_SECRET not in credentials.json — email notifications disabled"
}
# [1] DFWDS process
Log '[1] dfwds-process.js'
$dfwdsJs = Join-Path $prod 'dfwds-process.js'
$out = & $nodeExe $dfwdsJs 2>&1
$out | ForEach-Object { Log $_ }
# [2] Enumerate For_Web
Log '[2] enumerate For_Web'
$delta = Join-Path $prod 'delta_for_web_all.txt'
Get-ChildItem 'C:\Shares\webshare\For_Web' -File -Filter *.TXT |
ForEach-Object {
$sn = [System.IO.Path]::GetFileNameWithoutExtension($_.Name)
"$sn|$($_.FullName)|$($_.Length)|$($_.LastWriteTime.ToString('o'))"
} | Set-Content -Path $delta -Encoding ASCII
$count = (Get-Content $delta).Count
Log " enumerated $count files"
# [3] Upload via Node
Log '[3] upload-delta.js'
$uploadJs = Join-Path $prod 'upload-delta.js'
$out = & $nodeExe $uploadJs --delta $delta --batch 100 2>&1
$out | ForEach-Object { Log $_ }
# [4] Daily summary email
Log '[4] sending daily summary email'
if ($graphCreds) {
try {
# Parse totals from most recent upload log; default to zeros if not found
$totals = [PSCustomObject]@{ received=0; created=0; updated=0; unchanged=0; errors=0 }
$latestUploadLog = Get-ChildItem $uploadLogDir -Filter '*.log' -ErrorAction SilentlyContinue |
Sort-Object LastWriteTime -Descending | Select-Object -First 1
if ($latestUploadLog) {
$totalsLine = Get-Content $latestUploadLog.FullName -ErrorAction SilentlyContinue |
Where-Object { $_ -match '^# totals ' } | Select-Object -Last 1
if ($totalsLine) {
$totals = ($totalsLine -replace '^# totals\s*','') | ConvertFrom-Json
}
}
$status = if ($totals.errors -eq 0) { 'OK' } else { 'FAIL' }
$dateStr = Get-Date -Format 'yyyy-MM-dd'
$summaryBody = @"
Dataforth test datasheet daily pipeline completed on $env:COMPUTERNAME.
Time: $(Get-Date -Format o)
Files processed : $($totals.received)
Created (new on website) : $($totals.created)
Updated (refreshed) : $($totals.updated)
Unchanged : $($totals.unchanged)
Errors : $($totals.errors)
Log: $($latestUploadLog.FullName)
"@
SendEmail "[TestDataDB] Daily pipeline $status$dateStr" $summaryBody
} catch {
Log "WARNING: Summary email failed: $_"
}
} else {
Log ' Graph credentials not configured — skipping summary email'
}
Log '=== pipeline end (OK) ==='
} catch {
Log "FATAL: $_"
Log "StackTrace: $($_.ScriptStackTrace)"
$date = Get-Date -Format 'yyyy-MM-dd'
$host_ = $env:COMPUTERNAME
$errBody = @"
Host: $host_
Time: $(Get-Date -Format o)
Date: $date
FATAL ERROR
-----------
$_
Stack Trace
-----------
$($_.ScriptStackTrace)
Log file: $log
"@
SendEmail "[TestDataDB] PIPELINE FAILURE — $date" $errBody
throw
} finally {
# Retention: keep 60 days of pipeline logs
Get-ChildItem $logDir -Filter 'pipeline-*.log' -ErrorAction SilentlyContinue |
Where-Object { $_.LastWriteTime -lt (Get-Date).AddDays(-60) } |
Remove-Item -Force -ErrorAction SilentlyContinue
}