3 day Veeam Backup Report – Powercli

Just to confirm that I am, by no means, a Powercli (PowerShell) expert and would still class myself as a novice.  With this in mind there are probably tips and better ways to perform some of the items involved in my scripts… but the items that I have done seem to work for me and may help someone else in the process.

The script enclosed below is a a module that can be added to the ‘SysAdmin Modular Report’ that was created by ‘TheAgreeableCow’ and featured on Veeams community forums… links below:

http://www.theagreeablecow.com/2012/09/sysadmin-modular-reporting-samreports.html

http://forums.veeam.com/powershell-f26/sysadmin-modular-reporting-samreport-for-veeam-t13422.html

The concept behind SAMReport is taken from some of the work done by Alan Renouf with his vCheck Report:  http://www.virtu-al.net/vcheck-pluginsheaders/vcheck/

Due to wanting to create a table which is colour coded to show whether backups have been successful or failed, I have also utilised code from Martin Pugh called Set-CellColor, this can be found here:  http://community.spiceworks.com/scripts/show/2450-change-cell-color-in-html-table-with-powershell-set-cellcolor

 

Idea behind the report

So the idea behind the report was to make it easier for our backup administrators to perform their daily backup checks and to see whether there had been a failure of a backup over multiple days.  As with many companies, we have to abide by some Sarbannes-Oxley requirements, with our backups being subject to some of those checks.  The report checks the last three or four days of Veeam backups and compares them against your virtual machines to produce a report showing the success or failure of the backup over the previous days.  When a backup is successful, it turns the cell green with Success written in the cell and when it fails, it turns the cell red with Failed written in the cell.

There is also an element that excludes VMs… firstly it only checks powered on VMs (powered off VMs do not need to be checked on a daily backup check), secondly I use VMware Tags to create a list of Excluded VMs using a Tag Category of ‘Backup Tags’… this means that any virtual machine which has a Tag assigned to it with the Category ‘Backup Tags’ will also be excluded from the report.

As this report will run on a Tuesday through to Sunday to check the backups from the previous three or four nights (we do not have any backups that run on a Sunday), I also introduced a way for the script to change the Saturday backup column to read ‘Weekend of date‘ and check across both Saturday and Sunday (just in case a weekly backup has run through to the Sunday).

Anyway, that’s enough about the idea behind the report, please find enclosed below a view of how the report comes out and also the script:

Veeam Report


asnp "VeeamPSSnapIn" -ErrorAction SilentlyContinue

####################################################################
# Configuration
#
# vCenter server
$Title = "Veeam Protected Machines in Woking"

$vcenter = $VMware_Server
#
# To Exclude VMs from report add VM names to be excluded as fol
# simple wildcards are supported:
# $excludevms=@("vm1","vm2", "*_replica")

#$srmvms=@()

#Connect-SrmServer
#$SrmConnection=Connect-SrmServer
#$SrmApi=$SrmConnection.ExtensionData
#$protectionGroups = $srmApi.Protection.ListProtectionGroups()
#$protectionGroups | % {
# $protectionGroup = $_

# $protectionGroupInfo = $protectionGroup.GetInfo()

# The following command lists the virtual machines associated with a protection group
# $protectedVms = $protectionGroup.ListProtectedVms()
# The result of the above call is an array of references to the virtual machines at the vSphere API
# To populate the data from the vSphere connection, call the UpdateViewData method on each virtual machine view object
# $protectedVms | % { $_.Vm.UpdateViewData() }
# After the data is populated, use it to generate a report

# $protectedVms | %{
# select VmName
# $srmvms+=$_.VM.Name
# }
#}
$excludevms=@()

$table = ""
$TableName = ""
$1days = ""
$2days = ""
$3days = ""
$4days = ""
$5days = ""
$6days = ""
$7days = ""
$8days = ""
$9days = ""
####################################################################

