Skip to content

Instantly share code, notes, and snippets.

@andreagx
Last active July 7, 2021 08:21
Show Gist options
  • Select an option

  • Save andreagx/73c24f65e66529ad1996 to your computer and use it in GitHub Desktop.

Select an option

Save andreagx/73c24f65e66529ad1996 to your computer and use it in GitHub Desktop.
WindowsBackupEmailReportv2
<#
.NOTES
===========================================================================
Created with: Windows Powershell ISE
Created on: 22/10/2015 03:16 V2.0.1
Created by: Andrea Gallazzi
Filename: backup_email_V2.ps1
===========================================================================
.DESCRIPTION
The script send by email a report with Windows Server Backup activity and the target status
If backup fail or target space is under 10% the row in the table becomes with a red background
File Location: C:\Users\Public\BackupLog.htm
http://andreagx.blogspot.it/2014/01/windows-server-backup-inviare-un-report.html
#>
#Specify here the name of your customer
$Customer = "YOUR CUSTOMER"
#hostname
$Hostname = $env:COMPUTERNAME
# Output file path
$path = $env:public
$OutputFile = $path + "\BackupLog.htm"
# (Get-Date).AddDayS(-1) is from yesterday
# $date = (Get-Date).AddDayS(-1)
<#
*****Waring*******
# *****Waring******* This two lines is required only on Windows Server 2012
$orgCulture = Get-Culture
[System.Threading.Thread]::CurrentThread.CurrentCulture = New-Object "System.Globalization.CultureInfo" "en-US"
*****Waring*******
#>
#ID catched = 1,4,5,8,9,13,14,17,18,19,20,21,22,49,50,51,52,100,517,518,521,527,528,544,545,546,561,564,612
$getevt = Get-WinEvent -ProviderName "Microsoft-Windows-Backup" | Where-Object {
$_.ID -eq "1" -or
$_.ID -eq "4" -or
$_.ID -eq "8" -or
$_.ID -eq "9" -or
$_.ID -eq "13" -or
$_.ID -eq "14" -or
$_.ID -eq "17" -or
$_.ID -eq "18" -or
$_.ID -eq "19" -or
$_.ID -eq "20" -or
$_.ID -eq "21" -or
$_.ID -eq "22" -or
$_.ID -eq "49" -or
$_.ID -eq "50" -or
$_.ID -eq "51" -or
$_.ID -eq "52" -or
$_.ID -eq "100" -or
$_.ID -eq "517" -or
$_.ID -eq "518" -or
$_.ID -eq "521" -or
$_.ID -eq "527" -or
$_.ID -eq "528" -or
$_.ID -eq "544" -or
$_.ID -eq "545" -or
$_.ID -eq "546" -or
$_.ID -eq "561" -or
$_.ID -eq "564" -or
$_.ID -eq"612" } |
Select-Object TimeCreated, Message, ID, LevelDisplayName -first 6 | Sort-Object TimeCreated -descending
$evid_html = $getevt | ConvertTo-Html -PreContent "<p>Backup (Operational) - Last 6 Events :</p>" -Fragment
## Get-Summary and shadows on line
$SumC = Get-WBSummary | Select-Object CurrentOperationStatus | FW
$SumCS = Out-String -InputObject $SumC
$SumL = Get-WBSummary | Select-Object LastSuccessfulBackupTime | FW
$SumLS = Out-String -InputObject $SumL
$SumN = Get-WBSummary | Select-Object NextBackupTime | FW
$SumNS = Out-String -InputObject $SumN
$V = vssadmin list shadows
$Numberofcopies = ($V -like "*shadow*/*").count
$regex = "([0-9]{2}[/|-]){2}[0-9]{4}"
$Oldstr = ($V | select-string -Pattern $regex | Select-Object Matches -First 1 | fw | Out-String).trim()
$Oldestcopy = $Oldstr.trim("{","}")
function WBSum ( $OldestCopyOnLine, $LastSuccessBackupTime, $NextBackupTIme,$NumberOfCopiesOnLine, $CurrentOperation)
{
New-Object -TypeName psObject -Property ([ordered]@{
'NumberOfCopiesOnLine' = $Numberofcopies
'LastSuccessBackupTime' = $SumLS.Trim()
'NextBackupTIme' = $SumNS.Trim()
'OldestCopyOnLine' = $OldestCopy
'CurrentOperation' = $SumCS.Trim()
})
}
$Summary = WBSum | ConvertTo-Html -PreContent "<p>Backup (Summary):</p>" -Fragment
#Free Space on backup target.
$drives = Get-WBDisk | Where-Object { $_.ContainsBackup -eq "True" }
$drives_html = $drives | Select @{ Name = "Drive"; Expression = { $_.DiskName } },
@{ Name = "TargetSize(GB)"; Expression = { $_.TotalSpace/1GB -as [int] } },
@{ Name = "TargetUsed(GB)"; Expression = { "{0:N2}" -f (($_.TotalSpace - $_.Freespace)/1GB) } },
@{ Name = "TargetFree(Gb)"; Expression = { "{0:N2}" -f ($_.FreeSpace/1GB) } },
@{ Name = "TargetFree(%)"; Expression = { "{0:N2}" -f (($_.FreeSpace/$_.TotalSpace) * 100) } } | ConvertTo-Html -PreContent "<p>Backup (Target):</p>" -Fragment
#Free Space on logical disk.
$lu_html = Get-WmiObject -Class Win32_LogicalDisk |
Where-Object { $_.DriveType -ne 5 } |
Sort-Object -Property Name |
Select-Object Name, VolumeName, FileSystem, VolumeDirty, Description, `
@{ "Label" = "DiskSize(GB)"; "Expression" = { "{0:N2}" -f ($_.Size/1GB) } }, `
@{ "Label" = "FreeSpace(GB)"; "Expression" = { "{0:N2}" -f ($_.FreeSpace/1GB) } }, `
@{ "Label" = "LuFree(%)"; "Expression" = { "{0:N2}" -f ($_.FreeSpace/$_.Size * 100) } } | ConvertTo-Html -PreContent "<p>Logical Unit - Free Space:</p>" -Fragment
# Set enumeration limit to unlimited
$FormatEnumerationLimit = -1
# Get-WBPolicy
$cbt = Get-WBPolicy | Select-Object ComponentsToBackup | FW
$cbtS = Out-String -InputObject $cbt
$vtb = Get-WBPolicy | Select-Object VolumesToBackup | FW
$vtbS = Out-String -InputObject $vtb
$vssbo = Get-WBPolicy | Select-Object VssBackupOptions | FW
$vssboS = Out-String -InputObject $vssbo
$ss = Get-WBPolicy | Select-Object SystemState | FW
$ssS = Out-String -InputObject $ss
function Get-WBPol ( $ComponentsToBackup, $VolumesToBackup, $VssBackupOptions,$SystemState)
{
New-Object -TypeName psObject -Property ([ordered]@{
'ComponentsToBackup' = $cbts.Trim().Trim("{","}")
'VolumesToBackup' = $vtbS.Trim().Trim("{","}")
'VssBackupOptions' = $vssboS.Trim().Trim("{","}")
'SystemState' = $ssS.Trim().Trim("{","}")
})
}
$WBPol = Get-WBPol | ConvertTo-Html -PreContent "<p>WBpolicy:</p>" -Fragment
#Html
$header = "<p>Reporting Backup Status On: " + $hostname + " - " + " Customer: " + $Customer + "</p>"
$a = @"
<meta name="Andrea Gallazzi - andreagx.blogspot.com" content="Windows Server Backup Report by E-mail V2" />
<title>Windows Server Backup Report by E-mail v 2.0</title>
<style>
Body {
font-family: Verdana;
font-size: 11px
}
Table {
border-width: 1px;
border-style: solid;
border-color: gray;
border-collapse: collapse;
background-color: #4e6387;
width: 100%;
margin-left 10%;
margin-right auto;
position: relative;
font-family: Verdana;
font-size: 11px;
color: white;
box-shadow: 10px 10px 5px #BDBDBD;
}
Th {
border-width: 1px;
padding: 5px;
border-style: solid;
border-color: gray;
background-color: #48597A;
color: #F4F7FF;
text-align: left;
font-family: Verdana;
font-size: 11px;
color: White
}
Td {
border-width: 1px;
padding: 5px;
border-style: solid;
border-color: gray;
font-family: Verdana;
font-size: 11px;
color: White
}
H2 {
padding: 5px;
border-style: solid;
border-color: gray;
font-family: Verdana;
font-size: 14px;
color: White
}
H1 {
color: black;
font-family: Verdana;
font-size: 11px;
color: #566B95
}
p {
font-family: Verdana;
font-size: 14px;
color: #566B95
}
</style>
"@
Add-Type -AssemblyName System.Xml.Linq
#Convert
$xml = [System.Xml.Linq.XDocument]::Parse("$(ConvertTo-HTML -Title "Server Status" -head $a -Body "$evid_html $drives_html $lu_html $Summary $WBPol")")
# Find the index of the column you want to format:
$wsIndex1 = (($xml.Descendants("{http://www.w3.org/1999/xhtml}th") | Where-Object { $_.Value -eq "LevelDisplayName" }).NodesBeforeSelf() | Measure-Object).Count
$wsIndex2 = (($xml.Descendants("{http://www.w3.org/1999/xhtml}th") | Where-Object { $_.Value -eq "ID" }).NodesBeforeSelf() | Measure-Object).Count
$wsIndex3 = (($xml.Descendants("{http://www.w3.org/1999/xhtml}th") | Where-Object { $_.Value -eq "LuFree(%)" }).NodesBeforeSelf() | Measure-Object).Count
$wsIndex4 = (($xml.Descendants("{http://www.w3.org/1999/xhtml}th") | Where-Object { $_.Value -eq "TargetFree(%)" }).NodesBeforeSelf() | Measure-Object).Count
# Event
switch ($xml.Descendants("{http://www.w3.org/1999/xhtml}td") | Where { ($_.NodesBeforeSelf() | Measure).Count -eq $wsIndex1 })
{
{ $_.Value -eq "Error" } { $_.Parent.SetAttributeValue("style", "background: Red;"); continue }
{ $_.Value -eq "Errore" } { $_.Parent.SetAttributeValue("style", "background: Red;"); continue }
{ $_.Value -eq "Warning" } { $_.Parent.SetAttributeValue("style", "background: Orange;"); continue }
{ $_.Value -eq "Avviso" } { $_.Parent.SetAttributeValue("style", "background: Orange") }
}
# Target ID
switch ($xml.Descendants("{http://www.w3.org/1999/xhtml}td") | Where { ($_.NodesBeforeSelf() | Measure).Count -eq $wsIndex2 })
{
{ $_.Value -eq 4 } { $_.Parent.SetAttributeValue("style", "background: Green"); continue }
}
# Target free space
switch ($xml.Descendants("{http://www.w3.org/1999/xhtml}td") | Where { ($_.NodesBeforeSelf() | Measure).Count -eq $wsIndex4 })
{
{ $_.Value -lt 20} { $_.Parent.SetAttributeValue("style", "background: Purple") }
}
#LU free space
switch ($xml.Descendants("{http://www.w3.org/1999/xhtml}td") | Where { ($_.NodesBeforeSelf() | Measure).Count -eq $wsIndex3 })
{
{ $_.Value -lt 10} { $_.Parent.SetAttributeValue("style", "background: Orange") }
}
# Save the html output into a file
$xml.Save("$OutputFile")
# Send Email
$bodycont = (Get-Content $OutputFile)
# smtp server
$emailSmtpServer = "smtp.domain.com"
$emailSmtpServerPort = "587"
$emailSmtpUser = "email@domain.com"
$emailSmtpPass = "password"
# recipient
$emailFrom = "WSB Email Report V2 <email@domain.com>"
$emailTo = "email1@domain.com,email2@domain.com"
# message
$emailMessage = New-Object System.Net.Mail.MailMessage( $emailFrom , $emailTo )
$emailMessage.Subject = "##" + " - " + $Customer + " - " + "Backup report from: " + $Hostname + " ##"
$emailMessage.IsBodyHtml = $true
$emailMessage.Body = $bodycont
#client
$SMTPClient = New-Object System.Net.Mail.SmtpClient( $emailSmtpServer , $emailSmtpServerPort )
$SMTPClient.EnableSsl = $true
$SMTPClient.Credentials = New-Object System.Net.NetworkCredential( $emailSmtpUser , $emailSmtpPass );
$SMTPClient.Send( $emailMessage )
#>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment