The following is an example of the report's output:
The "msgs" have been truncated for the screenshot.
The following code was written to support multiple Veeam servers, not all code is supported by Veeam, uses a config.xml file, uses Powershell SecureStrings to encrypt passwords (http://technet.microsoft.com/en-us/maga ... 14574.aspx), uses PowerShell Remoting (https://blogs.technet.com/b/heyscriptin ... mands.aspx), runs as a scheduled task, if I had to rewrite this today I would probably change some things but it works , and lastly use at your own risk:
Code: Select all
$ErrorActionPreference = "stop"
#html styling
$style = "<style>"
$style = $style + "TABLE{border-width: 1px;border-style: solid;border-color: black;border-collapse: collapse;}"
$style = $style + "TH{border-width: 1px;padding: 1px;border-style:double;border-color: black;}"
$style = $style + "TD{border-width: 1px;padding: 5px;border-style:double;border-color: black;}"
$style = $style + "</style>"
#For debugging
#Get-PSSession | Remove-PSSession
#Reading config file
$ScriptPath = Split-Path -parent $MyInvocation.MyCommand.Definition
$Config = [xml](Get-Content "$ScriptPath\config.xml")
###Create a new PSSession to each server in $VeeamSrvs and assign to a variable
$VeeamCreds = New-Object System.Management.Automation.PSCredential $Config.AppSettings.Creds.veeam.username, ($Config.AppSettings.Creds.veeam.EncryptedPass | ConvertTo-SecureString)
$VeeamSrvSessions = New-Object System.Collections.ArrayList
foreach ($VeeamSrv in $Config.AppSettings.VeeamSrvs.HostName)
{
$VeeamSrvSessions.add((New-PSSession -ComputerName $VeeamSrv -Credential $VeeamCreds)) | out-null
}
###
###Connect to each Veeam Server and add the Veeam Snapin
foreach ($VeeamSrvSession in $VeeamSrvSessions)
{
Invoke-Command -session $VeeamSrvSession -ScriptBlock `
{
#Add Veeam snapin if needed
if ( (Get-PSSnapin -Name VeeamPSSnapIn -ErrorAction SilentlyContinue) -eq $null )
{
Add-PsSnapin -Name VeeamPSSnapIn
}
} -AsJob
}
Get-Job | Wait-Job
###
###Connect to all Veeam servers and return status on jobs that have warnings or failures and have completed within the last day
foreach ($VeeamSrvSession in $VeeamSrvSessions)
{
Invoke-Command -session $VeeamSrvSession -ScriptBlock `
{$JobStatus = (Get-VBRJob | Where-Object {$_.GetLastResult() -ne "Success" -and $_.GetLastResult() -ne "None" -and $_.findlastsession().progress.stoptime -ge (Get-Date).addhours(-24)}) |
ForEach-Object {$_ | Select-object @{Name="Job";Expression={$_.Name}}, @{Name="Status";Expression={$_.GetLastResult()}}, `
@{Name="ID";Expression={$_.id}}, @{Name="Job Msg";Expression={$_.FindLastSession().info.description}}, @{Name="Session";Expression={$_.FindLastSession()}}}
if ($JobStatus -ne $null)
{
#Adding new properties to array
$JobStatus | ForEach-Object {$_ | Add-Member -MemberType NoteProperty "Server" -Value $Env:COMPUTERNAME}
$JobStatus | ForEach-Object {$_ | Add-Member -MemberType NoteProperty "VM Msg" -Value $null}
#Collecting VM failure info
foreach ($JobStat in $JobStatus)
{
#Not supported by Veeam
$Info = [Veeam.Backup.Core.CBackupTaskSession]::GetByJobSession(($JobStat.Session | foreach-object {$_.info}).id)
$JobStat."VM Msg" = ($info | ForEach-Object {$_} | Where-Object {$_.status -ne "Success"}) |
Foreach-object {$_ | Select-Object @{Name="VM";Expression={$_.ObjectName}}, @{Name="Reason";Expression={$_.Reason}} | Format-List | Out-String}
}
$JobStatus
}
} -AsJob
}
Get-Job | Wait-Job
$JobStatus = Get-Job | Receive-Job
###
#Closing open PS sessions
Get-PSSession | Remove-PSSession
###Sending report
#Mail settings
$MailSrv = $Config.AppSettings.Email.SRV
$MailFrom = $Config.AppSettings.Email.From
$MailTo = $Config.AppSettings.Email.To
$MailSbjt = "Veeam Job Status Report $(get-date)"
$MailBody = ($JobStatus | Select-Object Job, Status, "Job Msg", "VM Msg", Server | Sort-Object Status -Descending | ConvertTo-Html -Head $style | Out-String) `
-replace ("VM :","<p></p><b>VM:</b>") `
-replace ("Reason :","<p></p><b>Reason:</b>") `
-replace ("<td>Failed","<td bgcolor=red>Failed")
Send-MailMessage -SmtpServer $MailSrv -From $MailFrom -To $MailTo -Subject $MailSbjt -Body $MailBody -BodyAsHtml
###
Code: Select all
<!-- file.xml -->
<AppSettings>
<VeeamSrvs>
<HostName>veeam-srv1.domain.com</HostName>
<HostName>veeam-srv2.domain.com</HostName>
<HostName>veeam-srv3.domain.com</HostName>
</VeeamSrvs>
<Creds>
<Veeam>
<Username>user@domain.com</Username>
<EncryptedPass></EncryptedPass>
</Veeam>
</Creds>
<Email>
<SRV>veeam.domain.com</SRV>
<From>veeam-report@domain.com</From>
<To>user@domain.com</To>
</Email>
</AppSettings>