Function Set-CellColor
{ <#
.SYNOPSIS
Function that allows you to set individual cell colors in an HTML table
.DESCRIPTION
To be used inconjunction with ConvertTo-HTML this simple function allows you
to set particular colors for cells in an HTML table. You provide the criteria
the script uses to make the determination if a cell should be a particular
color (property -gt 5, property -like "*Apple*", etc).

You can add the function to your scripts, dot source it to load into your current
PowerShell session or add it to your $Profile so it is always available.

To dot source:
.".\Set-CellColor.ps1"

.PARAMETER Property
Property, or column that you will be keying on.
.PARAMETER Color
Name or 6-digit hex value of the color you want the cell to be
.PARAMETER InputObject
HTML you want the script to process. This can be entered directly into the
parameter or piped to the function.
.PARAMETER Filter
Specifies a query to determine if a cell should have its color changed. $true
results will make the color change while $false result will return nothing.

Syntax
<Property Name> <Operator> <Value>

<Property Name>::= the same as $Property. This must match exactly
<Operator>::= "-eq" | "-le" | "-ge" | "-ne" | "-lt" | "-gt"| "-approx" | "-like" | "-notlike"
<JoinOperator> ::= "-and" | "-or"
<NotOperator> ::= "-not"

The script first attempts to convert the cell to a number, and if it fails it will
cast it as a string. So 40 will be a number and you can use -lt, -gt, etc. But 40%
would be cast as a string so you could only use -eq, -ne, -like, etc.
.PARAMETER Row
Instructs the script to change the entire row to the specified color instead of the individual cell.
.INPUTS
HTML with table
.OUTPUTS
HTML
.EXAMPLE
get-process | convertto-html | set-cellcolor -Propety cpu -Color red -Filter "cpu -gt 1000" | out-file c:\test\get-process.html

Assuming Set-CellColor has been dot sourced, run Get-Process and convert to HTML.
Then change the CPU cell to red only if the CPU field is greater than 1000.

.EXAMPLE
get-process | convertto-html | set-cellcolor cpu red -filter "cpu -gt 1000 -and cpu -lt 2000" | out-file c:\test\get-process.html

Same as Example 1, but now we will only turn a cell red if CPU is greater than 100
but less than 2000.

.EXAMPLE
$HTML = $Data | sort server | ConvertTo-html -head $header | Set-CellColor cookedvalue red -Filter "cookedvalue -gt 1"
PS C:\> $HTML = $HTML | Set-CellColor Server green -Filter "server -eq 'dc2'"
PS C:\> $HTML | Set-CellColor Path Yellow -Filter "Path -like ""*memory*""" | Out-File c:\Test\colortest.html

Takes a collection of objects in $Data, sorts on the property Server and converts to HTML. From there
we set the "CookedValue" property to red if it's greater then 1. We then send the HTML through Set-CellColor
again, this time setting the Server cell to green if it's "dc2". One more time through Set-CellColor
turns the Path cell to Yellow if it contains the word "memory" in it.

.EXAMPLE
$HTML = $Data | sort server | ConvertTo-html -head $header | Set-CellColor cookedvalue red -Filter "cookedvalue -gt 1" -Row

Now, if the cookedvalue property is greater than 1 the function will highlight the entire row red.

.NOTES
Author: Martin Pugh
Twitter: @thesurlyadm1n
Spiceworks: Martin9700
Blog: www.thesurlyadmin.com

Changelog:
1.5 Added ability to set row color with -Row switch instead of the individual cell
1.03 Added error message in case the $Property field cannot be found in the table header
1.02 Added some additional text to help. Added some error trapping around $Filter
creation.
1.01 Added verbose output
1.0 Initial Release
.LINK
http://community.spiceworks.com/scripts/show/2450-change-cell-color-in-html-table-with-powershell-set-cellcolor
#>

[CmdletBinding()]
Param (
[Parameter(Mandatory=$true,Position=0)]
[string]$Property,
[Parameter(Mandatory=$true,Position=1)]
[string]$Color,
[Parameter(Mandatory=$true,ValueFromPipeline=$true)]
[Object[]]$InputObject,
[Parameter(Mandatory=$true)]
[string]$Filter,
[switch]$Row
)

Begin {
Write-Verbose "$(Get-Date): Function Set-CellColor begins"
If ($Filter)
{ If ($Filter.ToUpper().IndexOf($Property.ToUpper()) -ge 0)
{ $Filter = $Filter.ToUpper().Replace($Property.ToUpper(),"`$Value")
Try {
[scriptblock]$Filter = [scriptblock]::Create($Filter)
}
Catch {
Write-Warning "$(Get-Date): ""$Filter"" caused an error, stopping script!"
Write-Warning $Error[0]
Exit
}
}
Else
{ Write-Warning "Could not locate $Property in the Filter, which is required. Filter: $Filter"
Exit
}
}
}

Process {
ForEach ($Line in $InputObject)
{ If ($Line.IndexOf("<tr><th") -ge 0)
{ Write-Verbose "$(Get-Date): Processing headers..."
$Search = $Line | Select-String -Pattern '<th ?[a-z\-:;"=]*>(.*?)<\/th>' -AllMatches
$Index = 0
ForEach ($Match in $Search.Matches)
{ If ($Match.Groups[1].Value -eq $Property)
{ Break
}
$Index ++
}
If ($Index -eq $Search.Matches.Count)
{ Write-Warning "$(Get-Date): Unable to locate property: $Property in table header"
Exit
}
Write-Verbose "$(Get-Date): $Property column found at index: $Index"
}
If ($Line -match "<tr( style=""background-color:.+?"")?><td")
{ $Search = $Line | Select-String -Pattern '<td ?[a-z\-:;"=]*>(.*?)<\/td>' -AllMatches
$Value = $Search.Matches[$Index].Groups[1].Value -as [double]
If (-not $Value)
{ $Value = $Search.Matches[$Index].Groups[1].Value
}
If (Invoke-Command $Filter)
{ If ($Row)
{ Write-Verbose "$(Get-Date): Criteria met! Changing row to $Color..."
If ($Line -match "<tr style=""background-color:(.+?)"">")
{ $Line = $Line -replace "<tr style=""background-color:$($Matches[1])","<tr style=""background-color:$Color"
}
Else
{ $Line = $Line.Replace("<tr>","<tr style=""background-color:$Color"">")
}
}
Else
{ Write-Verbose "$(Get-Date): Criteria met! Changing cell to $Color..."
$Line = $Line.Replace($Search.Matches[$Index].Value,"<td style=""background-color:$Color"">$Value</td>")
}
}
}
Write-Output $Line
}
}

End {
Write-Verbose "$(Get-Date): Function Set-CellColor completed"
}
}

