Examples/Test-UploadAndWatch.ps1
|
<# .SYNOPSIS Real-world end-to-end test: upload a package, create the app, and poll until packaging completes. .DESCRIPTION Demonstrates the primary automation use case: upload an installer, create the application with -RunImmediately, and watch the workflow status every 5 minutes until it reaches "ReadyForQualityReview" (Ready for QR). New-JuribaAppRApplication handles the heavy lifting automatically: - Reads Default Settings for VM groups and output format bitmask - Calls server-side metadata extraction for name/manufacturer/version - Command lines are determined server-side by the product (not sent in the payload) .PARAMETER InstanceUrl The base URL of the App Readiness instance. Not required if already connected via Connect-JuribaAppR. .PARAMETER APIKey Your API key for authentication. Not required if already connected via Connect-JuribaAppR. .PARAMETER SetupFilePath Path to the installer to upload (EXE, MSI, etc.). .PARAMETER IntervalSeconds Seconds between status polls. Default 300 (5 minutes). .PARAMETER TimeoutMinutes Maximum minutes to wait. Default 30. .EXAMPLE .\Test-UploadAndWatch.ps1 -InstanceUrl "https://demo.appr.juriba.app" ` -APIKey "your-key" -SetupFilePath "C:\Installers\7z2407-x64.exe" #> [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSAvoidUsingWriteHost', '', Justification = 'Interactive example script - user-facing colored console output for progress and results.')] [CmdletBinding()] param ( [Parameter(Mandatory = $false)] [string]$InstanceUrl, [Parameter(Mandatory = $false)] [string]$APIKey, [Parameter(Mandatory = $true)] [string]$SetupFilePath, [int]$IntervalSeconds = 300, [int]$TimeoutMinutes = 30 ) $ErrorActionPreference = 'Stop' # Import the module $modulePath = Join-Path (Join-Path $PSScriptRoot '..') 'Juriba.AppR.psd1' Import-Module $modulePath -Force Write-Host "Module imported" -ForegroundColor Cyan # 1. CONNECT (skip if already connected) Write-Host "`n=== Step 1: Connect ===" -ForegroundColor Magenta $existing = Get-JuribaAppRSession if ($existing) { Write-Host "Already connected to $($existing.Instance)" -ForegroundColor Green } elseif ($InstanceUrl -and $APIKey) { Connect-JuribaAppR -Instance $InstanceUrl -APIKey $APIKey Write-Host "Connected to $InstanceUrl" } else { Write-Error "Not connected. Either run Connect-JuribaAppR first, or pass -InstanceUrl and -APIKey." } # 2. UPLOAD Write-Host "`n=== Step 2: Upload ===" -ForegroundColor Magenta $upload = Send-JuribaAppRSetupFile -FilePath $SetupFilePath -Verbose:$VerbosePreference Write-Host "Uploaded: $($upload.FileName) ($([Math]::Round($upload.FileSize / 1MB, 2)) MB)" Write-Host " UUID: $($upload.Uuid)" Write-Host " Name: $($upload.Name)" Write-Host " Manufacturer: $($upload.Manufacturer)" Write-Host " Version: $($upload.Version)" # 3. CREATE APPLICATION # New-JuribaAppRApplication now automatically: # - Reads Default Settings (VM groups, output format bitmask) # - Extracts metadata from the server (name, manufacturer, version) # - Command lines are NOT sent — the product determines them server-side # using hash matching, Juriba KB, and AI-based detection Write-Host "`n=== Step 3: Create Application ===" -ForegroundColor Magenta $splatCreate = @{ Uuid = $upload.Uuid FileName = $upload.FileName FileSize = $upload.FileSize TotalChunks = $upload.TotalChunks RunImmediately = $true } # Pass any client-side metadata as hints (server-side extraction takes priority # inside New-JuribaAppRApplication, but these serve as fallbacks) if ($upload.Name) { $splatCreate['Name'] = $upload.Name } if ($upload.Manufacturer) { $splatCreate['Manufacturer'] = $upload.Manufacturer } if ($upload.Version) { $splatCreate['Version'] = $upload.Version } $app = New-JuribaAppRApplication @splatCreate -Verbose:$VerbosePreference Write-Host "Application created. Response:" $app | Format-List # 4. WAIT FOR CREATION TO RESOLVE (get the app ID) Write-Host "`n=== Step 4: Wait for creation to resolve ===" -ForegroundColor Magenta $appId = $null # Poll the creation state to get the actual app ID $creationTimeout = (Get-Date).AddMinutes(5) while ((Get-Date) -lt $creationTimeout) { try { $state = Get-JuribaAppRApplicationCreationState -UploadId $upload.Uuid # applicationId is nested inside .data $resolvedId = if ($state.data.applicationId) { $state.data.applicationId } elseif ($state.applicationId) { $state.applicationId } else { $null } if ($resolvedId -and $resolvedId -gt 0) { $appId = $resolvedId Write-Host "Application ID resolved: $appId" -ForegroundColor Green break } Write-Host " Waiting for app ID... (state: $($state | ConvertTo-Json -Compress))" } catch { Write-Host " Waiting for creation state... ($($_.Exception.Message))" -ForegroundColor DarkGray } Start-Sleep -Seconds 10 } if (-not $appId) { # Try to find it by listing recent apps Write-Host " Searching application list for uploaded file..." -ForegroundColor Yellow $allApps = Get-JuribaAppRApplicationList -AllUsers $match = $allApps | Where-Object { $_.basic.name -eq $upload.Name -or $_.basic.name -like "*$([System.IO.Path]::GetFileNameWithoutExtension($upload.FileName))*" } | Sort-Object { $_.basic.id } -Descending | Select-Object -First 1 if ($match) { $appId = $match.basic.id Write-Host "Found app by name: $($match.basic.name) (id=$appId)" -ForegroundColor Green } else { Write-Error "Could not determine the application ID. Check the UI manually." } } # 5. POLL STATUS Write-Host "`n=== Step 5: Watch packaging status (every $IntervalSeconds seconds, timeout $TimeoutMinutes min) ===" -ForegroundColor Magenta $result = Watch-JuribaAppRApplicationStatus -AppId $appId ` -IntervalSeconds $IntervalSeconds -TimeoutMinutes $TimeoutMinutes Write-Host "`n=== Result ===" -ForegroundColor Magenta Write-Host "Status: $($result.Status)" -ForegroundColor $(if ($result.Status -eq 'ReadyForQualityReview') { 'Green' } else { 'Yellow' }) Write-Host "Progress: $($result.Progress)%" Write-Host "Elapsed: $($result.Elapsed)" Write-Host "Polls: $($result.PollCount)" # On failure, dump diagnostics to help debug if ($result.Status -match 'Fail|Cancel') { Write-Host "`n=== Failure Diagnostics ===" -ForegroundColor Red # Dump relevant fields from the app detail returned by Watch if ($result.AppDetail) { $ext = $result.AppDetail.ext if ($ext) { Write-Host " ext.status: $($ext.status)" Write-Host " ext.progressPercent: $($ext.progressPercent)" Write-Host " ext.statusMessage: $($ext.statusMessage)" Write-Host " ext.errorMessage: $($ext.errorMessage)" } # Show packaging info if present if ($result.AppDetail.packages) { Write-Host "`n Packages:" -ForegroundColor Yellow $result.AppDetail.packages | ForEach-Object { Write-Host " Type=$($_.packageType) Status=$($_.status) Error=$($_.errorMessage)" } } # Full ext dump for anything we missed Write-Host "`n Full ext object:" -ForegroundColor Yellow $ext | ConvertTo-Json -Depth 3 | Write-Host } # Pull event history for the app try { Write-Host "`n Event history:" -ForegroundColor Yellow $events = Get-JuribaAppRApplicationEvent -AppId $appId $events | ForEach-Object { $ts = if ($_.date) { $_.date } elseif ($_.timestamp) { $_.timestamp } else { '' } $msg = if ($_.message) { $_.message } elseif ($_.description) { $_.description } else { ($_ | ConvertTo-Json -Compress) } Write-Host " [$ts] $msg" } } catch { Write-Host " Could not retrieve events: $($_.Exception.Message)" -ForegroundColor DarkGray } } # Disconnect only if we connected in this script if ($InstanceUrl -and $APIKey) { Disconnect-JuribaAppR } |