<# Bootstrap operativo unico per il bridge Panasonic live su Windows. Comandi supportati: - setup : imposta token, pubblica runtime, testa HTTP, installa task e lo avvia - test : esegue solo lo smoke test HTTP verso staging - status : mostra token, cartelle, stato task e ultime righe log - log : segue il log live in tail -wait - stop : ferma il task schedulato Uso rapido: .\bootstrap-netgescon-panasonic-live.ps1 .\bootstrap-netgescon-panasonic-live.ps1 -Action status #> param( [ValidateSet('setup', 'test', 'status', 'log', 'stop', 'dry-run', 'live-run')] [string]$Action = 'setup', [string]$BaseUrl = 'https://staging.netgescon.it', [string]$Token = 'netgescon-cti-test-20260311', [string]$Extensions = '201-208,601,603,0001,0003', [string]$TaskName = 'NetGescon Panasonic Live Bridge', [string]$RuntimeDir = 'C:\ProgramData\NetGescon\panasonic-live\current', [string]$LogFile = '', [string]$InteropOutputDir = '', [switch]$SkipHttpTest ) Set-StrictMode -Version Latest $ErrorActionPreference = 'Stop' function Write-Step { param([string]$Message) Write-Host '' Write-Host ('=== {0} ===' -f $Message) } function Ensure-Directory { param([string]$Path) if ([string]::IsNullOrWhiteSpace($Path)) { return } if (-not (Test-Path $Path)) { New-Item -ItemType Directory -Path $Path -Force | Out-Null } } function Get-ResolvedLogFile { if (-not [string]::IsNullOrWhiteSpace($LogFile)) { return $LogFile } if (-not [string]::IsNullOrWhiteSpace($env:LOCALAPPDATA)) { return (Join-Path $env:LOCALAPPDATA 'NetGescon\Logs\netgescon-tapi-dotnet-events-live.log') } return 'C:\ProgramData\NetGescon\Logs\netgescon-tapi-dotnet-events-live.log' } function Get-ResolvedInteropDir { if (-not [string]::IsNullOrWhiteSpace($InteropOutputDir)) { return $InteropOutputDir } if (-not [string]::IsNullOrWhiteSpace($env:LOCALAPPDATA)) { return (Join-Path $env:LOCALAPPDATA 'NetGescon\tapi-interop') } return 'C:\ProgramData\NetGescon\tapi-interop' } function Get-RepoWindowsOpsRoot { $scriptRoot = $PSScriptRoot $publishScript = Join-Path $scriptRoot 'publish-netgescon-panasonic-runtime.ps1' if (Test-Path $publishScript) { return $scriptRoot } if (Test-Path (Join-Path $RuntimeDir 'publish-netgescon-panasonic-runtime.ps1')) { return $RuntimeDir } throw 'Script publish-netgescon-panasonic-runtime.ps1 non trovato. Lancia il bootstrap dalla cartella scripts\ops\windows del repo.' } function Publish-Runtime { param([string]$SourceRoot) $publishScript = Join-Path $SourceRoot 'publish-netgescon-panasonic-runtime.ps1' if (-not (Test-Path $publishScript)) { throw "Script publish non trovato: $publishScript" } Write-Step 'Publish runtime locale' & powershell.exe -NoProfile -ExecutionPolicy Bypass -File $publishScript -TargetRoot $RuntimeDir } function Test-HttpBridge { $testScript = Join-Path $RuntimeDir 'test-netgescon-panasonic-api.ps1' if (-not (Test-Path $testScript)) { throw "Script test non trovato: $testScript" } Write-Step 'Smoke test HTTP verso staging' & powershell.exe -NoProfile -ExecutionPolicy Bypass -File $testScript -BaseUrl $BaseUrl -Token $Token -Extension '205' } function Install-Task { $installCmd = Join-Path $RuntimeDir 'install-netgescon-panasonic-live-task.cmd' if (-not (Test-Path $installCmd)) { throw "Launcher task non trovato: $installCmd" } Write-Step 'Installazione task' & $installCmd -Mode current-user-logon -BaseUrl $BaseUrl -Extensions $Extensions -LogFile $script:ResolvedLogFile -InteropOutputDir $script:ResolvedInteropDir } function Start-BridgeTask { Write-Step 'Avvio task' Start-ScheduledTask -TaskName $TaskName Start-Sleep -Seconds 2 Get-ScheduledTaskInfo -TaskName $TaskName | Format-List LastRunTime, LastTaskResult, NextRunTime, TaskName } function Stop-BridgeTask { Write-Step 'Stop task' Stop-ScheduledTask -TaskName $TaskName -ErrorAction SilentlyContinue Get-ScheduledTaskInfo -TaskName $TaskName | Format-List LastRunTime, LastTaskResult, NextRunTime, TaskName } function Show-Status { Write-Step 'Stato bridge' Write-Host ('BaseUrl : {0}' -f $BaseUrl) Write-Host ('RuntimeDir : {0}' -f $RuntimeDir) Write-Host ('LogFile : {0}' -f $script:ResolvedLogFile) Write-Host ('InteropDir : {0}' -f $script:ResolvedInteropDir) Write-Host ('Token user : {0}' -f ([Environment]::GetEnvironmentVariable('NETGESCON_CTI_SHARED_TOKEN', 'User'))) try { Get-ScheduledTaskInfo -TaskName $TaskName | Format-List LastRunTime, LastTaskResult, NextRunTime, NumberOfMissedRuns, TaskName } catch { Write-Host ('Task non trovato: {0}' -f $TaskName) } if (Test-Path $script:ResolvedLogFile) { Write-Host '' Write-Host 'Ultime 30 righe log:' Get-Content $script:ResolvedLogFile -Tail 30 } else { Write-Host '' Write-Host 'Log non ancora presente.' } } function Follow-Log { Write-Step 'Follow log live' Ensure-Directory -Path (Split-Path -Parent $script:ResolvedLogFile) if (-not (Test-Path $script:ResolvedLogFile)) { New-Item -ItemType File -Path $script:ResolvedLogFile -Force | Out-Null } Get-Content $script:ResolvedLogFile -Tail 100 -Wait } function Start-DryRunWatcher { $watchScript = Join-Path $RuntimeDir 'watch-netgescon-panasonic-tapi-dotnet-events.ps1' if (-not (Test-Path $watchScript)) { throw "Watcher non trovato: $watchScript" } Write-Step 'Dry-run watcher Panasonic' Write-Host ('Runtime script: {0}' -f $watchScript) Write-Host ('Log file : {0}' -f $script:ResolvedLogFile) Write-Host ('Interop dir : {0}' -f $script:ResolvedInteropDir) & powershell.exe -NoProfile -ExecutionPolicy Bypass -File $watchScript ` -Extensions $Extensions ` -BridgeMode 'dry-run' ` -LogFile $script:ResolvedLogFile ` -InteropOutputDir $script:ResolvedInteropDir ` -IncludeDiagnosticEvents } function Start-LiveWatcher { $watchScript = Join-Path $RuntimeDir 'watch-netgescon-panasonic-tapi-dotnet-events.ps1' if (-not (Test-Path $watchScript)) { throw "Watcher non trovato: $watchScript" } Write-Step 'Live watcher Panasonic' Write-Host ('Runtime script: {0}' -f $watchScript) Write-Host ('BaseUrl : {0}' -f $BaseUrl) Write-Host ('Log file : {0}' -f $script:ResolvedLogFile) Write-Host ('Interop dir : {0}' -f $script:ResolvedInteropDir) & powershell.exe -NoProfile -ExecutionPolicy Bypass -File $watchScript ` -Extensions $Extensions ` -BridgeMode 'live' ` -BaseUrl $BaseUrl ` -Token $Token ` -LogFile $script:ResolvedLogFile ` -InteropOutputDir $script:ResolvedInteropDir } $script:ResolvedLogFile = Get-ResolvedLogFile $script:ResolvedInteropDir = Get-ResolvedInteropDir Ensure-Directory -Path (Split-Path -Parent $script:ResolvedLogFile) Ensure-Directory -Path $script:ResolvedInteropDir switch ($Action) { 'setup' { Write-Step 'Impostazione token utente' [Environment]::SetEnvironmentVariable('NETGESCON_CTI_SHARED_TOKEN', $Token, 'User') Write-Host ('Token utente impostato: {0}' -f ([Environment]::GetEnvironmentVariable('NETGESCON_CTI_SHARED_TOKEN', 'User'))) $sourceRoot = Get-RepoWindowsOpsRoot Publish-Runtime -SourceRoot $sourceRoot if (-not $SkipHttpTest.IsPresent) { Test-HttpBridge } Install-Task Start-BridgeTask Show-Status break } 'test' { Test-HttpBridge break } 'status' { Show-Status break } 'log' { Follow-Log break } 'stop' { Stop-BridgeTask break } 'dry-run' { $sourceRoot = Get-RepoWindowsOpsRoot Publish-Runtime -SourceRoot $sourceRoot Start-DryRunWatcher break } 'live-run' { [Environment]::SetEnvironmentVariable('NETGESCON_CTI_SHARED_TOKEN', $Token, 'User') $sourceRoot = Get-RepoWindowsOpsRoot Publish-Runtime -SourceRoot $sourceRoot Start-LiveWatcher break } }