$vcenterobj = Get-VBRServer -Name $vcenter
New-VIProperty -Name Tag -ObjectType VirtualMachine -Value { Get-TagAssignment -Entity $args[0] -Category "" | select -ExpandProperty Tag }
$excludevms=@(get-tagassignment -Category 'Backup Tags' | select -property @{N='VM';E={$_.Entity}})

$FullVM = Get-vm | Where-Object {$_.PowerState -eq "PoweredOn" -and $_ -notin $excludevms.VM.Name}

# Get a list of all VMs from vCenter and add to hash table, assume Unprotected
$Result=@()
foreach ($vm in ($FullVM | ForEach-Object {$_ | Select-object @{Name="VMname";Expression={$_.Name}}})) {

$vm | Add-Member -MemberType NoteProperty -Name "backed_up" -Value $False
$vm | Add-Member -MemberType NoteProperty -Name "backed_up2" -Value $False
$vm | Add-Member -MemberType NoteProperty -Name "backed_up3" -Value $False
$vm | Add-Member -MemberType NoteProperty -Name "backed_up4" -Value $False

$Result += $vm
# }
}
# Find all backup job sessions that have ended in the last week
$vbrsessions = ""

if ([DateTime]::Today.AddDays(-1).DayOfWeek -eq "Saturday") {

$vbrsessions = Get-VBRBackupSession | Where-Object {$_.JobType -eq "Backup" -or $_.JobType -eq "Replica" -and $_.EndTime -ge [DateTime]::Today.AddDays(-1).AddHours(05) -and $_.EndTime -lt [DateTime]::Today.AddHours(23) -and $_ -notin $excludevms.VM.Name}

foreach ($session in $vbrsessions) {
foreach ($vm in ($session.gettasksessions() | ForEach-Object { $_ | Select-object @{Name="VMname";Expression={$_.Name}}})) {

$VMObj = $Result | where {$_.VMName -eq $vm.VMname }
if ($VMObj){
$VMObj.backed_up = $True

}

}
}

}

