Background
Jocha work with a lot of startup companies and small-business owners, which is great in so many ways. While it gives us the possibility to design and set everything up from scratch, with all the best practices, it usually means working with a smaller budget compared to the larger corporations.
Windows Backup is a great built-in feature in Windows Server, however it lacks a useful reporting feature. We’ve built a PowerShell-script that will give you a nice report summary of the last backup job. As always we recommend using the last version of Windows Management Framework for this script.
Requirements
– Elevated PowerShell-session.
– Windows Server Backup feature installed.
– At least Windows Management Framework 3.0
Solution
By using built-in functions and leveraging scripts and third-party products you can save a lot of money.
This PowerShell-script will retrieve the last backup job send an email with a report of the results.
<# .SYNOPSIS Windows Backup Mail Report Written by Joakim, http://jocha.se .DESCRIPTION Version 4.1 - Updated 2016-05-31 This script will mail a report from the latest Windows Backup job, can also fetch and generate reports from remote servers. The script requires at least PowerShell v3. .EXAMPLE To automate this script, setup a scheduled task. Name: Backup Email Task Description: Notifies backup admin of scheduled backup status Run whether user is logged on or not Trigger > On event > Log=Microsoft-Windows-Backup/Operational > Source=Backup > Event ID(s)= 4,5,8,9,17,22,49,50,52,100,517,518,521,527,528,544,545,546,561,564,612 Action: Start a Program Program: Powershell Arguments: -Command "C:\Scripts\WBJobReport.ps1" -ExecutionPolicy Bypass #> Add-PSSnapin Windows.ServerBackup -ErrorAction SilentlyContinue ####################################### #-------- Variables to change --------# # Uncomment the two rows below and row 207 to enable "Remote Report" generation. #$Servers = New-PSSession -Computername Server01, Server02, Server03 #Invoke-Command -Session $Servers { # Set your Company name $Company = "MyCompany" # Set the recipient/sender email-address $MailTo = "[email protected]" $MailFrom = "$Company Backup <[email protected]>" # SMTP user account password $MailUser = "MyUser" $MailPassword = "MyPassword" # SMTP Server $MailServer = "smtpserver.company.com" # SMTP Port $MailPort = 587 # If your server uses SSL, otherwise set to $false $UseSSL = $true #---- Don't change anything below ----# ####################################### Try { $CurrentTime = (Get-Date).ToString("yyyy-MM-dd HH:mm") $Computer = Get-Content env:computername $WBJob = Get-WBJob -Previous 1 $WBSummary = Get-WBSummary $WBLastSuccess = ($WBSummary.LastSuccessfulBackupTime).ToString("yyyy-MM-dd HH:mm") $WBResult = $WBSummary.LastBackupResultHR $WBErrorMsg = $WBJob.ErrorDescription + "`n" + $WBSummary.DetailedMessage $WBStartTime = $WBJob.StartTime $WBEndTime = $WBJob.EndTime $WBDuration = (New-TimeSpan -Start $WBStartTime -End $WBEndTime) $Password = ConvertTo-SecureString $MailPassword -AsPlainText -Force $Credentials = New-Object System.Management.Automation.PSCredential ($MailUser, $Password) Function FormatBytes { Param ( [System.Int64]$Bytes ) [string]$BigBytes = "" #Convert to TB If ($Bytes -ge 1TB) {$BigBytes = [math]::round($Bytes / 1TB, 2); $BigBytes += " TB"} #Convert to GB ElseIf ($Bytes -ge 1GB) {$BigBytes = [math]::round($Bytes / 1GB, 2); $BigBytes += " GB"} #Convert to MB ElseIf ($Bytes -ge 1MB) {$BigBytes = [math]::round($Bytes / 1MB, 2); $BigBytes += " MB"} #Convert to KB ElseIf ($Bytes -ge 1KB) {$BigBytes = [math]::round($Bytes / 1KB, 2); $BigBytes += " KB"} #If smaller than 1KB, leave at bytes. Else {$BigBytes = $Bytes; $BigBytes += " Bytes"} Return $BigBytes } Function Log-BackupItems { Param ( [System.String]$Name, [System.String]$Status, [System.Int64]$Bytes ) $Item = New-Object System.Object; $Item | Add-Member -Type NoteProperty -Name "Name" -Value $Name; $Item | Add-Member -Type NoteProperty -Name "Status" -Value $Status; $Item | Add-Member -Type NoteProperty -Name "Size" -Value (FormatBytes -Bytes $Bytes); Return $Item; } $results=@() $WBJob | % { $_.JobItems | % { $BackupItem = $null If ($_.Name -eq 'VolumeList') { $_ | % {$_.SubItemList | % { $BackupItem = Log-BackupItems -Name $_.Name -Status $_.State -Bytes $_.TotalBytes $results += $BackupItem }} } Else { $_ | % { $BackupItem = Log-BackupItems -Name $_.Name -Status $_.State -Bytes $_.TotalBytes $results += $BackupItem } } } } # Change Result of 0 to Success in green text and any other result as Failure in red text If ($WBResult -eq 0) { $WBResult = "Successful"} Else {$WBResult = "Failed"} # Assemble the HTML Report $HTMLMessage = @" <!DOCTYPE html> <html> <head> <title>$Company Backup Report for $Computer</title> <style> body { font-family: Verdana, Geneva, Arial, Helvetica, sans-serif; font-size: 12px } h3{ clear: both; font-size: 150%; margin-left: 20px;margin-top: 30px; } table { padding: 15px 0 20px; width: 500px; text-align: left; } td, th { padding: 0 20px 0 0; margin 0; text-align: left; } th { margin-top: 15px } a, a:visited { color: #2ea3f2; text-decoration: none; } #Report { width: 600px; } #Successful { color: green } #Failed { color: red } </style> </head> <body> <div id="Report"> <p><h3><a href="http://jocha.se">$Company Backup Report for $Computer</a></p></h3> <table id="summary"><tbody> <tr><td>Todays date:</td> <td>$CurrentTime</td></tr> <tr><td>Last Successful Backup:</td> <td>$WBLastSuccess</td></tr> <tr><td>Start time last backup:</td> <td>$WBStartTime</td></tr> <tr><td>End time last backup:</td> <td>$WBEndTime</td></tr> <tr><td>Duration last backup:</td> <td>$WBDuration</td></tr> <tr><td>Backup Result:</td> <td><b id="$WBResult">$WBResult</b></td></tr> <tr><td>Error Message (if applicable):</td> <td>$WBErrorMsg</td></tr></tbody></table> $( $html = $results | ConvertTo-HTML -Fragment $xml=[xml]$html $attr=$xml.CreateAttribute('id') $attr.Value='items' $xml.table.Attributes.Append($attr) | out-null $html=$xml.OuterXml | out-string $html ) </div> </body> </html> "@ $email = @{ SMTPServer = $MailServer UseSSL = $UseSSL BodyAsHtml = $true Port = $MailPort Credential = $Credentials Encoding = ([System.Text.Encoding]::UTF8) To = $MailTo From = $MailFrom Subject = "$WBResult Backup on $Computer" Body = $HTMLMessage } Send-MailMessage @email } Catch { $email = @{ SMTPServer = $MailServer BodyAsHtml = $true UseSSL = $UseSSL # Port is a PowerShell v3 variable Port = $MailPort Credential = $Credentials Encoding = ([System.Text.Encoding]::UTF8) To = $MailTo From = $MailFrom Subject = "Failed Backup on $Computer" Body = "The backup script failed to run!" } Send-MailMessage @email } # Uncomment below to enable "Remote Report". #}
We hope you’ve found this article helpful, feel free to share it on your social platforms.
Please let us know if you have any questions!
Hi
Great script.
I modified the mailto variable to send to multiple recipients.
$MailTo = @("[email protected]","[email protected]")
Grtz
Hello! first things first, Thank you very much for this script. It makes it extremely easy to stay on top of daily backups without having to log in to verify them manually.
Now on to my question, has anyone successfully made this into a deploy-able batch file or MSI installer yet? This would be great to be able to just select the Company name and email address and the script does everything else.
I would like to add a few more details of my experience.
Server 2012 R2:
This script works perfectly.
Server 2008 R2:
I have tried several 2008 servers and found myself having no luck getting this script to work. I have tested on PS2,3 and 4 with similar outcomes. For some reason, when I run in PS ISE, it asks me for a user/password. If I type the admin/pass in, the script errors out but if I type the email info it, it sends the email but the body says "The backup script failed to run!"
Do you have any advice?
Can this script be adapted for Windows 10 Backup?
Hi,
My email name/password are different than my admin credentials. The script will run if I comment out the mailuser/password, and use port 25 SSL= false and comment out credential in the email part (my ISP doesn't require authentification).
But I have to put my admin username/password in plain text in the script. Is there anyway to run this with the credentials from the scheduled task?
Move these 2 lines up to the username/password section
$Password = ConvertTo-SecureString $MailPassword -AsPlainText -Force
$Credentials = New-Object System.Management.Automation.PSCredential ($MailUser, $Password)
Thanks! It works good so far.
Did someone try to configure a scheduled task in MS-Server 2016?
I'm not able to add several Event-IDs (Error: only numbers are accepted).
Any idea?
Yes. you have to create a "Custom" filter. I struggled with this for a little while before figuring it out. See the Photo that i attached.
http:// i64.tinypic.com /166x7o5.jpg
I get same on Server 2012 R2 – custom filter required
Script great for 2012 r2. I have a problem with run on 2008 and SBS 2011 – The backup sctipt failed to run. I change the script that Lee said (delete Send-MailMessage and use smtpClient but his tip is for old version of script and didn't match line numbers of new one. Could anyone help? Do you have working 2008 script?
Hi,
Which PowerShell version are you running on the 2008 R2 server?
Best regards
I really want to use this script but I don't get what I need to edit or delete to get it working.
Hi Nathan,
What error are you getting? Which server version?
Best regards
I HAVE server 2012 with powershell 4.0 and i m getting the error below kindly guide me.
Send-MailMessage : Cannot validate argument on parameter 'To'.
The argument is null or empty.
Provide an argument that is not null or empty, and then try the command again.
At line:204 char:22
+ Send-MailMessage @mail
+ ~~~~~
+ CategoryInfo : InvalidData: (:) [Send-MailMessage], ParameterBindingValidationExce
ption
+ FullyQualifiedErrorId : ParameterArgumentValidationError,Microsoft.PowerShell.Commands.Send
MailMessage
I get an email but the only content says: "the backup script failed to run!"
Hi Joakim,
We are trying to get it to work on SB2016 with frmae work 5.1
But it is not working, is it compatible with the latest version?
Working for me with the latest patches. What error are you getting?
Best regards
hi,
Can someone help me, am getting the below error. The email id i have mentioned while running the command is our official id. I have put [email protected] just for information to you guys.
At C:\Users\Administrator\Desktop\Get-Scripts.ps1:33 char:22
+ $MailFrom = [email protected]
+ ~~~~~~~~~~~~~~~~~~~~~~~
Unexpected token '[email protected]' in expression or statement.
+ CategoryInfo : ParserError: (:) [], ParentContainsErrorRecordException
+ FullyQualifiedErrorId : UnexpectedToken
PS C:\Users\Administrator\Desktop>
Hi,
The script ran successfully, got a doubt here. Will the script run automatically everytime a backup happens. I get the notification only when the script is ran manually.
I solved "the backup script failed to run!" by commenting out the following:
# SMTP user account password
#$MailUser = "MyUser"
#$MailPassword = "MyPassword"
#$Password = ConvertTo-SecureString $MailPassword -AsPlainText -Force
#$Credentials = New-Object System.Management.Automation.PSCredential ($MailUser, $Password)
2x
#Credential = $Credentials
Does anyone know how to get all the reports into one email, i.e. I have 8 WSB servers running and get 8 separate emails, would be great just to get one email with the 8 reports contained.
Awesome script!!! Thank you!
Hello all,
I am getting "the backup script failed to run!".
I have Windows Server 2008 R2. Power shell 5.1.14409.1005
Any help would be great. really need this script to work.
Thanks
Thanks for the Script.
A few things I had to do to make this work on Server 2016
I had to Comment out the Email Auth as it is not required on our setup (Same as PatsWin did)
I also setup the Task Scheduler to only look for Event ID 14, as this is logged every time a Backup Job completes (Failed or Success).
On the Task Scheduler I had to setup the Arguments as:
Arguments: -File "C:\Scripts\WBJobReport.ps1" -ExecutionPolicy Bypass
I also had to check the Option to "Run with highest privileges"
hi,
amazing script
but, when error 518 occurs (The backup operation failed because another backup or recovery operation is in progress, please stop the conflicting operation and then rerun the backup operation.)
the script writes that the backup was successful
hello,
realy cool script!!!
Thanks for sharing…works perfect on MS Sever 2012R2
Helle Joakim,
is it possible to run the script at a given time?
On a server 2016 it runs just once and then never again using task planer…
Hi,
Yes you can run the script at any time. However it will only report the last job.
Best regards,
Joakim
Hi,
My servers is 2011 sbs and not support PS 3.0 version, is it possible to converto to 2.0?
Best Regards,
When I run the script on my windows 10 machine aswell as on a server 2016 essentials, I get a credntials pop up box. If I enter email credentials in the box it works. Why doesnt it use the saved credentials from the script???
Hello Jocha
We appreciate you for the wonderful script . This script is serving the purpose
In our environment we are facing some issues while deploying it . We have some 21 physical servers configure with the windows backup utility . We placed this script on another remote server , We are getting report for some 18 server while running the script manually . with schedule its not running on windows server . For rest 3 servers we are getting below error
+ CategoryInfo : OpenError: (System.Manageme….RemoteRunspace:RemoteRunspace) [New-PSSession], PSRemotingTransportException
+ FullyQualifiedErrorId : -2144108387,PSSessionOpenFailed
New-PSSession : [HACSSAPDEOT02] Connecting to remote server HACSSAPDEOT02 failed with the following error message : WinRM cannot process the request. The following error with errorcode 0x80090322 occurred while using Kerberos authentication: An unknown
security error occurred.
Possible causes are:
-The user name or password specified are invalid.
-Kerberos is used when no authentication method and no user name are specified.
-Kerberos accepts domain user names, but not local user names.
-The Service Principal Name (SPN) for the remote computer name and port does not exist.
-The client and remote computers are in different domains and there is no trust between the two domains.
After checking for the above issues, try the following:
-Check the Event Viewer for events related to authentication.
-Change the authentication method; add the destination computer to the WinRM TrustedHosts configuration setting or use HTTPS transport.
Note that computers in the TrustedHosts list might not be authenticated.
-For more information about WinRM configuration, run the following command: winrm help config. For more information, see the about_Remote_Troubleshooting Help topic.
At C:\Hessphysicalserverjobreport\AJAINJobReport.ps1:18 char:12
+ $Servers = New-PSSession -Computername HACSSAPDEOP02,HACSSAPDEOP05,HACSSAPDEOP06 …
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : OpenError: (System.Manageme….RemoteRunspace:RemoteRunspace) [New-PSSession], PSRemotingTransportException
+ FullyQualifiedErrorId : -2144108387,PSSessionOpenFailed
PS C:\Hessphysicalserverjobreport>