Windows update automatic e-mail notification

As the number of servers that I am responsible for managing increases, it becomes more difficult to ensure that they are all patched up to date.

As most of the machines I manage are SBS boxes I thought that it would be nice to put something together which behaves in much the same way as the SBS generated e-mail alerts.

So, the result is a script which sends e-mail notifications to a specified address and gives details of which patches are available to be installed.  The administrator can choose which of the four patch levels will trigger an e-mail alert (Critical, Important, Moderate & Low).

If there are no outstanding patches at the appropriate alert levels to be installed then the script will quit without sending an e-mail.

The script is then run as a scheduled task every evening and I can quickly see if I have anything to action.  The report includes links to the relevant KB articles and further information made available by Microsoft.


The script only takes a couple of minutes to setup as there are only six settings at the top of the file…

Setting any of the following to 1 will generate trigger alerts for that particular update severity:

  • AlertCritical
  • AlertImportant
  • AlertModerate 
  • AlertLow
  • EmailFrom – Specifies the e-mail address the report will be sent from.
  • EmailTo – Specifies the e-mail address to send the reports to.


As shown above I have been running with AlertCritical/AlertImportant set to 1 and the other two set to 0. 

So, if you want to receive email alerts all you need to do is download this Zip file, extract the contents to a folder on your server and then edit the variables at the top of the script.  To perform a test run go into a command prompt and change directory to the location where you extracted the script and run:

cscript winupdates.vbs

With any luck you should get an e-mail soon after with the results.  If you find that it is not generating you an e-mail as expected, one reason may be that there are no patches available to install.  Bear in mind that not all items from Windows update will appear.  For example “Internet Explorer 7″ is not a patch and therefore will not be listed.

Running the script interactively as above will take a few moments while Windows Update(or WSUS if you have it installed) are checked for new updates. 

Once you have completed a successful test you can go ahead and setup a scheduled task.  Assuming an installation directory of “c:\scripts” the scheduled task command should look something like this:

C:\WINDOWS\system32\cscript.exe c:\scripts\winupdates.vbs

Also worth a mention that I have used this on standard(non-sbs) Windows servers and it works well.

Perhaps if enough people use this script, it will actually save as much time as it took to make it, but I doubt it. :)