if ([DateTime]::Today.AddDays(-1).DayOfWeek -eq "Friday") {

$vbrsessions = Get-VBRBackupSession | Where-Object {$_.JobType -eq "Backup" -or $_.JobType -eq "Replica" -and $_.EndTime -ge [DateTime]::Today.AddDays(-1).AddHours(17) -and $_.EndTime -lt [DateTime]::Today.AddHours(04) -and $_ -notin $excludevms.VM.Name}

foreach ($session in $vbrsessions) {
foreach ($vm in ($session.gettasksessions() | ForEach-Object { $_ | Select-object @{Name="VMname";Expression={$_.Name}}})) {

$VMObj = $Result | where {$_.VMName -eq $vm.VMname }
if ($VMObj){
$VMObj.backed_up = $True

}

}
}

}

if ([DateTime]::Today.AddDays(-1).DayOfWeek -eq "Sunday") {

}

if ([DateTime]::Today.AddDays(-1).DayOfWeek -ne "Saturday" -or "Sunday"){
$vbrsessions = Get-VBRBackupSession | Where-Object {$_.JobType -eq "Backup" -or $_.JobType -eq "Replica" -and $_.EndTime -ge [DateTime]::Today.AddDays(-1).AddHours(17) -and $_.EndTime -lt [DateTime]::Today.AddHours(15) -and $_ -notin $excludevms.VM.Name}

foreach ($session in $vbrsessions) {
foreach ($vm in ($session.gettasksessions() | ForEach-Object { $_ | Select-object @{Name="VMname";Expression={$_.Name}}})) {

$VMObj = $Result | where {$_.VMName -eq $vm.VMname }
if ($VMObj){
$VMObj.backed_up = $True

}

}
}
}
if ([DateTime]::Today.AddDays(-2).DayOfWeek -eq "Saturday") {

$vbrsessions = Get-VBRBackupSession | Where-Object {$_.JobType -eq "Backup" -or $_.JobType -eq "Replica" -and $_.EndTime -ge [DateTime]::Today.AddDays(-2).AddHours(05) -and $_.EndTime -lt [DateTime]::Today.AddDays(-1).AddHours(23) -and $_ -notin $excludevms.VM.Name}

foreach ($session in $vbrsessions) {
foreach ($vm in ($session.gettasksessions() | ForEach-Object { $_ | Select-object @{Name="VMname";Expression={$_.Name}}})) {

$VMObj = $Result | where {$_.VMName -eq $vm.VMname }
if ($VMObj){
$VMObj.backed_up2 = $True

}

}
}

}

# Find all successfully backed up VMs in selected sessions (i.e. VMs not ending in failure) and update status to "Protected"

if ([DateTime]::Today.AddDays(-2).DayOfWeek -eq "Friday") {

$vbrsessions = Get-VBRBackupSession | Where-Object {$_.JobType -eq "Backup" -or $_.JobType -eq "Replica" -and $_.EndTime -ge [DateTime]::Today.AddDays(-2).AddHours(17) -and $_.EndTime -lt [DateTime]::Today.AddDays(-1).AddHours(04) -and $_ -notin $excludevms.VM.Name}

foreach ($session in $vbrsessions) {
foreach ($vm in ($session.gettasksessions() | ForEach-Object { $_ | Select-object @{Name="VMname";Expression={$_.Name}}})) {

$VMObj = $Result | where {$_.VMName -eq $vm.VMname }
if ($VMObj){
$VMObj.backed_up2 = $True

}

}
}

}

