This PowerShell script allows you to set up an automated database backup alert email for your Exchange Server environment.
The components of this solution are:
- The PowerShell script itself, Get-DailyBackupAlerts.ps1
- The Settings.xml file for customizing SMTP and other settings
- Task Scheduler for automatically running the script each day
This script is available on the TechNet Script Gallery or Github. Comments are welcome below. If you find a bug please consider raising it as an issue on Github.
Here is a demonstration of the script in action. This video is based of earlier versions of the script, but should give you an idea of what the script is intended to do.
How do i run the script with schedule task ?
Config to task schedule:
1-General:
Run Whether user is logged on or not
Run with highest privileges
2-Triggers
Daily às 07:00AM
3-Action
Start a program
4-Program/Script : C:\Windows\system32\WindowsPowerShell\v1.0> .\powershell.exe
5-Add arguments: -PSConsoleFile “H:\Program Files\Microsoft\Exchange Server\V15\Bin\exshell.psc1” -command “. c:\scripts\ExchangeServerHealth.ps1 -reportmode –SendEmail”
“. c:\scripts\Get-DailyBackupAlerts.ps1 -AlwaysSend -log -Verbose”
Hello Vinicuis
i tried the same command but it doesn’t work with me
Hi Paul
I tried to schedule a Task in Task schedular to run the script daily.
but i can’t get it running.
so I wrote a batch, which starts the Get-DailyBackupAlerts.ps1
so, this works
What do i have to addjust in the script to get the mail everyday, even if there are noch failures in Backup. When I call the Script manually, I add the switch -alwaysSend.
But how can I realize this when I start it automatically per batch in the task-scheduler?
hi Paul, How to get the output in CSV file, i tried export-csv not working.
In our environment, we dont allow anonymous connection. So we cant get output email in HTML.
Regards,
Naveen
Hi Paul, getting there, the Exchange 2010 DB’s I have excluded don’t appear.
The db01 , db02 and so forth are Exchange 2007 Databases, while I want to report on the ones I manage, it would be handy to remove the ones I don’t. Some of those DB names are unique, but even those when added as an exclusion they still show in the report.
I got the database names using get-mailboxdatabase , any idea where I am going wrong ?
I’m not even sure this script works properly for Exchange 2007. You might need to include the storage group name. But I don’t have any Exchange 2007 servers running to test this.
Whoops, it stripped out some of the post, lets try again
EG, a server and dag I want to exclude is apex10m821, the dag APEX01DAG
I have tried adding the DB, then in desperation, the server name, but they are still reported on
“Exclusions>APEX01DAGAPEX10M821”
Is it something in the format of how I have added the exclusion,
the post keeps stripping out the DB15 , for the example I have added spaces so you can see I am putting them in the right format :-0
ok, it won’t let me use the < as it sees them as tags in these posts
Just one database name per line should work.
for some reason it does not, for example, plenty across the org are called “DB01” , I add that into the settings.xml file, so it reads (as this reply will strip the tags, I will write it)
less than DBName greater thanDB01less than /DBName greater than
and it still reports on all those, I should just be slotting the dag name in the space between the examples ?
Not sure what you mean by “plenty across the org are called DB01”. Each database name in an organization must be unique.
I’ve just tested it in my lab and it’s working fine when I add each database name on its own line in the config file. All you need to add is the database name. No server names or DAG names required.
You can run the script with -Verbose to see some more information in the output. Perhaps that will give you a clue.
Hi Paul, the script runs fine, but I cannot get the exclusions to work, we have a big environment, but I only want to report on certain servers.
I have tried:
DB15DB16DB17
and as a test, the server name
Exclusions>APEX01DAGAPEX10M821
But still getting everything in the report, what am I doing wrong ?
I have configured the script the one year ago and it was working fine. now we have change the backup policy from daily full to daily incremental after that I am getting alert that backup is failed how ever if I check from backup console or from exchange it shows backup is completed. Any idea ?
Make sure you’re running the latest version of the script.
great script thank you
Getting error
ObjectNotFound: (C:\Scripts\DailyBackupAlerts.ps1-1.09\Get-DailyBackupAlerts.ps1:100 char:20
+ [xml]$ConfigFile = Get-Content “$MyDir\Settings.xml”
any help would be appreciated
ok I got it very long day. thanks again for the script
Hi, thanks for this report..BUt I have one question,
getting this at the end with -verbose
Sending email report
Cannot validate argument on parameter ‘From’. The argument is null or empty. Provide an argument that is not null or empty, and then try the command again.
I have edit the settings xlm file for my enviroment
I did run with
.\Get-DailyBackupAlerts.ps1 -AlwaysSend -Log -Verbose and without verbose
and my settings are like this in the xlm file
smtp.xxxxx.xx
25
replay@xxx.xx
xxxxx@xxxxxx.xx
48
24
You need to use a valid SMTP address in the XML file. If you’re trying to send the report to multiple recipients I recommend using a distribution group.
when i run the script, it runs fine, but in the end it gives an error
Cannot validate argument on parameter ‘From’. The argument is null or empty
I can’t offer any suggestions if you don’t tell me how you’re running the script. What is the command line you’re running? Did you edit the Settings.xml file correctly?
Hi Paul,
Have you ever merged the Test-ExchangeServerHealth and Get-DailyBackupAlerts scripts so it produces one email?
Thanks Gareth.
No. The main reason is because they were developed separately at different times and for different audiences.
how can I change the UTC Time Stamp to local time stamp
Does anyone know why all my backup report as Full backups when i know they are incremental?
Can you show the backup timestamps for one of the databases?
This is last nights on one database. It was an incremental but reports as full. We use BackupExec14 to do the Exchange backups. Its not an issue just a strange.
SnapshotLastFullBackup : True
SnapshotLastIncrementalBackup :
SnapshotLastDifferentialBackup :
SnapshotLastCopyBackup :
LastFullBackup : 30/11/2016 20:25:16
LastIncrementalBackup :
LastDifferentialBackup :
LastCopyBackup :
If those are the results that Get-MailboxDatabase returns, then Exchange thinks it is a full backup. Perhaps your backup software is actually taking a full backup. Either way, I suggest you open a case with Symantec to determine why it’s saying one thing and Exchange is saying a different thing.
I thought it was the backup software . It is definitely doing an incremental we have 23mdb and all but two report full backups.
I will speak to symantec.
Thanks
Hi Paul,
Great script but now getting the error “Cannot convert value “Never” to type “System.Int32”…”. as well now.
Many thanks
Roy
Please describe your environment.
SOLVED:
This happens when you have a database with no Incremental backups.
As a workaround i’ve replaced $LastInc = “Never” with $LastInc = 2147483647.
Technical explanation as i see it: Sorting an array with different types of values string, int has unpredictable results.
Regards.
When I run the scripts it gives me a bunch of user accounts that it says have been corrupt or isn’t compatible with Microsoft Support Requirements…
What is it doing?
If you run Get-Mailbox and see a bunch of the same warnings then you’ve probably got some mailboxes with invalid attributes.
Hi Paul,
Thanks for this wonderful script.
Please advsie on below error coming after running the script at PowerShell prompt .
I have recived the report of all the database successfully via email.
Kind regards
Sanjay
You cannot call a method on a null-valued expression.
At C:ScriptsBackupAlertsGet-DailyBackupAlerts.ps1:389 char:48
+ $LatestBackup = ($LastBackups.GetEnumerator <<<< () | Sort-Object -Property Value)[0]
+ CategoryInfo : InvalidOperation: (GetEnumerator:String) [], RuntimeException
+ FullyQualifiedErrorId : InvokeMethodOnNull
Hey Paul, script works also for me like a charm. Great work.
is it possible to get the output sorted by databasename? because we have db´s with numbering from 001 to 999 in the name.
also i have the problem, that on publicfolder database i get same error message like above:
“Cannot convert value “Never” to type “System.Int32”…”.
any ideas?
Thanks
Jens
When I run the command with -AlwaysSend and -Log parameters, I get the below error. I downloaded the script today. Hope I am using the latest available script. Please advice
[PS] C:Get-DailyBackupAlerts.ps1-1.09>.Get-DailyBackupAlerts.ps1 -AlwaysSend -Log
Cannot convert value “Never” to type “System.Int32”. Error: “Input string was not in a correct format.”
At C:Get-DailyBackupAlerts.ps1-1.09Get-DailyBackupAlerts.ps1:336 char:21
+ $LastInc <<<< = "Never"
+ CategoryInfo : MetadataError: (:) [], ArgumentTransformationMetadataException
+ FullyQualifiedErrorId : RuntimeException
You cannot call a method on a null-valued expression.
At C:Get-DailyBackupAlerts.ps1-1.09Get-DailyBackupAlerts.ps1:474 char:133
+ "Incremental" { $dbObj | Add-Member NoteProperty -Name "UTC Time Stamp" -Value $db.LastIncrementalBackup.
ToUniversalTime <<<< () }
+ CategoryInfo : InvalidOperation: (ToUniversalTime:String) [], RuntimeException
+ FullyQualifiedErrorId : InvokeMethodOnNull
WARNING: Unable to connect to the remote server
Out-File : The process cannot access the file 'C:Get-DailyBackupAlerts.ps1-1.09Get-DailyBackupAlerts.log' because it
is being used by another process.
At C:Get-DailyBackupAlerts.ps1-1.09Get-DailyBackupAlerts.ps1:154 char:35
+ "$timestamp $logentry" | Out-File <<<< $logfile -Append
+ CategoryInfo : OpenError: (:) [Out-File], IOException
+ FullyQualifiedErrorId : FileOpenFailure,Microsoft.PowerShell.Commands.OutFileCommand
Out-File : The process cannot access the file 'C:Get-DailyBackupAlerts.ps1-1.09Get-DailyBackupAlerts.log' because it
is being used by another process.
At C:Get-DailyBackupAlerts.ps1-1.09Get-DailyBackupAlerts.ps1:154 char:35
+ "$timestamp $logentry" | Out-File <<<
Version of Exchange?
Exchange Server 2010
Version: 14.03.0123.003
I get the file lock error on Exchange 2010 as well, so I’ve raised a bug for that in Github. I think it’s being caused by the SMTP connection failing:
WARNING: Unable to connect to the remote server
The other errors I can’t reproduce. Please run the script with -Log and send the log file to feedback@practical365.com so I can take a look.
Dear paul,
Thanks for the quick response.
I had issue with smtp configuration. I do not get the warning anymore after I fixed it. With this the file lock error also got vanished. I get the report properly now. However, I still do have the error shown in the EMS, while I run the script.
Cannot convert value “Never” to type “System.Int32”. Error: “Input string was not in a correct format.”
At C:Get-DailyBackupAlerts.ps1-1.09Get-DailyBackupAlerts.ps1:378 char:23
+ $LastInc <<<< = "Never"
+ CategoryInfo : MetadataError: (:) [], ArgumentTransformationMetadataException
+ FullyQualifiedErrorId : RuntimeException
You cannot call a method on a null-valued expression.
At C:Get-DailyBackupAlerts.ps1-1.09Get-DailyBackupAlerts.ps1:532 char:134
+ "Incremental" { $dbObj | Add-Member NoteProperty -Name "UTC Time Stamp" -Value $db.LastIncrementalBackup
.ToUniversalTime <<<< () }
+ CategoryInfo : InvalidOperation: (ToUniversalTime:String) [], RuntimeException
+ FullyQualifiedErrorId : InvokeMethodOnNull
What happen to this issue? I’m also have same problem. I couldn’t run well, and I got the latest version Exchange 2010 SP3
Version: 14.03.0210.002
What is the fix for this? Thank you.
What happen to this issue? I’m also have same problem. I couldn’t run well, and I got the latest version Exchange 2010 SP3
Version: 14.03.0210.002
What is the fix for this? Thank you.
OK, so I read the rest of the postings after I posted this and there was someone else with the same problem and Paul suggested downloading the new script.
I did and now I see the two servers that were backed up 102 hours ago in Red like they should be.
Paul,
I am running your latest Backup report script on Exchange 2010 with about 25 databases. I have 2 DAGS.
I noticed this in the email this morning.
I have 2 databases that are showing last full backup 102 hours ago but the script is not reporting the error.
When I manually ran the script this morning I get the following Error
Method invocation failed because [System.String] doesn’t contain a method named ‘ToInt32’. At D:ScriptsBackupsGet-BackupAlerts.ps1:424 char:39
elseif ($($LatestBackup.Value.ToInt32 <<<< ($null)) -gt $threshold) {
Thanks
I ran this script and it doesn’t send the message. I am running this script from the mail server after the backup occurs. I do not get any errors when running the script so I am not sure what is happening. I do understand that relaying has to be enabled from the IP address of the server itself but I am not able to add the receive connector to allow this. I am getting another exchange error that it is duplicate to another connector.
Any help would be greatly appreciated.
Depends which version of Exchange, and every environment is different, but generally no special connectors required if you’re sending the reports to an internal email address. Some things to try – running the script on the Exchange server itself, telnet from the backup server to the Exchange server to verify that port 25 is accessible, run the script with -Log and check the log file, double check your SMTP settings in Settings.xml are correct.
Wow. This is crazy!! The script runs perfect. I used the -Log and everything was good in it. The problem has to be the exchange server. I can telnet to it from the backup and the email address is an internal one, and the xml settings are all correct. I don’t know where to look at this point.
Possible that the SMTP connection is successful but delivery is failing. Turn on protocol logging on the receive connectors and try again. Look at connections coming from the backup server IP to see whether they’re being rejected. You can also perform a message tracking search to see if Exchange is discarding the email for some reason.
Also if you can Telnet from the backup server to Exchange, keep going and perform SMTP testing via the Telnet session.
It is not even hitting the receive log once I enable logging. The message is also not in the message tracking.
Also the backup server is the exchange server. I am pushing the backup to a NAS.
I should have mentioned earlier that this is part of a DAG. Does that make a difference?
If you think of a variable, test that variable. So if the script isn’t working from your Exchange server, try installing the Exchange management tools on a workstation or server and run the script from there.
You also didn’t say whether your Telnet testing worked.
The mail sends from the telnet commands. I did this from another domain machine. I also installed the exchange tools on this machine and tried the power shell script. I get the same result as before the script seems to run but the mail never gets delivered. Since everything’s working from the telnet command from that same machine I assume that it is not the exchange server.
Send me your report email, log file, and settings.xml file to feedback@exchangeserverpro.net so I can take a look.
Sorry, I am not following, “your report email”
Ah yeah, your report email isn’t working… just send me the log and settings.xml file.
I am a total idiot!!! I just noticed that you must add the -AlwaysSend if you want an email everytime the script is run. Thank you for all your help and the great script you provided us.
BTW it is Exchange 2016 Enterprise.
Ji Paul,
Am getting same Error Msg..
Please Advice on this
Run the script with the -Log parameter and send the log file to feedback@practical365.com so I can take a look.
Hi Paul
Am getting error, while uploading this script
Please help me
Error msg:
Method invocation failed because [System.String] doesn’t contain a method named ‘ToInt32’.
At C:Users_umaganesh.subbiahDesktopGet-DailyBackupAlerts.ps1-1.07Get-DailyBackupAlerts.ps1:424 char:39
+ elseif ($($LatestBackup.Value.ToInt32 <<<< ($null)) -gt $threshold) {
+ CategoryInfo : InvalidOperation: (ToInt32:String) [], RuntimeException
+ FullyQualifiedErrorId : MethodNotFound
Method invocation failed because [System.String] doesn't contain a method named 'ToInt32'.
At C:Users_umaganesh.subbiahDesktopGet-DailyBackupAlerts.ps1-1.07Get-DailyBackupAlerts.ps1:424 char:39
+ elseif ($($LatestBackup.Value.ToInt32 <<<< ($null)) -gt $threshold) {
+ CategoryInfo : InvalidOperation: (ToInt32:String) [], RuntimeException
+ FullyQualifiedErrorId : MethodNotFound
Method invocation failed because [System.String] doesn't contain a method named 'ToInt32'.
At C:Users_umaganesh.subbiahDesktopGet-DailyBackupAlerts.ps1-1.07Get-DailyBackupAlerts.ps1:424 char:39
+ elseif ($($LatestBackup.Value.ToInt32 <<<< ($null)) -gt $threshold) {
+ CategoryInfo : InvalidOperation: (ToInt32:String) [], RuntimeException
+ FullyQualifiedErrorId : MethodNotFound
Method invocation failed because [System.String] doesn't contain a method named 'ToInt32'.
At C:Users_umaganesh.subbiahDesktopGet-DailyBackupAlerts.ps1-1.07Get-DailyBackupAlerts.ps1:424 char:39
+ elseif ($($LatestBackup.Value.ToInt32 <<<< ($null)) -gt $threshold) {
+ CategoryInfo : InvalidOperation: (ToInt32:String) [], RuntimeException
+ FullyQualifiedErrorId : MethodNotFound
Method invocation failed because [System.String] doesn't contain a method named 'ToInt32'.
At C:Users_umaganesh.subbiahDesktopGet-DailyBackupAlerts.ps1-1.07Get-DailyBackupAlerts.ps1:424 char:39
Can you please try this updated version and let me know if the problem continues.
https://github.com/cunninghamp/Get-DailyBackupAlerts.ps1/archive/development.zip
My backup software says the daily differential backups are successful but your script only shows the last successful backup as being our weekly full. Is that by design or is something up with my backup software?
The script doesn’t check the last diff time stamp, only full and inc. That’s just due to the nature of the environment I first wrote it in. I plan to make an update that will include diffs, it’s just not my top priority right now 🙂
ok, looking forward to the update. Thank you!
Hi Pual,
Thank you , This is exactly I was looking for I run it from exchange powershell & I have got an error as below.
[PS] C:Get-DailyBackupAlerts>.Get-DailyBackupAlerts.ps1 -Verbose -Log -AlwaysSend
VERBOSE: Threshold for this check is 24 hours
VERBOSE: Loading the Exchange Server PowerShell snapin
Update-TypeData : The following error occurred while loading the extended type data file:
Microsoft.PowerShell, C:Program FilesMicrosoftExchange ServerV14binexchange.types.ps1xml : File skipped because i
t was already present from “Microsoft.PowerShell”.
At C:Program FilesMicrosoftExchange ServerV14binRemoteExchange.ps1:94 char:17
+ Update-TypeData <<<< -PrependPath $typeFilePath
+ CategoryInfo : InvalidOperation: (:) [Update-TypeData], RuntimeException
+ FullyQualifiedErrorId : TypesXmlUpdateException,Microsoft.PowerShell.Commands.UpdateTypeDataCommand
Update-TypeData : The following error occurred while loading the extended type data file:
Microsoft.PowerShell, C:Program FilesMicrosoftExchange ServerV14binExchange.partial.Types.ps1xml : File skipped b
ecause it was already present from "Microsoft.PowerShell".
Microsoft.PowerShell, C:Program FilesMicrosoftExchange ServerV14binexchange.types.ps1xml : File skipped because i
t was already present from "Microsoft.PowerShell".
At C:Program FilesMicrosoftExchange ServerV14binRemoteExchange.ps1:104 char:16
+ Update-TypeData <<<< -PrependPath $partialTypeFile
+ CategoryInfo : InvalidOperation: (:) [Update-TypeData], RuntimeException
+ FullyQualifiedErrorId : TypesXmlUpdateException,Microsoft.PowerShell.Commands.UpdateTypeDataCommand
Welcome to the Exchange Management Shell!
Hello
I get output as Zero hours
How do I change that to real time please
did you test for Exchange 2016? I can not get the result of test in 2016
Yes, it works fine on my Exchange 2016 servers.
hi paul
unable to escape “M a i l T o” and “/ M a i l T o” as required in the XML file when posting here. please remove my posts or adapt my first post accordingly
You’re trying to post a tip about sending to multiple recipients, so I’m going to repeat the same advice I’ve given everyone above – just use a distribution list. It’s really that simple.
is removed as well as
hi paul
“” was removed in my recent post, I don’t know how to escape the automatic link conversion ?
recipient1@mail.com
recipient2@mail.com
Multiple recipients using the Settings.xml file:
recipient1@mail.com
recipient2@mail.com
recipient3@mail.com
@paul: thanks for the handy script
Hi Paul,
How can I send the report to multiple recipients? I’ve tried below combinations in Settings.xml file with no luck. Thank you.
“recipient1@mail.com”,”recipient2@mail.com”
“recipient1@mail.com”;”recipient2@mail.com”
recipient1@mail.com,recipient2@mail.com
recipient1@mail.com;recipient2@mail.com
Use a distribution list. Then you don’t need to modify the script files any time the list of recipients changes, you can just change membership of the DL.
It’s possible, you must add one line per recipient :
Pingback: Performing a Like for Like Exchange Server Migration
Pingback: Backing up Exchange 2016 Using Windows Server Backup
Pingback: PowerShell Script: Check Exchange Mailbox Database Last Backup Time
yes, its working in shell…thanks Paul
hipaul,
is this output stored anyware n the system??
Hi Paul,
i have changed the XML settings but still its not working on exchange 2010. once goto the path and enter the its just showing started… after that no results..
Does it work if you run the script manually in PowerShell?
This is a superb script !!! Thank U Paul!
I receive this one error randomly anytime I run the script for at least 1 of my 3 DAG member servers. Has anyone encountered this and can provide details to resolve it?
WARNING: Windows Failover Clustering encountered a transient error. Trying the operation again may be successful.
Error: ‘IsNodeClustered’.
Add-Member : Cannot bind argument to parameter ‘Name’ because it is null.
At E:SourcescriptsTest-ExchangeServerHealth.ps1:1553 char:53
+ $memberObj | Add-Member NoteProperty -Name <<<< $($healthitem.Check) -Value $healthitemresult -Force
+ CategoryInfo : InvalidData: (:) [Add-Member], ParameterBindingValidationException
+ FullyQualifiedErrorId : ParameterArgumentValidationErrorNullNotAllowed,Microsoft.PowerShell.Commands.AddMemberCommand
Regards
I tried to run the script this morning while my DAG backup was running and the script failed with unable to connect to server. Is this correct.
No. The script should work while backups are in progress. What do you use for backups?
We use EMC Avamar/Data domain.
It was very nice script Paul!!!
Hello there,
I can’t find how to download this script 🙁
Is there a download link?
Thanks in advance,
Best regards,
Rachid
i made changes only on SMTP setting nothing else. just to let you know i am running this on exchange 2013 will it work?
It will work on 2013.
I think by the looks of your error message you’ve made the XML syntax invalid with your edits, and you should try again.
this is what i am getting in begging of the script.
Cannot convert value “System.Object[]” to type “System.Xml.XmlDocument”. Error: “The ‘DBName’
start tag on line 9 position 6 does not match the end tag of ‘JournalDB’. Line 9, position 15.”
At C:ScriptsGet-DailyBackupAlerts-v1.06-2Get-DailyBackupAlerts.ps1:91 char:1
+ [xml]$ConfigFile = Get-Content “$MyDirSettings.xml”
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : MetadataError: (:) [], ArgumentTransformationMetadataException
+ FullyQualifiedErrorId : RuntimeException
and i am getting following at the end also not be able to receive report in my email
WARNING: Cannot validate argument on parameter ‘From’. The argument is null or empty. Supply an arg
ument that is not null or empty and then try the command again.
Have you made any edits to the script file? Often people miss a closing quote or bracket when they do that.
Edit: or the XML file. The syntax of that file has to be perfect or it will all fall apart very quickly.
Ignore previous comment. Realised that by removing the ThresholdMonday line instead of changing the hours caused this issue.
However, still would like confirmation that the output shows successful completed backups as opposed to commenced.
Thank you
Ran the script successfully using the -Verbose method. My databases have backed up within the last 24 hours but the email output shows them with an Alert status. I notice from the email output that the alert is set to 0 hours.
“This is the Exchange database backup status for the last 0 hours.
There are 21 database backup alerts today.
The following databases have not been backed up in the last 0 hours.”
I haven’t amended the script. If I need to, can you confirm where.
I have removed the 48 from the Settings.xml but left the 24
Also, can you confirm that the output from the Exchange shell shows completed backups as opposed to commenced?
Thanks
Hi Paul,
Do we have any option to add last backup size for the each database in the script.
Thanks,
Aravind
Pingback: Get-DailyBackupAlerts.ps1 Script Updated to v1.06
Hi Paul,
I need your help to display in the report table which sent to me by email, Red color as backgroundcolor for Alerts in the status and Green color for OK in the Status. can you please modify the script and send it to my email.
hi Paul,
I’m looking for results on my exchange servers if a server name start with *sox*. is there a way i can just search for that? other than that a great script! thank you!
Have you opened the script in a PowerShell editor and looked at the code?
got it sorted thanks! added *sox* to the script.
Pingback: Get-DailyBackupAlerts.ps1 v1.04 is Available
Nice script. Thank you Paul.
One comment. In large environment it takes quite long to execute. In my case about 20 minutes.
So I removed command to get list of all mailboxes (longest command in my case)
And slightly modified mailbox counting (where that list had been used):
[int]$mbcount = 0
[int]$mbcount = (Get-MailboxStatistics -Database $db.name | ?{$_.ObjectClass -notlike “*ExOleDbSystemMailbox*”} | Measure-Object).Count
#[int]$archivecount = 0
#[int]$archivecount = ($mailboxes | Where-Object {$_.ArchiveDatabase -eq $($db.name)}).count
#[int]$mbcount = $mbcount + $archivecount
It saved in my case more than 15 minutes
Love the idea for the script. But I can’t get it to work. I get this error
Exception calling “Send” with “1” argument(s): “Failure sending mail.”
At C:scriptsGet-DailyBackupAlerts.ps1:322 char:12
+ $smtp.Send <<<< ($message)
+ CategoryInfo : NotSpecified: (:) [], MethodInvocationException
+ FullyQualifiedErrorId : DotNetMethodException
It is likely that the SMTP server you specified is rejecting the mail. The article mentions that this may require you to set up a relay connector.
Had the incorrect smtp server entered. Thanks.
I keep getting the error
Exception calling “Send” with “1” argument(s): “Mailbox unavailable. The server response was: 5.7.1 Unable
to relay”
At C:Install.SetScriptsGet-DailyBackupAlerts.ps1:329 char:12
+ $smtp.Send <<<< ($message)
+ CategoryInfo : NotSpecified: (:) [], MethodInvocationException
+ FullyQualifiedErrorId : DotNetMethodException
From the article: “If the SMTP server you specify is valid but no emails are being sent you may need to configure a relay connector or add the IP address of the workstation/server that is running the script to an existing relay connector.”
Hi,
Your script works OK, but something is bothering me.
When script results shows the last full/incremental backup, the command
get-mailboxdatabase [database_name] |fl last*backup*
shows nothing.
LastFullBackup :
LastIncrementalBackup :
LastDifferentialBackup :
LastCopyBackup :
When I go to the Exchange console and right clikc the same database, I can see the date of the last backup.
Can you tell me why the get-mailboxdatabase doesn’t show it?
BR
Mike
Got it. The right command is
get-mailboxdatabase [database_name] -status |fl last*backup*
than it shows the dates OK.
Is it possible to add one more field to the report?
Database Size
When i backup my databases it would be nice to see the size of each database that got backed up.
Thanks.
I’ll try and include something like that for the next version.
Paul,
Aswesome! Thanks for sharing. One request when you make your next revision… Would it be possible to include database size in the report? That would be great to have as we send this report regardless of backup status for history.
THX!
HI
Will this script work with Exchange 2013?
What changes have to make?
Tnx.
Hello Paul,
there is a slight mix up from some word :
First you give the example with alwayssend, in the send it is missing.
Also the schedule is not working until changing into this :
-command “c:scriptsget-dailybackupalerts.ps1″ -AlwaysSend
Thanks for this great script !
original text :
On the Actions tab click New and add an action of Start a program. Configure the program of powershell.exe and the arguments -command “c:scriptsget-dailybackupalerts.ps1 -AlwaysSend” instead.
If you would prefer the script always sends the report even if there are no alerts, then use the arguments -command “c:scriptsget-dailybackupalerts.ps1″
Hi,
Just to share my expirience with Windows 2008 R2 x64 server, based on this article (http://social.technet.microsoft.com/Forums/scriptcenter/en-US/0ea10ab8-8dd3-4c4c-977c-bbfd0bb17a1d/powershell-script-not-running-as-scheduled-task-server-2008?forum=ITCG)
It is worked fine for me when I set parameters in this format:
-command & (“{C:ScriptsGet-DailyBackupAlerts.ps1}”)
Hi Paul,
I think I’m going to love this report, if I can get it to send the mail message.
It seems to run just fine in WindowsPowershell or Exchange Powershell until the very end. I get this error:
VERBOSE: Alert email will be sent
VERBOSE: Report summary: Alerts 130, OK 99
VERBOSE: Sending email report
Exception calling “Send” with “1” argument(s): “Failure sending mail.”
At H:ExchangeScriptsDatabaseGet-DailyBackupAlerts.ps1:322 char:12
+ $smtp.Send <<<< ($message)
+ CategoryInfo : NotSpecified: (:) [], MethodInvocationException
+ FullyQualifiedErrorId : DotNetMethodException
Any ideas would be appreciated.
Refer to the note in the article above about configuring a relay connector.
Pingback: Create an Exchange Mail Flow Latency Heat Map with PowerShell
Hi Paul, thanks for the script. I’ve been using Data Protection Manager to manage my backups for Exchange 2013. Noticed I’d stopped getting email and found the reason was my disk was full. DPM was reporting everything was ok, but upon closer inspection it showed the last backup was over a week prior. Just goes to show nothing compares to a bit of human monitoring. Hoping your script will prevent this happening again.
Precisely the type of situation the script was written to avoid 🙂
Hi Paul,
This is a great script. My environment has Exchange 2003 and Exchange 2010 databases. I have around 128 databases in Exchange 2003 which I want to exclude from this script. I thought that rather than typing the name of all of them, it would be easy to remove the -IncludePreExchange2010 switch from the command in the script. However it did not help. Can you please help me with a way to exclude all Exchange 2003 databases from the scope of this script?
I would suggest modifying that line so it pipes in a Get-ExchangeServer command that excludes the Exchange 2003 servers.
So instead of what you see in the script, perhaps try:
$ex2010servers = get-exchangeserver | where {$_.AdminDisplayVersion -like “Version 14.*”}
$dbs = @($ex2010servers | Get-MailboxDatabase | Where {$_.Recovery -ne $true})
I have tried to adding in the lines as stated for $ex2010servers = get-exchangeserver | where {$_.AdminDisplayVersion -like “Version 14.*”}
$dbs = @($ex2010servers | Get-MailboxDatabase | Where {$_.Recovery -ne $true}) , but when i do the output comes out like this:
Last Backup Type Hrs Ago Time Stamp
Never/Unknown Never/Unknown Never/Unknown
Never/Unknown Never/Unknown Never/Unknown
Never/Unknown Never/Unknown Never/Unknown
Never/Unknown Never/Unknown Never/Unknown
Never/Unknown Never/Unknown Never/Unknown
Never/Unknown Never/Unknown Never/Unknown
Never/Unknown Never/Unknown Never/Unknown
When i remove this and change back to the way the script is by default, my outputs are correct again. My entry to the script is below, please let me know if something looks incorrect. I am trying to exclude anything that is 2003/2007 as well.
#Add Exchange 2010 snapin if not already loaded
if (!(Get-PSSnapin | where {$_.Name -eq “Microsoft.Exchange.Management.PowerShell.E2010”}))
{
Write-Verbose “Loading Exchange 2010 Snapin”
Add-PSSnapin Microsoft.Exchange.Management.PowerShell.E2010 -ErrorAction SilentlyContinue
}
Write-Verbose “Initializing variables”
$report = @()
$alertdbs = @()
$okdbs = @()
[bool]$alertflag = $false
#Current time is used in alert calculations
$now = [DateTime]::Now
Write-Verbose “Current date/time is $now”
Write-Verbose “Retrieving list of mailboxes for use in mailbox count later”
$mailboxes = $(Get-Mailbox -IgnoreDefaultScope -ResultSize Unlimited)
#……………………………..
# Script
#……………………………..
#Get all Mailbox and Public Folder databases
Write-Verbose “Retrieving database list”
$ex2010servers = get-exchangeserver | where {$_.AdminDisplayVersion -like “Version 14.*”}
$dbs = @($ex2010servers | Get-MailboxDatabase | Where {$_.Recovery -ne $true})
if ($dbs)
Hi Paul,
Script works perfectly when run manually with -Verbose or -AlwaySend (also changed $threshold to 1 for testing and all ok).
However, when scheduled, the script does not send email regardless of -AlwaySend switch setting or $threshold 1 set in the script.
Windows Server 2008 R2 SP1, Exchange Server 2010 SP2 RU6, Powershell Version 2.0.
Any ideas?
Many thanks.
Usually this is either a mistake in the scheduled task’s command line, or a permissions issue with the scheduled task.
Hi Paul,
Is there a simple way to run the /powershell-script-health-check-report-exchange-2010/ from another computer to be able to monitor my exchange servers ?
I would like to be able to monitor them and if the server where the script is installed is out of service, i would like to know the state of it.(?)
You can run the script from any server or workstation that has the Exchange management tools installed.
Pingback: Managing Exchange Server - Tips from the Trenches - exchangevirtualconference.com
Paul,
Please help me still i am facing this issue.
Thank You
Sreejith
Hi Paul,
I run this command on a 2007 Box and i am getting the full report except Mailbox count. All DB’s Mailbox count showing as “0”. Rest all details correct. Please help me on this.
Thank You
Sreejith
Hi, Paul!
Thank you for your job! But script don’t work on Russian Exchange 2010 🙁
1. Get-DailyBackupAlerts.ps1 -Verbose
for 8 of 13 databases it shows errors
——————–
Не удается преобразовать значение “1 647” в тип “System.Int32”. Ошибка: “Входная строка имела неверный формат.”
C:ScriptsGet-DailyBackupAlerts.ps1:189 знак:12
+ [int]$ago <<<< = "{0:N0}" -f $ago
+ CategoryInfo : MetadataError: (:) [], ArgumentTransformationMetadataException
+ FullyQualifiedErrorId : RuntimeException
———————
What in English is smth like this:
———————
Can not convert the value "1 647" to type "System.Int32". Error: "Input string was invalid."
C:ScriptsGet-DailyBackupAlerts.ps1:189 char:12
+ [int]$ago <<<< = "{0:N0}" -f $ago
+ CategoryInfo : MetadataError: (:) [], ArgumentTransformationMetadataException
+ FullyQualifiedErrorId : RuntimeException
———————
2. Running in English EMS (without verbose):
———————-
Cannot convert value "1 578" to type "System.Int32". Error: "Input string was not in a correct format."
At C:TEMPGet-DailyBackupAlerts.ps1:189 char:3
+ [int]$ago = "{0:N0}" -f $ago
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : MetadataError: (:) [], ArgumentTransformationMetadataException
+ FullyQualifiedErrorId : RuntimeException
Cannot convert value "1 600" to type "System.Int32". Error: "Input string was not in a correct format."
At C:TEMPGet-DailyBackupAlerts.ps1:189 char:3
+ [int]$ago = "{0:N0}" -f $ago
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : MetadataError: (:) [], ArgumentTransformationMetadataException
+ FullyQualifiedErrorId : RuntimeException
——————– … and so on 8 times
Hi Paul,
Again one help for this script.
I am running this script in 2007 Exchange Shell
Script is runningfine and it’s generating the email aswell.
Only thing is Mailboxes count showing 0 for all DB’s.
Thank you
Sreejith
Is there a way to color code the background of the Status ?
Alert = Red
OK = Green
Hello Paul,
Is het Possible to send a mail to more then one mailaccount?
I use a mailgroup, because we arre using this for more scripts and I want to add a single user that only receives the results of this script.
I tried to add the account with a semicolon (;) but this only gives errors.
Hello Paul,
After trying some things, I discoverd the answer. I had to use a comma between the emailadresses.Then the script works.
How can I color code the Status background?
Alert = Red
OK = Green
For whatever reason, the script has started to work and there arent any errors anymore.
thank you.
Yeah I am using a valid email address, server, etc.. I just modified the below to suit with my details.
$smtpServer = “smtp.exchangeserverpro.net”
$smtpFrom = “exchangeserver@exchangeserverpro.net”
$smtpTo = “administrator@exchangeserverpro.net”
Great Script Paul. It runs on screen but get the below errors right at the end.
I used the -verbose -alwayssend options.
New-Object : Exception calling “.ctor” with “2” argument(s): “The specified string is not in the form required for an e
-mail address.”
At C:appsBackupAlert.ps1:314 char:23
+ $message = New-Object <<<< System.Net.Mail.MailMessage $smtpfrom, $smtpto
+ CategoryInfo : InvalidOperation: (:) [New-Object], MethodInvocationException
+ FullyQualifiedErrorId : ConstructorInvokedThrowException,Microsoft.PowerShell.Commands.NewObjectCommand
Property 'Subject' cannot be found on this object; make sure it exists and is settable.
At C:appsBackupAlert.ps1:315 char:11
+ $message. <<<< Subject = $messageSubject
+ CategoryInfo : InvalidOperation: (Subject:String) [], RuntimeException
+ FullyQualifiedErrorId : PropertyNotFound
Property 'IsBodyHTML' cannot be found on this object; make sure it exists and is settable.
At C:appsBackupAlert.ps1:316 char:11
+ $message. <<<< IsBodyHTML = $true
+ CategoryInfo : InvalidOperation: (IsBodyHTML:String) [], RuntimeException
+ FullyQualifiedErrorId : PropertyNotFound
Property 'Body' cannot be found on this object; make sure it exists and is settable.
At C:appsBackupAlert.ps1:317 char:11
+ $message. <<<< Body = ConvertTo-Html -Body "$intro $summary $alertintro $alerthtml $okintro $okhtml $outro" -Head
$style
+ CategoryInfo : InvalidOperation: (Body:String) [], RuntimeException
+ FullyQualifiedErrorId : PropertyNotFound
VERBOSE: Sending email report
Exception calling "Send" with "1" argument(s): "Value cannot be null.
Parameter name: message"
At C:appsBackupAlert.ps1:322 char:12
+ $smtp.Send <<<< ($message)
+ CategoryInfo : NotSpecified: (:) [], MethodInvocationException
+ FullyQualifiedErrorId : DotNetMethodException
“The specified string is not in the form required for an e -mail address.”
Are you using a string that is a valid email address?
Pingback: The UC Architects » Episode 16: Dave the Ghost
Pingback: The UC Architects Episode 16: Dave the Ghost | Steve Goodman's Exchange Blog
Pingback: The UC Architects Podcast Ep16 | EighTwOne (821)
Paul,
How can I exclude pre ex2010 databases only?
thanks
Yes, it’s great script.. A question only.. it’s possible to include and size of last backup session..?
That info would normally come from your backup product. It isn’t stored in Exchange.
Paul,
Great script. This was exactly what I was looking for. Just one question on the latest version. I have about 68 existing Exchange 2007 DBs I would like to exclude, but have not been able to successfully exclude them in the script unless I type out the entire “serversgdb” format in the exclude DBs section. I do not want to type out all 68 2007 DBs. Is there another way to exclude these DBs from the report?
Thanks,
Johnny
Whether you type them in the script or type them in a txt file that the script references, one way or the other you’re still typing them out.
Unless you have some other criteria you can filter them out with (eg a common string in their names or which server they sit on).
i want to do similar, but i only want results on 6 servers of my 58. and those six have sox in their name. any suggestions?
Is there a way to use a variable so that the script takes the SMTP server settings from the local exchange server it is running on?
Ex.
$smtpServer = “localhost”
$smtpFrom = “administrator@%Domain%”
Thanks,
Carl
Pingback: How to Automate Exchange 2010 Database Backup Alert Emails « JC’s Blog-O-Gibberish
should it work on windows server 2008 R2 for both Active Director and File Server Backup?
Can some one post a working exchange 2007 version of this script?
The powershell script does not work for me because getting database list show all databases of my organization, how I can only get report of my servers ?
Thanks.
Running the script seperately against e2k7 boxes sends the alert as required, but tge currently running status column is blank even when the backup is running please advise.
Pingback: Test-ExchangeServerHealth – PowerShell Script to Generate a Health Check Report for Exchange Server 2010 | Yusuf Mangera
Hi Paul,
Thanks for the script, it is very well laid out and concise. One thing I’ll add is that the LastFullBackup timestamp (and the LastIncrementalBackup’s, LastDiff..’s, etc.) is actually from when the last successful backup started, not when the last backup was finished. In other words it’s saying your data is good and safe up until that time.
Many thanks, this is going into my scheduler.
Should you have problems executing this script via task scheduler, modify -command switch:
powershell -command “. ‘C:scriptsGet-DailyBackupAlerts.ps1′”
Hi Paul, Thanks for the script, works like a charm… when you say that the databases haven’t been backed up… what do you mean by that?
If a daily Windows Server Backup is performed… should this reflect it? Or still there is a better procedure to backup the Exchange databases?
Thanks.
Hi Paul, I would like to know, in which language this screept has been written ?
Powershell.
This works great but I have a database that is currently being backed up but is not being reported. I’d like to convert this to more of a database backup report. Database xyz has not been backed up database abc backup is in progress and then database 123 was completed on…
My problem is that I am not that versed in power shell. Any guidance would be welcome.
Thanks
Paul
I got the script to work for testing purposes with the threshold set to 1hr. But now when I change the script’s threshold to 10, it checks the databases and does not send an email.
I ran the powershell commands manually and have databases that were last backed up over 24 hours ago.
Shouldn’t the script still send an email?
There was a bug with the script that should fix that. I recommend trying the latest version.
I just came across this and am attempting to shoehorn this into my Exchange 2007 environment. I’ve got it to run and email without a problem. I’ve loaded the Exchange 2007 PS addin to PS. However, the report neglects to include the server/dag and database type in those sections.
When I run the commands to get the list of databases and their status…it lists everything as expected. Any hints?
Thanks again for a wonderful script!
I got it going. Exchange 2007 doesn’t allow have IsMailboxDatabase/IsPublicFolderDatabase equals True/False as a valid database property. I manually used:
db.Name -eq “Name of my Mailbox Database”) {$dbtype = “Mailbox”}
and
db.Name -eq “Name of my PF Database”) {$dbtype = “Public Folder”}
At that point, I ignored some of the logic for what gets set in the server/dag value column of the report. db.MasterServerOrAvailabilityGroup isn’t a valid property for me, so I simply used used db.Server to fill in the Server/DAG value.
I then included:
$dbObj | Add-Member NoteProperty -Name “Storage Group” -Value $db.StorageGroup.Name
to give me the Storage Group Name where my Mailbox Database resides.
Seems to work great. i adjusted the Monday threshold to 48 hours and all other days’ threshold to 24. updated the comments to match..”This will go out if a backup hasn’t been done in more than 24 hours”.
One thing to note…i have a couple spam mailboxes that I don’t back up…i keep rolling logs on it. That mailbox database hasn’t been backed up…even though it would come back with never, the email never goes out. Shouldn’t it email if a database (MB or PF) hasn’t been backed up?
When i try to run this script it says it is not signed.. i can ofcourse lower my guard and have exection policy set to unrestricted but it would be neater to have this script trusted by my servers.. how do i set that option?
Pingback: PowerShell Script: Generate an Exchange 2010 Health Check Report
Paul, a brilliant script, who hasn’t been caught out with logs files at some point!!!
Pingback: PowerShell Script: Check Exchange 2010 Database Backups
Hello,
If I run manually it works great. If run from a batch file or via scheduler, the email does not list the db and is generally blank. Suggestions?
Wally Hass
Possible that the credentials being used to run the scheduled task do not have access to Exchange.
Will this script work with Exchange 2007?
Should work pretty well, possibly just need a few modifications around the Server/DAG name detection and how it handles public folders vs mailbox databases.
Could just simplify that If/Else block down to just use $db.Server regardless of whether it is PF or MB database.
Pingback: Avoid Running Out of Transaction Log Disk Space on Exchange Servers
Pingback: Como automatizar o envio de email de alerta para backup no Exchange 2010 « Rodrigo Rodrigues .:. www.andersonpatricio.org