Veeam backup report via PowerShell

Here’s the fun thing about audit’s. That’s right, I said fun and audit in the same breath. The great thing about audits is that they are tedious and repetitive…

Which makes them great candidates for automating!

I have a task in front of me to document our backups. Thankfully we use Veeam, which means I get to PowerShell this bad boy! It’s an audit, so I could make this super simple and just pipe the output from Get-VBRJob to a CSV and call it a day. The problem with that approach is that it doesn’t provide any additional utility beyond the audit.

What would be useful though was if I could take all the servers in my target group and compare them against all of the jobs from Veeam and output a pretty little CSV where you could at a glance tell where everything was. Here’s what I came up with:

function get-veeampluginstatus{
  if(! $(Get-PSSnapin -Name VeeamPSSnapin -Registered -ea SilentlyContinue) ){
    Write-Host "This script requires the VeeamPSSnapIn to continue. Please install this and retry."
    exit
  }
  elseif( ! $(Get-PSSnapin -name VeeamPSSnapIn -ea SilentlyContinue)){
    Add-PSSnapin -Name VeeamPSSnapIn
  }
}

get-veeampluginstatus

$targetclusters=@("cluster1","cluster2")
$JobArray =@()
$vcentersvr="vcenterserver"
$veeamsvr="vbrserver"

if(!$cred){$cred=get-credential}

Connect-VIServer $vcentersvr
Connect-VBRServer -Server $veeamsvr -Credential $cred

### Get a hash table from Veeam of all Jobs and member servers
foreach($job in Get-VBRJob)
{
  $JobHash=new-object system.object
  $vms=$job.GetObjectsInJob() | Select-Object -Property name -ExpandProperty name
  $JobHash | Add-Member -type NoteProperty -name Name -value $job.Name
  $JobHash | Add-Member -type NoteProperty -name VMs -value $vms
  $JobArray +=$JobHash
}

###Get all Vm's in the target clusters. Iterate through hash table and if a job match add value to VMArray
$SummaryArray =@()
foreach ($target in $targetclusters)
{
  foreach($VM in $(get-cluster $target|get-vm)){
    $VMArray=new-object system.object
    $vname=$(get-vm $vm).name
    $VMArray|Add-Member -type NoteProperty -name VM -Value $vname

    for ($i=0; $i -lt $JobArray.count ;$i++){
      if($JobArray[$i].VMs.Count -gt 0){
        if($JobArray[$i].VMs -contains $vname ){
          $VMArray|Add-Member -type NoteProperty -Name $($JobArray[$i].name) -Value "enabled"
        }
        else{
          $VMArray|Add-Member -type NoteProperty -Name $($JobArray[$i].name) -Value "-"
        }
      }
    }
    $SummaryArray +=$VMArray
  }
}

$SummaryArray | Export-Csv "veeam_jobs_$(get-date -Format dd_MM_yyyy).csv" -NoTypeInformation<span id="mce_SELREST_start" style="overflow:hidden;line-height:0;">&#65279;</span>
lines 1-20 In the current format, this report is meant to be run in an ad-hoc fashion, so lines 1-20 are really just setting the scene.
One thing of note, I chose to target clusters in my script. This could very easily be altered to target any container objects in vSphere by altering lines 13 & 35.
lines 24-31 When building reports, I’m a fan of using custom objects, it’s just how I roll. Plus it’s readable and easy to consume. There’s a really good explanation of custom objects and how to use them here. In this case I build a custom object, $JobHash, to hold the couple of bits of info about each job. I’ll come back to this in a few.

Each job object that’s returned by Get-VBRjob has a method associated, GetObjectsInJob(). This method tells us which VMs are in the job. Since the VMs are returned as an object, I’m just selecting the name for use in the report

Then the Add-Member commandlet is used to add the job name and VM names to $JobHash. Finally individual jobs are each added into $JobArray on line 30 before moving on.

lines 35-55 The general premise of this whole section is to take the previously built array of jobs, conveniently named $JobArray,  compare it to the list of VM’s from our $targetclusters and build our output.
lines 38-40 If you remember I said at the beginning, I want a visual report of all VM’s and their job status. So regardless of job status, every VM gets an element in $VMArray from our friend Add-Member.
lines 42-52 For each VM that’s returned on line 37 we iterate through $JobArray and based on whether a match is made or not, an entry is made for that VM-Job combo in the $VMArray table, which is concatenated onto $SummaryArray before moving on to the next VM.
lines 56 We done! Pump out the $SummaryArray to a datestamped csv file.

2019-06-01 13_26_23-veeam_jobs_01_06_2019.csv - ExcelAnd here’s what we get for output. It’s a very simple report, but it hits exactly the mark I was aiming for, which is a way to see at a glance what is configured where. There are also several places where the code could be made more efficient, but this is one case where the destination matters far more than the journey.

2 thoughts on “Veeam backup report via PowerShell

Leave a comment