if ([DateTime]::Today.AddDays(-2).DayOfWeek -eq "Sunday") {

}

if ([DateTime]::Today.AddDays(-2).DayOfWeek -ne "Saturday" -or "Sunday"){
$vbrsessions = Get-VBRBackupSession | Where-Object {$_.JobType -eq "Backup" -or $_.JobType -eq "Replica" -and $_.EndTime -ge [DateTime]::Today.AddDays(-2).AddHours(17) -and $_.EndTime -lt [DateTime]::Today.AddDays(-1).AddHours(15)-and $_ -notin $excludevms.VM.Name}

foreach ($session in $vbrsessions) {
foreach ($vm in ($session.gettasksessions() | ForEach-Object { $_ | Select-object @{Name="VMname";Expression={$_.Name}}})) {

$VMObj = $Result | where {$_.VMName -eq $vm.VMname }
if ($VMObj){
$VMObj.backed_up2 = $True

}

}

}

}

$vbrsessions = ""
if ([DateTime]::Today.AddDays(-3).DayOfWeek -eq "Saturday") {

$vbrsessions = Get-VBRBackupSession | Where-Object {$_.JobType -eq "Backup" -or $_.JobType -eq "Replica" -and $_.EndTime -ge [DateTime]::Today.AddDays(-3).AddHours(05) -and $_.EndTime -lt [DateTime]::Today.AddDays(-2).AddHours(23) -and $_ -notin $excludevms.VM.Name}

foreach ($session in $vbrsessions) {
foreach ($vm in ($session.gettasksessions() | ForEach-Object { $_ | Select-object @{Name="VMname";Expression={$_.Name}}})) {

$VMObj = $Result | where {$_.VMName -eq $vm.VMname }
if ($VMObj){
$VMObj.backed_up3 = $True

}

}
}

}

if ([DateTime]::Today.AddDays(-3).DayOfWeek -eq "Friday") {

$vbrsessions = Get-VBRBackupSession | Where-Object {$_.JobType -eq "Backup" -or $_.JobType -eq "Replica" -and $_.EndTime -ge [DateTime]::Today.AddDays(-3).AddHours(17) -and $_.EndTime -lt [DateTime]::Today.AddDays(-2).AddHours(04) -and $_ -notin $excludevms.VM.Name}

foreach ($session in $vbrsessions) {
foreach ($vm in ($session.gettasksessions() | ForEach-Object { $_ | Select-object @{Name="VMname";Expression={$_.Name}}})) {

$VMObj = $Result | where {$_.VMName -eq $vm.VMname }
if ($VMObj){
$VMObj.backed_up3 = $True

}

}
}

}
if ([DateTime]::Today.AddDays(-3).DayOfWeek -eq "Sunday") {

}

if ([DateTime]::Today.AddDays(-3).DayOfWeek -ne "Saturday" -or "Sunday"){
$vbrsessions = Get-VBRBackupSession | Where-Object {$_.JobType -eq "Backup" -or $_.JobType -eq "Replica" -and $_.EndTime -ge [DateTime]::Today.AddDays(-3).AddHours(17) -and $_.EndTime -lt [DateTime]::Today.AddDays(-2).AddHours(15)-and $_ -notin $excludevms.VM.Name}

foreach ($session in $vbrsessions) {
foreach ($vm in ($session.gettasksessions() | ForEach-Object { $_ | Select-object @{Name="VMname";Expression={$_.Name}}})) {

$VMObj = $Result | where {$_.VMName -eq $vm.VMname }
if ($VMObj){
$VMObj.backed_up3 = $True

}

}
}
}

$vbrsessions = ""