37 thoughts on “Windows update automatic e-mail notification

  1. Hi Paul,

    Tried using this but the script would either give no output (even though there were needed updates on the server) or would give this following error even though I entered in my sendfrom and sendto email addresses correctly:

    c:\scripts\winupdates.vbs(60, 4) CDO.Message.1: The “SendUsing” configuration value is invalid.

    Any ideas? I tried on both Server 2003 R2 and Server 2000 SP4. WSUS is configured via GPO on these servers and is able to push out updates, so the update query to my WSUS 3 server appears to be working fine.

  2. Ok, I figured it out. The VBScript you have assumes there is a local smtp server to send out the notification. If your using a remote SMTP server, then insert this code in the section that specifies the message objects (objMessage.Subject, etc):

    ‘==This section provides the configuration information for the remote SMTP server.
    ‘==Normally you will only change the server name or IP.
    objMessage.Configuration.Fields.Item _
    (“”) = 2

    ‘Name or IP of Remote SMTP Server
    objMessage.Configuration.Fields.Item _
    (“”) = “”

    ‘Server port (typically 25)
    objMessage.Configuration.Fields.Item _
    (“”) = 25


    ‘==End remote SMTP server configuration section==


  3. I have updated the script to include support for remote SMTP servers.

    Edit the variables at the top of the script to specify a server. Could be extended for SMTP auth as well.

  4. Very nice feature.
    I have tested it on Windows Server 2008 as well, and it seems to work OK. I’ll asume this will be the same on Vista

  5. Paulie,

    When you say “could be extended for SMTP auth as well,” what does it take to use, say, Gmail to send? I don’t see a variable for username and password for SMTP auth.

  6. Paulie, this sounds like a very handy script! I am not script junkie though and I am not sure how to add SMTP authentication so that the server can send e-mail. Would you mind pasting in the code or updating the zip with that?

    I would lovvve to be able to use this to keep on top of updates on all my servers, but without SMTP authentication, I can’t send e-mail!

    Thanks soo much. I hope you, or someone still checks out this post.

  7. for those who need SMTP authentication …
    objMessage.Configuration.Fields.Item (“”) = RemoteSMTPUser
    objMessage.Configuration.Fields.Item (“”) = RemoteSMTPPass
    objMessage.Configuration.Fields.Item (“”) = 1

    by the way: … great script *thumbs up*

  8. Is there anyway that we could add a listing of the machine’s IP address in the header along beside the computer name?

    Have been tinkering with it, but no luck thus far.

  9. I am trying to get this work with gmail. Would it be possible to provide a working example I could use?

  10. I am trying to get this working as well. Does the cdo webpage still work (Microsoft)? When I try to go to the URL, I get a page not found.

  11. Dear Sir/Madam,

    Script sounds nice, can you tell me where i can download the script ? is theire any download link ?

    I looking forward to hear from you, thanks and have a nice day.

    Best regards,
    Adriaan Bredero

  12. Hi Paulie,

    Thanks for the link, i have downloaded the file but i have another question.

    Is it reguired that i fill in a remote SMTP server ? when i leave the SMTP server empty. (will the server try to send the e-mail by himself ?)

    Does the script also works with Windows Server 2003 ? or only with the 2008 versions and higher ?

    I looking forward to hear from you, thanks and have a nice day.

    Best regards,
    Adriaan Bredero

  13. Hi Paulie,

    I have added the SMTP credentials to the script, but i get an error.

    Is it possible that you can change the script so the auth SMTP credentials can be filled in, in the script ? now i can only fill in the SMTP address but not the loginname and password. (reguired to send e-mail)

    I looking forward to hear from you, thanks.

    Best regards,
    Adriaan Bredero

  14. HI Paul

    I find this script extremely useful in its purpose. Well done.

    However, I have installed it (and modified to fit my personal SMTP server API object instead of the one you have included) but I notice there is a problem that maybe you might have an answer for.

    I noticed that with a lot of the updates the ‘MsrcSeverity’ value was not being filled and therefore the script was not performing correctly (for readers, the value of this ‘field’ contains the severity “Critical”, “Important” etc and is need to filter out and report whats what). I did a number of tests on various updates by using the wscript.echo command to output the value and quite often (but not always) it was blank. It took a long time to figure this out by involving using the script to list all patches and updates, even ones that have already been installed (removing Isinstalled from updateSearcher.Search(“IsInstalled=0″ ) and adding WScript.Echo update.Title & ” ‘”&update.MsrcSeverity&”‘” for everyone found to show their title and severity. As a consequence I have slightly mod’ed the script to assume all ‘blank’ severities (MsrcSeverity) as important. Im no specialist and made the following change:

    Select Case severity
    Case “‘Critical’”
    CriticalCount = Criticalcount+1
    CriticalHTML = CriticalHTML & MakeHTMLLine(update)
    Case “‘Important’”
    ImportantCount = Importantcount + 1
    ImportantHTML = ImportantHTML & MakeHTMLLine(update)
    ‘ Next added to incorporate missing severity report (seems common) and default assume them to IMPORTANT
    Case “””
    ImportantCount = Importantcount + 1
    ImportantHTML = ImportantHTML & MakeHTMLLine(update)
    (note the intro of the variable ‘severity’ and the inclusion of quotes around the CASE tests)

    I dont know why only some updates have the MsrcSeverity value filling because you would think they all do (assuming this is what drives the Windows Update screen too). An example of an update that has it missing is the IMPORTANT update for Windows Defender definitions (but there are many other ‘patches’ too)

    Do you have any idea as to what is happening or a better way of handling this?

  15. You are right to make the blank ones appear as important because they may well be so it’s safer to include them. You can do that better by making the Case “Important” because a Case Else and moving the section to the bottom of the case list so that anything not understood is caught.

    I just tried this script on a Windows Server 2012 R2 and it worked great. I may even translate the principles into a c# program that I have for monitoring disk space, etc. as it’s that useful a script :)

  16. I am glad that you approve of code that I wrote seven years ago! I can hardly remember the code but I am very pleased, and surprised to hear that it still works in Windows Server 2012 r2!

    I’d be worried to look at the code again now, normally when I look at anything I wrote over a year ago it makes me shudder, but I do remember being quite pleased with this one in particular.

  17. Paulie…..We are in the process of moving from Windows Server 2003 to Windows Server 2008. We had several scripts using CDO to send e-mails which on our new 2008 server do not work. The new machine has Office 2010 installed.

    Did you do anything special to get CDO installed and running on the 2008 server?


  18. You need to run your scripts in 32-bit mode and the will work again, take a look in:


  19. Paulie…Thanks for the information, but the decision seems to be to rewrite the scripts in Powershell. We’ll see how that goes….RDK

  20. Hey great job with the script can you think of anyway to make it so we’d receive an email when the updates are finished installing like bringing on a new Domain controller and waiting for it to finish patching can take hours.

  21. Kudos on a long-life good tool.
    Someone once asked about not listing hidden updates, and I needed that myself, a quick web search gave me the solution: add “and IsHidden=0″ to the search query:
    Set searchResult = updateSearcher.Search("IsInstalled=0 and Type='Software'")
    Set searchResult = updateSearcher.Search("IsInstalled=0 and Type='Software' and IsHidden=0")

  22. This script is fantastic!! I do have a question though. I am in charge of maintaining 100 computers, and I cannot possibly sort through 100 emails everyday. Is there any way to add a piece to the script that would only send the email if there are updates for the computer? That would be awesome.


  23. I believe it already does that, for example if you set AlertCritical to 1 and all of the others to 0, it will only email you regarding that particular computer when there are critical updates. If there are none, then it won’t send the email.

    I could be wrong, it’s been many years since I last looked at it,but I am pretty sure that is how it works.

  24. Oh. Ok. I didn’t notice that yet. Haven’t put it on any other computers yet. But, this script is really going to make my life a little easier!! Thank you very much for it.

Leave a Reply

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

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>