$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 "
" # mostrar los resultados de azcopy Add-Content $toSend "
" Add-Content $toSend "

Copia del archivo .bco al repositorio de Azure

" Add-Content $toSend "
"
 
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 "
" # 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 "
" Add-Content $toSend "

Resumen de resultados (últimas 24h)

" Add-Content $toSend "
" 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 "
" 
Add-Content -Path $toSend -Value (Get-Content $last24h_backups)
Add-Content $toSend "
" if ((Get-Content $last24h_backups) -match 'Failed' -or (Get-Content $last24h_backups) -match 'None') { $subject += " ⚠️" } Add-Content $toSend "

Scale-Out Offloads

" # [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 "
" 
Add-Content -Path $toSend -Value (Get-Content $last24h_offloads)
Add-Content $toSend "
" 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 "

Discos locales

" >> $toSend # mostrar el estado del SOBR Add-Content $toSend "
" Add-Content $toSend "

Estado del repositorio Scale-Out

" Add-Content $toSend "
" $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