From 3ca3fb69749918d928d990f1f7087d9e36a8e20c Mon Sep 17 00:00:00 2001 From: tigattack <10629864+tigattack@users.noreply.github.com> Date: Wed, 4 Jun 2025 00:32:06 +0100 Subject: [PATCH 1/3] fix(vbrsessioninfo): use different method for getting agent & tape sessions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Resolves #120 by passing the job ID in to the `Get-VBRSessionInfo` function and called Veeam's `CBackupSession`'s `GetByJob` method, then filtering for the last result. A bit janky, but hardly more than before. - Reasolves invalid reference to non-existent `$job` variable. I'm unable to test this with tape jobs so hopefully it doesn't cause any issues ¯\_(ツ)_/¯ --- AlertSender.ps1 | 5 +++-- Bootstrap.ps1 | 8 +++++++- resources/VBRSessionInfo.psm1 | 18 ++++++++++-------- 3 files changed, 20 insertions(+), 11 deletions(-) diff --git a/AlertSender.ps1 b/AlertSender.ps1 index 12553fe..1ce9dc0 100644 --- a/AlertSender.ps1 +++ b/AlertSender.ps1 @@ -1,4 +1,5 @@ param( + [String]$JobId, [String]$SessionId, [String]$JobType, $Config, @@ -72,7 +73,7 @@ try { # Job info preparation ## Get the backup session. - $session = (Get-VBRSessionInfo -SessionId $SessionId -JobType $JobType).Session + $session = (Get-VBRSessionInfo -SessionId $SessionId -JobId $JobId -JobType $JobType).Session ## Initiate logger variable $vbrSessionLogger = $session.Logger @@ -84,7 +85,7 @@ try { do { Write-LogMessage -Tag 'INFO' -Message 'Session not completed. Sleeping...' Start-Sleep -Seconds 10 - $session = (Get-VBRSessionInfo -SessionId $SessionId -JobType $JobType).Session + $session = (Get-VBRSessionInfo -SessionId $SessionId -JobId $JobId -JobType $JobType).Session } while ($false -eq $session.Info.IsCompleted -and $stopwatch.Elapsed -lt $timeout) $stopwatch.Stop() diff --git a/Bootstrap.ps1 b/Bootstrap.ps1 index de39b81..59c1d02 100644 --- a/Bootstrap.ps1 +++ b/Bootstrap.ps1 @@ -103,7 +103,13 @@ else { # Get the session information and name. Write-LogMessage -Tag 'INFO' -Message 'Getting VBR session information' -$sessionInfo = Get-VBRSessionInfo -SessionId $SessionId -JobType $JobType +try { + $sessionInfo = Get-VBRSessionInfo -SessionId $SessionId -JobId $JobId -JobType $JobType +} +catch { + Write-LogMessage -Tag 'ERROR' -Message "Failed to retrieve session information: $_" + exit 1 +} $jobName = $sessionInfo.JobName $vbrSessionLogger = $sessionInfo.Session.Logger diff --git a/resources/VBRSessionInfo.psm1 b/resources/VBRSessionInfo.psm1 index 8b17a69..329b48d 100644 --- a/resources/VBRSessionInfo.psm1 +++ b/resources/VBRSessionInfo.psm1 @@ -9,7 +9,9 @@ function Get-VBRSessionInfo { [Parameter(Mandatory)][ValidateNotNullOrEmpty()] [string]$SessionId, [Parameter(Mandatory)][ValidateNotNullOrEmpty()] - [string]$JobType + [string]$JobType, + [Parameter(Mandatory)][ValidateNotNullOrEmpty()] + [string]$JobId ) # Import VBR module @@ -33,16 +35,16 @@ function Get-VBRSessionInfo { # to load in whatever's required to utilise the GetByOriginalSessionId method. # See https://forums.veeam.com/powershell-f26/want-to-capture-running-jobs-by-session-type-i-e-sobr-tiering-t75583.html#p486295 Get-VBRSession -Id $SessionId | Out-Null + # Get the session details. - $session = [Veeam.Backup.Core.CBackupSession]::GetByOriginalSessionId($SessionId) + $session = [Veeam.Backup.Core.CBackupSession]::GetByJob($JobId) | Select-Object -Last 1 - # Copy the job's name to it's own variable. - if ($JobType -eq 'EpAgentBackup') { - $jobName = $job.Info.Name - } - elseif ($JobType -in 'BackupToTape', 'FileToTape') { - $jobName = $job.Name + if ($null -eq $session) { + throw "$JobType job session with ID '$SessionId' could not be found." } + + # Extract the job name from the session + $jobName = $session.Name } } From 017072b144acd02a6a8fd0f7164ddfa8e15bc609 Mon Sep 17 00:00:00 2001 From: tigattack <10629864+tigattack@users.noreply.github.com> Date: Wed, 4 Jun 2025 00:34:14 +0100 Subject: [PATCH 2/3] feat(bootstrap): improve error handling - Catch more issues - Stop logging and rename log file to include job name (if we got that far before failing) in all caught error scenarios. --- Bootstrap.ps1 | 66 ++++++++++++++++++++++++++++++++++----------------- 1 file changed, 44 insertions(+), 22 deletions(-) diff --git a/Bootstrap.ps1 b/Bootstrap.ps1 index 59c1d02..c7449e1 100644 --- a/Bootstrap.ps1 +++ b/Bootstrap.ps1 @@ -6,6 +6,32 @@ param ( [string]$SessionId = $null ) +function FinishBootstrap { + param( + [switch]$Failed + ) + + if ($config.logging.enabled) { + Stop-Logging + + if ($newLogfile) { + # Rename log file to include the job name. + try { + Rename-Item -Path $logFile -NewName "$(Split-Path $newLogfile -Leaf)" -ErrorAction Stop + } + catch { + Write-Output "ERROR: Failed to rename log file: $_" | Out-File $logFile -Append + } + } + } + if ($Failed) { + exit 1 + } + else { + exit 0 + } +} + # Import modules Import-Module Veeam.Backup.PowerShell -DisableNameChecking Import-Module "$PSScriptRoot\resources\Logger.psm1" @@ -19,7 +45,7 @@ if ($JobId -and -not $SessionId) { $SessionId = (Get-VBRBackupSession | Where-Object {$_.JobId -eq $JobId} | Sort-Object EndTimeUTC -Descending | Select-Object -First 1).Id.ToString() if ($null -eq $SessionId) { Write-Output 'ERROR: Failed to retrieve the session ID for the provided job ID. Please check the job ID.' - exit 1 + FinishBootstrap -Failed } } elseif ($SessionId -and -not $JobId) { @@ -27,7 +53,7 @@ elseif ($SessionId -and -not $JobId) { $JobId = (Get-VBRBackupSession -Id $SessionId | Sort-Object EndTimeUTC -Descending | Select-Object -First 1).JobId.ToString() if ($null -eq $JobId) { Write-Output 'ERROR: Failed to retrieve the job ID for the provided session ID. Please check the session ID.' - exit 1 + FinishBootstrap -Failed } } if ($JobId -and $SessionId) { @@ -91,13 +117,19 @@ else { # At time of writing, there is no alternative way to discover the job time. Write-LogMessage -Tag 'INFO' -Message 'Getting VBR job details' $job = Get-VBRJob -WarningAction SilentlyContinue | Where-Object {$_.Id.ToString() -eq $JobId} -if (!$job) { - # Can't locate non tape job so check if it's a tape job - $job = Get-VBRTapeJob -WarningAction SilentlyContinue | Where-Object {$_.Id.ToString() -eq $JobId} - $JobType = $job.Type +if ($job) { + $JobType = $job.JobType } else { - $JobType = $job.JobType + # Can't locate non-tape job so check if it's a tape job + Write-LogMessage -Tag 'DEBUG' -Message "Job with ID $JobId not found in VBR jobs. Checking for tape jobs." + $job = Get-VBRTapeJob -WarningAction SilentlyContinue | Where-Object {$_.Id.ToString() -eq $JobId} + if ($job) { + $JobType = $job.Type + } else { + Write-LogMessage -Tag 'ERROR' -Message "Job with ID $JobId not found in tape jobs. Exiting." + FinishBootstrap -Failed + } } @@ -108,7 +140,7 @@ try { } catch { Write-LogMessage -Tag 'ERROR' -Message "Failed to retrieve session information: $_" - exit 1 + FinishBootstrap -Failed } $jobName = $sessionInfo.JobName $vbrSessionLogger = $sessionInfo.Session.Logger @@ -118,7 +150,7 @@ $vbrLogEntry = $vbrSessionLogger.AddLog('[VeeamNotify] Parsing job & session inf # Quit if job type is not supported. if ($JobType -notin $supportedTypes) { Write-LogMessage -Tag 'ERROR' -Message "Job type '$($JobType)' is not supported." - exit 1 + FinishBootstrap -Failed } Write-LogMessage -Tag 'INFO' -Message "Bootstrap script for Veeam job '$jobName' (job $JobId session $SessionId) - Session & job detection complete." @@ -135,6 +167,7 @@ $newLogfile = "$PSScriptRoot\log\$($date)-$($logJobName).log" # Build argument string for the alert sender script. $powershellArguments = "-NoProfile -File $PSScriptRoot\AlertSender.ps1", ` + "-JobId `"$JobId`"", ` "-SessionId `"$SessionId`"", ` "-JobType `"$JobType`"", ` "-Config `"$configRaw`"", ` @@ -155,18 +188,7 @@ try { catch { Write-LogMessage -Tag 'ERROR' -Message "Failed to launch AlertSender.ps1: $_" $vbrSessionLogger.UpdateErr($vbrLogEntry, '[VeeamNotify] Failed to launch Alert Sender.', "Please check the log: $newLogfile") | Out-Null - exit 1 + FinishBootstrap -Failed } -# Stop logging. -if ($config.logging.enabled) { - Stop-Logging - - # Rename log file to include the job name. - try { - Rename-Item -Path $logFile -NewName "$(Split-Path $newLogfile -Leaf)" -ErrorAction Stop - } - catch { - Write-Output "ERROR: Failed to rename log file: $_" | Out-File $logFile -Append - } -} +FinishBootstrap From 4b2bbc9e42bc91dfcecc91fa899285df9f0b5db4 Mon Sep 17 00:00:00 2001 From: github-actions <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 3 Jun 2025 23:39:01 +0000 Subject: [PATCH 3/3] [CI] Run script formatter --- Bootstrap.ps1 | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Bootstrap.ps1 b/Bootstrap.ps1 index c7449e1..19fbfbd 100644 --- a/Bootstrap.ps1 +++ b/Bootstrap.ps1 @@ -126,7 +126,8 @@ else { $job = Get-VBRTapeJob -WarningAction SilentlyContinue | Where-Object {$_.Id.ToString() -eq $JobId} if ($job) { $JobType = $job.Type - } else { + } + else { Write-LogMessage -Tag 'ERROR' -Message "Job with ID $JobId not found in tape jobs. Exiting." FinishBootstrap -Failed }