if ([DateTime]::Today.AddDays(-4).DayOfWeek -eq "Saturday") {

$vbrsessions = Get-VBRBackupSession | Where-Object {$_.JobType -eq "Backup" -or $_.JobType -eq "Replica" -and $_.EndTime -ge [DateTime]::Today.AddDays(-4).AddHours(05) -and $_.EndTime -lt [DateTime]::Today.AddDays(-3).AddHours(23) -and $_ -notin $excludevms.VM.Name}

foreach ($session in $vbrsessions) {
foreach ($vm in ($session.gettasksessions() | ForEach-Object { $_ | Select-object @{Name="VMname";Expression={$_.Name}}})) {

$VMObj = $Result | where {$_.VMName -eq $vm.VMname }
if ($VMObj){
$VMObj.backed_up4 = $True

}

}
}

}

if ([DateTime]::Today.AddDays(-4).DayOfWeek -eq "Friday") {

$vbrsessions = Get-VBRBackupSession | Where-Object {$_.JobType -eq "Backup" -or $_.JobType -eq "Replica" -and $_.EndTime -ge [DateTime]::Today.AddDays(-4).AddHours(17) -and $_.EndTime -lt [DateTime]::Today.AddDays(-3).AddHours(04) -and $_ -notin $excludevms.VM.Name}

foreach ($session in $vbrsessions) {
foreach ($vm in ($session.gettasksessions() | ForEach-Object { $_ | Select-object @{Name="VMname";Expression={$_.Name}}})) {

$VMObj = $Result | where {$_.VMName -eq $vm.VMname }
if ($VMObj){
$VMObj.backed_up4 = $True

}

}
}

}
if ([DateTime]::Today.AddDays(-4).DayOfWeek -eq "Sunday") {

}

if ([DateTime]::Today.AddDays(-4).DayOfWeek -ne "Saturday" -or "Sunday"){
$vbrsessions = Get-VBRBackupSession | Where-Object {$_.JobType -eq "Backup" -or $_.JobType -eq "Replica" -and $_.EndTime -ge [DateTime]::Today.AddDays(-4).AddHours(17) -and $_.EndTime -lt [DateTime]::Today.AddDays(-3).AddHours(15)-and $_ -notin $excludevms.VM.Name}

foreach ($session in $vbrsessions) {
foreach ($vm in ($session.gettasksessions() | ForEach-Object { $_ | Select-object @{Name="VMname";Expression={$_.Name}}})) {

$VMObj = $Result | where {$_.VMName -eq $vm.VMname }
if ($VMObj){
$VMObj.backed_up4 = $True

}

}
}
}

$Comments = 'Comments'

if ([DateTime]::Today.AddDays(-1).DayOfWeek -eq "Sunday"){
$1days = [DateTime]::Today.AddDays(-1).ToString('ddd d MMM yyy')
$2days = 'Weekend of ' + [DateTime]::Today.AddDays(-2).ToString('d MMM yyy')
$3days = [DateTime]::Today.AddDays(-3).ToString('ddd d MMM yyy')
$4days = [DateTime]::Today.AddDays(-4).ToString('ddd d MMM yyy')
$TableName = "Backups"
$table = New-Object system.Data.DataTable "$TableName"
$col2 = New-Object system.Data.DataColumn VM, ([string])
$col8 = New-Object system.Data.DataColumn $4days, ([string])
$col9 = New-Object system.Data.DataColumn $3days, ([string])
$col10 = New-Object system.Data.DataColumn $2days, ([string])
$col12 = New-Object system.Data.DataColumn Comments, ([string])

$table.columns.add($col2)
$table.columns.add($col8)
$table.columns.add($col9)
$table.columns.add($col10)
$table.columns.add($col12)
foreach ($vm in $Result) {

$row = $table.NewRow();$row.VM=$vm.VMname;$row.$4days=$vm.backed_up4;$row.$3days=$vm.backed_up3;$row.$2days=$vm.backed_up2;$table.Rows.Add($row)#;$table.Rows.Add($row)

}

$datetoday=get-date -format D
$reportdate=get-date -format "yyyy-MMM-d"
$ResultsText = "The following machines in Woking have been successfully backed up using Veeam in the past " + $AgeAlert + " Day(s)"
$ResultsAlert = "Good"

############################################################################################################
# Output #
#------------------------

$OutText = $ResultsText
$OutData = $Table | Select-Object VM,$4days,$3days,$2days,$Comments | Sort-Object VM
$OutAlert = $ResultsAlert
$Attachment = ""
}

