This is an old revision of the document!
Table of Contents
Automated Veeam Backup Report Script
Objective: This script automates the generation of a daily report for Veeam backup operations, including Azure copy status, backup job summaries, scale-out offload summaries, local disk status, and Scale-Out Backup Repository (SOBR) status.
Code
- veeamReports.ps1
$toSend = "C:\Temp\logFile.txt" #$OutStr = "C:\Temp\AzCopyLogFile.txt" $src = "C:\Backup\VeeamConfigBackup" $SASURL = "https://bccveeam01.blob.core.windows.net/bccba-veeam-config-backup?sp=racwdl&st=2023-04-01T23:00:00Z&se=2025-02-04T07:00:00Z&spr=https&sv=2021-12-02&sr=c&sig=CrQ***********Y%3D" $subject = "[🥱] Veeam Daily Report" $last24h_backups = "C:\temp\veeamHistory_backups.txt" $last24h_offloads = "C:\temp\veeamHistory_offloads.txt" # comenzar un nuevo archivo y generar un mini header con la fecha y hostname echo '' > $toSend Add-Content $toSend "Reporte generado el $((Get-Date).ToString('dd/MM/yyyy-HH:mm:ss')) en $env:COMPUTERNAME" Add-Content $toSend "<br>" # mostrar los resultados de azcopy Add-Content $toSend "<br>" Add-Content $toSend "<h2>Copia del archivo .bco al repositorio de Azure</h2>" Add-Content $toSend "<pre>" C:\Tandem\Tools\azcopy.exe sync $src $SASURL --delete-destination=true 2>&1 | Where-Object { $_ -notmatch '0 Done, 0 Failed, 1 Pending' } | Out-File -FilePath $toSend -Append Add-Content $toSend "</pre>" # Si falló, inserta un signo de atención en el asunto del email if ((Get-Content $toSend) -match '1 Failed') { $subject += " ⚠️" } # mostrar los resultados de jobs para las últimas 24 horas, para tareas que se reintentaron, mostrar el último resultado Add-Content $toSend "<br>" Add-Content $toSend "<h2>Resumen de resultados (últimas 24h)</h2>" Add-Content $toSend "<br>" Import-Module Veeam.Backup.Powershell # Get-VBRBackupSession $backupSessions = Get-VBRBackupSession | Where-Object { $_.CreationTime -ge (Get-Date).AddDays(-1) } | Sort-Object CreationTime -Descending # Limit JobName to 12 characters and append '...' $backupSessions = $backupSessions | ForEach-Object { $modifiedJobName = $_.JobName.Substring(0, [Math]::Min($_.JobName.Length, 12)) if ($_.JobName.Length -gt 12) { $modifiedJobName += '...' } [PSCustomObject]@{ JobName = $modifiedJobName CreationTime = $_.CreationTime Result = $_.Result } } $backupSessions | Group-Object JobName | ForEach-Object { $_.Group[0] } | Format-Table > $last24h_backups # Append the contents of the temporary text file to the variable $toSend Add-Content $toSend "<pre>" Add-Content -Path $toSend -Value (Get-Content $last24h_backups) Add-Content $toSend "</pre>" if ((Get-Content $last24h_backups) -match 'Failed' -or (Get-Content $last24h_backups) -match 'None') { $subject += " ⚠️" } Add-Content $toSend "<h3>Scale-Out Offloads</h3>" # [Veeam.Backup.Core.CBackupSession]::GetByTypeAndTimeInterval $sobrOffload = [Veeam.Backup.Model.EDbJobType]::ArchiveBackup $offloadSessions = [Veeam.Backup.Core.CBackupSession]::GetByTypeAndTimeInterval($sobrOffload,(Get-Date).adddays(-1), (Get-Date).adddays(1)) | Sort-Object EndTime # Limit JobName to 12 characters and append '...' $offloadSessions = $offloadSessions | ForEach-Object { $modifiedJobName = $_.JobName.Substring(0, [Math]::Min($_.JobName.Length, 12)) if ($_.JobName.Length -gt 12) { $modifiedJobName += '...' } [PSCustomObject]@{ JobName = $modifiedJobName EndTime = $_.EndTime Result = $_.Result } } $offloadSessions | Group-Object JobName | ForEach-Object { $_.Group[0] } | Format-Table > $last24h_offloads # Append the contents of a text file to the variable $toSend Add-Content $toSend "<pre>" Add-Content -Path $toSend -Value (Get-Content $last24h_offloads) Add-Content $toSend "</pre>" if ((Get-Content $last24h_offloads) -match 'Failed' -or (Get-Content $last24h_offloads) -match 'None') { $subject += " ℹ️" } # anexar el estado de los discos locales Get-CimInstance -ClassName Win32_LogicalDisk -Filter "DriveType= 3" | Select-Object DeviceID, @{Name="Size (GB)"; Expression={"{0:N2}" -f ($_.Size / 1GB)}}, @{Name="Free Space (GB)"; Expression={"{0:N2}" -f ($_.FreeSpace / 1GB)}}, @{Name="Free Space (%)"; Expression={"{0:P2}" -f ($_.FreeSpace / $_.Size)}} | ConvertTo-Html -As Table -Fragment -PreContent "<h2>Discos locales</h2>" >> $toSend # mostrar el estado del SOBR Add-Content $toSend "<br>" Add-Content $toSend "<h2>Estado del repositorio Scale-Out</h2>" Add-Content $toSend "<br>" $sobrs = Get-VBRBackupRepository -Scaleout foreach ($sobr in $sobrs) { $extents = $sobr.Extent foreach ($extent in $extents) { $repo = $extent.Repository $container = $repo.GetContainer() $freePercentage = [Math]::Round(($container.CachedFreeSpace / $container.CachedTotalSpace) * 100) $output = [PSCustomObject]@{ RepositoryName = $repo.Name CachedTotalSpace = $container.CachedTotalSpace CachedFreeSpace = $container.CachedFreeSpace FreePercentage = $freePercentage } $output | ConvertTo-Html -As Table >> $toSend } } # configuración del envío del correo $emailFrom = "💻" $emailTo = "😅" $body = Get-Content $toSend | Out-String $smtpServer = "smtp.myorg.com" # acá efectivamente llama a sendmailmsg para hacer el envío Send-MailMessage -From $emailFrom -To $emailTo -Subject $subject -BodyAsHtml -Body $body -SmtpServer $smtpServer -Encoding ([System.Text.Encoding]::UTF8) # llamar al script de subida de resultados a la API [experimental] Invoke-Expression -Command C:\Tandem\Tools\uploadResultsToAPI.ps1
Code Explanation:
1. Variable Initialization: The script initializes variables for file paths, Azure Storage SAS URL, email subject, and temporary files for storing backup job and offload summaries.
2. Header Generation: The script starts by creating a new HTML file and adding a header containing the current date and the hostname of the machine.
3. Azure Copy Status: It executes the Azure copy operation using AzCopy and captures the output. If the operation fails, it appends a warning sign to the email subject.
4. Backup Job Summaries: It retrieves Veeam backup sessions for the last 24 hours, formats the data, and appends it to the HTML file. If any backup jobs failed or none were found, it adds a warning sign to the email subject.
5. Scale-Out Offload Summaries: It retrieves scale-out offload sessions for the last 24 hours, formats the data, and appends it to the HTML file. If any offload sessions failed or none were found, it adds an information sign to the email subject.
6. Local Disk Status: It fetches information about local disks (Drive Type 3) and converts it to an HTML table, appending it to the HTML file.
7. SOBR Status: It retrieves information about Scale-Out Backup Repositories (SOBRs), including total and free space, and appends it to the HTML file.
8. Email Configuration and Sending: It configures email settings, including sender, recipient(s), subject, body (HTML format), and SMTP server. Then it sends the email with the generated report.
9. API Results Upload (Experimental): It invokes a script to upload results to an API. This part is labeled as experimental.
