Wednesday, July 9, 2014

Windows update automatic e-mail notification

When managing Windows servers, I looked for a way to check update and notificate automatically via email like yum-cron on Redhat/CentOS and found one here. Thank you Paulie.

Though it's written in 2007 but is still working well for Windows 2012 servers.

Below is my modification to categorize MsrcSeverity to Important when it's blank and use Gmail SMTP with authentication.

 '==========================================================================  
 ' NAME:      Windows update automatic e-mail notification  
 ' AUTHOR:      Paul Murana, Accendo Solutions  
 ' DATE :      26/08/2007  
 ' MODIFIED: Luan Nguyen - 7/8/2014  
 '==========================================================================  
 'Change these variables to control which updates trigger an e-mail alert  
 'and to configure e-mail from/to addresses  
 AlertCritical     = 1   
 AlertImportant     = 1  
 AlertModerate     = 0  
 AlertLow     = 0  
 EmailFrom      = "from.email@gmail.com"  
 EmailTo      = "to.email@gmail.com"  
 smtpserver = "smtp.gmail.com"   
 smtpserverport = 465  
 smtpauthenticate = 1  
 sendusername = "from.email@gmail.com"  
 sendpassword = "password"  
 smtpusessl = 1  
 '==========================================================================  
 Set fso           = CreateObject("Scripting.FileSystemObject")  
 Set updateSession      = CreateObject("Microsoft.Update.Session")  
 Set updateSearcher      = updateSession.CreateupdateSearcher()  
 Set oShell           = CreateObject( "WScript.Shell" )  
 computername          = oShell.ExpandEnvironmentStrings("%ComputerName%")  
 DomainName          = oShell.ExpandEnvironmentStrings("%userdomain%")  
 EMailSubject           = "Windows Update Notification - " & DomainName & "\" & computername  
 Set oshell           = Nothing  
 Set searchResult      = updateSearcher.Search("IsInstalled=0 and Type='Software'")  
 If searchResult.Updates.count > 0 Then  
      For I = 0 To searchResult.Updates.Count-1  
        Set update = searchResult.Updates.Item(I)  
           Select Case update.MsrcSeverity  
                Case "Critical"   
                     CriticalCount = Criticalcount+1  
                     CriticalHTML = CriticalHTML & MakeHTMLLine(update)  
                     Wscript.Echo update.MsrcSeverity & " : " & update, vbCRLF  
                Case "Moderate"  
                     ModerateCount = Moderatecount + 1  
                     ModerateHTML = ModerateHTML & MakeHTMLLine(update)  
                     Wscript.Echo update.MsrcSeverity & " : " & update, vbCRLF  
                Case "Low"  
                     Lowcount = Lowcount + 1  
                     LowHTML = LowHTML & MakeHTMLLine(update)  
                     Wscript.Echo update.MsrcSeverity & " : " & update, vbCRLF  
                Case Else '"Important" or blank  
                     ImportantCount = Importantcount + 1  
                     ImportantHTML = ImportantHTML & MakeHTMLLine(update)  
                     Wscript.Echo "Important : " & update, vbCRLF  
           end select                 
      Next  
      If searchResult.Updates.Count = 0 Then  
           Wscript.Echo "No updates :)"  
           WScript.Quit  
      Else  
           If (AlertCritical=1 and CriticalCount > 0) then SendEmail=1 end if  
           If (AlertImportant=1 and ImportantCount > 0) then SendEmail=1 end if  
           If (AlertModerate=1 and ModerateCount > 0) then SendEmail=1 end if  
           If (AlertLow=1 and LowCount > 0) then SendEmail=1 end If  
           if SendEmail=1 and smtpserver <> "" Then  
                Set objMessage           = CreateObject("CDO.Message")   
                objMessage.Subject      = EMailSubject  
                objMessage.From      = EmailFrom  
                objMessage.To           = EmailTo  
                objMessage.HTMLBody      = ReplaceHTMLTemplate()  
                Set iConf = CreateObject("CDO.Configuration")  
                Set Flds = iConf.Fields           
                schema = "http://schemas.microsoft.com/cdo/configuration/"  
                Flds.Item(schema & "sendusing") = 2  
                Flds.Item(schema & "smtpserver") = smtpserver  
                Flds.Item(schema & "smtpserverport") = smtpserverport  
                Flds.Item(schema & "smtpauthenticate") = smtpauthenticate  
                if smtpauthenticate = 1 and sendusername <> "" and sendpassword <> "" then  
                     Flds.Item(schema & "sendusername") = sendusername  
                     Flds.Item(schema & "sendpassword") = sendpassword  
                end if  
                Flds.Item(schema & "smtpusessl") = smtpusessl  
                Flds.Update  
                Set objMessage.Configuration = iConf  
                objMessage.Send  
                set objMessage = nothing  
                set iConf = nothing  
                set Flds = nothing  
                Wscript.Echo "Email sent to " & EmailTo, vbCRLF  
           end if  
      end If  
 End If  
 Function MakeHTMLLine(update)  
      HTMLLine="<tr><td>" & update.Title & "</td><td>" & update.description & "</td><td>"  
      counter     =0       
      For Each Article in Update.KBArticleIDs   
            if counter > 0 then HTMLLine=HTMLLine & "<BR>"  
           HTMLLine=HTMLLine & "<a href=" & chr(34) & "http://support.microsoft.com/kb/" & article & "/en-us" & chr(34) & ">KB" & article & "</a>"  
            counter = counter +1  
        Next   
      For Each Info in Update.moreinfourls   
           if counter > 0 then HTMLLine=HTMLLine & "<BR>"  
           HTMLLine=HTMLLine & "<a href=" & chr(34) & info & chr(34) & ">" & "More information...</a>"  
           counter = counter +1  
        Next        
      HTMLLine = HTMLLine & "</td></tr>"  
      MakeHTMLLine = HTMLLine  
 End function  
 Function ReplaceHTMLTemplate()  
      Set HTMLFile = fso.opentextfile((fso.GetParentFolderName(WScript.ScriptFullName) & "\updatetemplate.htm"),1,false)  
      MasterHTML = HTMLFile.Readall  
      HTMLFile.close  
      MasterHTML = Replace(MasterHTML, "[criticalupdatecontents]", CriticalHTML)  
      MasterHTML = Replace(MasterHTML, "[importantupdatecontents]", ImportantHTML)  
      MasterHTML = Replace(MasterHTML, "[moderateupdatecontents]", ModerateHTML)  
      MasterHTML = Replace(MasterHTML, "[lowupdatecontents]", LowHTML)  
      MasterHTML = Replace(MasterHTML, "[computername]", Computername)  
      MasterHTML = Replace(MasterHTML, "[domainname]", domainname)  
      MasterHTML = Replace(MasterHTML, "[timenow]", now())  
      If (CriticalCount = 0) then  
          MasterHTML = TrimSection(MasterHTML, "<!--CriticalStart-->", "<!--CriticalEnd-->")  
      end if  
      If (ImportantCount = 0) then  
          MasterHTML = TrimSection(MasterHTML, "<!--ImportantStart-->", "<!--ImportantEnd-->")  
   end if  
   If (moderateCount = 0) then  
          MasterHTML = TrimSection(MasterHTML, "<!--ModerateStart-->", "<!--ModerateEnd-->")  
   end if  
      If (LowCount = 0) then       
          MasterHTML = TrimSection(MasterHTML, "<!--LowStart-->", "<!--LowEnd-->")  
   end if  
   ReplaceHTMLTemplate = MasterHTML         
 End Function  
 Function TrimSection(CompleteString,LeftString,RightString)  
      LeftChunkPos=inStr(CompleteString, LeftString)  
      RightChunkPos=inStrRev(CompleteString, Rightstring)  
      LeftChunk=Left(CompleteString, LeftChunkPos-1)  
      RightChunk=mid(CompleteString, RightChunkPos)  
      TrimSection=LeftChunk & RightChunk  
 End Function