if ([DateTime]::Today.AddDays(-2).DayOfWeek -eq "Sunday"){
$1days = [DateTime]::Today.AddDays(-1).ToString('ddd d MMM yyy')
$2days = [DateTime]::Today.AddDays(-2).ToString('ddd d MMM yyy')
$3days = 'Weekend of ' + [DateTime]::Today.AddDays(-3).ToString('d MMM yyy')
$4days = [DateTime]::Today.AddDays(-4).ToString('ddd d MMM yyy')
$TableName = "Backups"
$table = New-Object system.Data.DataTable "$TableName"
$col2 = New-Object system.Data.DataColumn VM, ([string])
$col8 = New-Object system.Data.DataColumn $4days, ([string])
$col9 = New-Object system.Data.DataColumn $3days, ([string])
$col11 = New-Object system.Data.DataColumn $1days, ([string])
$col12 = New-Object system.Data.DataColumn Comments, ([string])

$table.columns.add($col2)
$table.columns.add($col8)
$table.columns.add($col9)
$table.columns.add($col11)
$table.columns.add($col12)

foreach ($vm in $Result) {
$row = $table.NewRow();$row.VM=$vm.VMname;$row.$4days=$vm.backed_up4;$row.$3days=$vm.backed_up3;$row.$1days=$vm.backed_up;$table.Rows.Add($row)#;$table.Rows.Add($row)

}

$datetoday=get-date -format D
$reportdate=get-date -format "yyyy-MMM-d"
$ResultsText = "The following machines in Woking have been successfully backed up using Veeam in the past " + $AgeAlert + " Day(s)"
$ResultsAlert = "Good"
############################################################################################################
# Output #
#------------------------

$OutText = $ResultsText
$OutData = $Table | Select-Object VM,$4days,$3days,$1days,$Comments | Sort-Object VM
$OutAlert = $ResultsAlert
$Attachment = ""
}

if ([DateTime]::Today.AddDays(-3).DayOfWeek -eq "Sunday"){
$1days = [DateTime]::Today.AddDays(-1).ToString('ddd d MMM yyy')
$2days = [DateTime]::Today.AddDays(-2).ToString('ddd d MMM yyy')
$3days = [DateTime]::Today.AddDays(-3).ToString('ddd d MMM yyy')
$4days = 'Weekend of ' + [DateTime]::Today.AddDays(-4).ToString('d MMM yyy')
$TableName = "Backups"
$table = New-Object system.Data.DataTable "$TableName"
$col2 = New-Object system.Data.DataColumn VM, ([string])
$col8 = New-Object system.Data.DataColumn $4days, ([string])
$col10 = New-Object system.Data.DataColumn $2days, ([string])
$col11 = New-Object system.Data.DataColumn $1days, ([string])
$col12 = New-Object system.Data.DataColumn Comments, ([string])

$table.columns.add($col2)
$table.columns.add($col8)
$table.columns.add($col10)
$table.columns.add($col11)
$table.columns.add($col12)

foreach ($vm in $Result) {
$row = $table.NewRow();$row.VM=$vm.VMname;$row.$4days=$vm.backed_up4;$row.$2days=$vm.backed_up2;$row.$1days=$vm.backed_up;$table.Rows.Add($row)#;$table.Rows.Add($row)

}
$datetoday=get-date -format D
$reportdate=get-date -format "yyyy-MMM-d"
$ResultsText = "The following machines in Woking have been successfully backed up using Veeam in the past " + $AgeAlert + " Day(s)"
$ResultsAlert = "Good"

############################################################################################################
# Output #
#------------------------

$OutText = $ResultsText
$OutData = $Table | Select-Object VM,$4days,$2days,$1days,$Comments | Sort-Object VM
$OutAlert = $ResultsAlert
$Attachment = ""
}

if ([DateTime]::Today.AddDays(-4).DayOfWeek -eq "Sunday"){
$1days = [DateTime]::Today.AddDays(-1).ToString('ddd d MMM yyy')
$2days = [DateTime]::Today.AddDays(-2).ToString('ddd d MMM yyy')
$3days = [DateTime]::Today.AddDays(-3).ToString('ddd d MMM yyy')
$4days = [DateTime]::Today.AddDays(-4).ToString('ddd d MMM yyy')

$TableName = "Backups"
$table = New-Object system.Data.DataTable "$TableName"
$col2 = New-Object system.Data.DataColumn VM, ([string])
$col9 = New-Object system.Data.DataColumn $3days, ([string])
$col10 = New-Object system.Data.DataColumn $2days, ([string])
$col11 = New-Object system.Data.DataColumn $1days, ([string])
$col12 = New-Object system.Data.DataColumn Comments, ([string])

$table.columns.add($col2)
$table.columns.add($col9)
$table.columns.add($col10)
$table.columns.add($col11)
$table.columns.add($col12)

foreach ($vm in $Result) {
$row = $table.NewRow();$row.VM=$vm.VMname;$row.$3days=$vm.backed_up3;$row.$2days=$vm.backed_up2;$row.$1days=$vm.backed_up;$table.Rows.Add($row)#;$table.Rows.Add($row)

}
$datetoday=get-date -format D
$reportdate=get-date -format "yyyy-MMM-d"
$ResultsText = "The following machines in Woking have been successfully backed up using Veeam in the past " + $AgeAlert + " Day(s)"
$ResultsAlert = "Good"
############################################################################################################
# Output #
#------------------------

$OutText = $ResultsText
$OutData = $Table | Select-Object VM,$3days,$2days,$1days,$Comments | Sort-Object VM
$OutAlert = $ResultsAlert
$Attachment = ""
}

 

 

 

About the Author

Dinger

I have been in IT for the past 15 years and using virtualisation technologies for around the past 8 years. I started, as quite a lot of people do, working with PCs after playing with such iconic systems like the ZX81, ZX Spectrum and then progressing through 386s, 486s, Pentiums etc. After being headhunted at sixth form to work for a small company based around Hertfordshire, UK. I began working with small businesses and gaining a lot of hardware experience. Three years later, after helping to increase the size of the business, I needed to gain exposure to a larger environment to progress my own career. I joined a large manufacturing company around Electronic Test and Measurement which progressed my skills onto more PC work, hardware work and then onto Server Operating Systems. I progressed again onto a consultancy company based in Reading, UK. Initially working as an engineer performing hardware / software installations for larger companies contracted out to the consultancy company, I moved up into a Consultant position continuing my travel across the UK assisting and providing solutions to companies. I finally moved on again to my current position, working back in Hertfordshire, UK. Again working for a large manufacturing company, this time with over 50,000 users worldwide. I am responsible for the datacenter hardware, the storage environment, the vmware environment and also implementing their new Citrix XenApp farm. My days are busy but also productive, its a friendly environment and in my four years of being with the company, I have seen many changes in technology and infrastructure in use within the company. About the site I started this site as I had been thinking of having more of a presence on the web for a while. On a daily basis, I perform tasks and use tools that others may not use or may not think to do and therefore I thought that I would share some of these experiences and tips with others to help with their day to day work. Currently, my main focus of work is around VMware and Veeam Backup & Replication but hopefully as my tasks progress, I’ll be able to share useful bits of information about other areas of IT as well.

2 thoughts on “3 day Veeam Backup Report – Powercli

    • Author gravatar

      Hi Chris. Can yo drop me a line. I’d like to find out more about the running of this script. I have SOX audit coming at me and this looks to be a good solution. We don’t use tags but I can comment those lines out of the script.

      • Author gravatar

        Hi John,
        This script works quite well for us. The reason we use the Tags is that we have a number of VMs that we either do not back up with Veeam or need to be excluded for other reasons – tagging the VMs allows us to exclude those VMs from the report.

        Let me know what assistance you require.

        Thanks

        Chris

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.