En mi trabajo tengo que administrar un montón de servidores Windows 2008R2 y Windows 2012R2 y muchas veces me pierdo en cuanto ha actualizaciones. Lo que hago en este caso es programarme un script en powershell que me permite saber en cada servidor cuantas actualizaciones hay y como son (críticas o opcionales) con lo que llevo un pequeño registro y control de las mismas. Obviamente, lo que no os recomiendo es actualizar enseguida i cada semana. Lo suyo en cuanto a servidores es actualizar cada 30 o 60 días.
Os dejo el script 🙂
'==========================================================================
' NOMBRE: Notificaciones automáticas via mail de actualizaciones
' AUTOR: Paul Murana
'==========================================================================
'Cambiad estas variables para controlar los criterios de los avisos del mail
'y para configurar el servidor y los campos para/de
AlertCritical = 1
AlertImportant = 1
AlertModerate = 1
AlertLow = 1
AlertOthers = 1
EmailFrom = ""
EmailTo = ""
RemoteSMTPServer= ""
RemoteSMTPPort = "25"
'==========================================================================
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)
Case "Important"
ImportantCount = Importantcount + 1
ImportantHTML = ImportantHTML & MakeHTMLLine(update)
Case "Moderate"
ModerateCount = Moderatecount + 1
ModerateHTML = ModerateHTML & MakeHTMLLine(update)
Case "Low"
Lowcount = Lowcount + 1
LowHTML = LowHTML & MakeHTMLLine(update)
Case Else
Otherscount = Otherscount + 1
OthersHTML = OthersHTML & MakeHTMLLine(update)
end select
Next
If searchResult.Updates.Count = 0 Then
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 (AlertOthers=1 and OthersCount > 0) then SendEmail=1 end If
if SendEmail=1 Then
Wscript.Echo "sendEmail"
Set objMessage = CreateObject("CDO.Message")
objMessage.Subject = EMailSubject
objMessage.From = EmailFrom
objMessage.To = EmailTo
objMessage.HTMLBody = ReplaceHTMLTemplate()
if RemoteSMTPServer <> "" then
objMessage.Configuration.Fields.Item ("http://schemas.microsoft.com/cdo/configuration/sendusing") = 2
objMessage.Configuration.Fields.Item ("http://schemas.microsoft.com/cdo/configuration/smtpserver") = RemoteSMTPServer
objMessage.Configuration.Fields.Item ("http://schemas.microsoft.com/cdo/configuration/smtpserverport") = RemoteSMTPPort
objMessage.Configuration.Fields.Update
end if
objMessage.Send
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, "[othersupdatecontents]", OthersHTML)
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
If (OthersCount = 0) then
MasterHTML = TrimSection(MasterHTML, "<!--OthersStart-->", "<!--OthersEnd-->")
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
Guardamos el script en un fichero con extensión VBS (p.ej. yo lo llamo WinUpdates.vbs) y acto seguido lo único que debemos hacer és crear un script cmd o bat para que ejecute el fichero vbs y añadirlo a las tareas programadas.
cscript C:\WinUpdates\WinUpdates.vbs
Y voilá… nuestro script para avisos de updates de Windows listo 🙂
ACTUALIZACIÓN: Un lector del blog me ha hecho saber que aparece un error «Se sobrepasó el final del archivo». Bien, para solucionar esto, os dejo el código del fichero *.htm que debéis guardar como «updatetemplate.htm» en el mismo directorio donde tenéis el resto de los ficheros:
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"><html dir="ltr" lang="EN-US">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=Windows-1252">
<meta http-equiv="MSThemeCompatible" content="yes">
<meta name="MS-HAID" content="a_TablDefs">
<meta name="MS.LOCALE" content="EN-US">
<title>Windows updates status report</title>
<meta name="COMPONENT" content="unassigned">
</head>
<style type="text/css">
body { color: #000000;
background: #FFFFFF;
font-size: 80%;
font-family: Verdana, Arial, Sans Serif;
margin-left: 0em;
padding-left: 1.5em; }
a:link, a:visited { color: #0000FF; text-decoration:underline;}
a:active, a:hover { color: #FF0000; cursor:hand; text-decoration:underline;}
a.#reltopics { position:relative; top:1em; }
h1
{ font-size: 125%;
margin-bottom: .5em; clear:both; width: 85%; }
h2
{ font-size: 115%;
margin-top: 1.5em;
margin-bottom: .5em; clear:both; }
h3
{ font-size: 105%;
margin-top: 1.2em;
margin-bottom: .5em; clear:both; }
h4
{ font-size: 105%;
margin-top: 1.2em;
margin-bottom: .5em; clear:both; }
h5
{ font-size: 105%;
margin-top: 1.2em;
margin-bottom: .5em; clear:both; }
p
{ margin-top: .6em;
margin-bottom: .6em; }
ol
{ margin-top: .5em;
margin-bottom: 0em;
margin-left: 2.1em;
padding-left: 0em;
margin-right:2.1em; }
ul
{ margin-top: .6em;
margin-bottom: 0em;
list-style-type: disc;
margin-left: 1.5em;
padding-left: 0em;
margin-right: 1.5em; }
li
{ margin-bottom: .7em; clear:both; }
dd
{ margin-bottom: 0em;
margin-left: 1.5em; }
dt
{ margin-top: 1em; }
pre
{ margin-top: .5em;
margin-bottom: .5em; }
code
{ font-family: Courier New;
font-size: 1.1em; }
table
{ font-size: 100%;
margin-top: 1em;
margin-bottom: 1em; }
th
{ text-align: left;
background: #DDDDDD;
vertical-align: bottom;
padding: .2em;
padding-left: .45em;
padding-right: .5em;}
tr
{ vertical-align: top; }
td
{ background: #EEEEEE;
vertical-align: top;
padding: .2em;
padding-left: .45em;
padding-right: .5em;}
p.indent { margin-left: 1.3em; } /* used to indent text for notes and warnings; use this instead of the blockquote tag */
p.indent2 { margin-left: 3.5em; } /* used to indent text a second level under the first indent */
P.indentGray { color: #666666; } /* used in quad-method procedures */
p.procLabel { font-size: 105%;
font-weight: bold; clear: both; width: 85%; margin-top: 2em; }
p.uatshoot { font-weight: bold; margin-bottom: -.5em; margin-top: 1em; }
table.uatshoot {background-color: #FFFFFF; width: 90%; }
table.uatshoot td { padding: 0px 0px 0px 5px; }
p.note,p.tip, p.important, p.caution, p.warning
{ font-weight:bold; clear:both;
margin-top:1em;
margin-bottom:-.25em; }
</style>
<body>
<h1 class="topicHeading">Windows Update Status Report - [timenow]</h1>
<p><b>[domainname]\[computername]</b></p>
<br>
<!--CriticalStart-->
<div ID=Critical>
<p><b>Critical Updates</b></p>
<table>
<tbody>
<tr>
<th width="20%">Title</th>
<th width="70%">Description</th>
<th width="10%">Links</th>
</tr>
[criticalupdatecontents]
</tbody>
</table>
</div>
<!--CriticalEnd-->
<!--ImportantStart-->
<div ID=Important>
<p><b>Important Updates</b></p>
<table>
<tbody>
<tr>
<th width="20%">Title</th>
<th width="70%">Description</th>
<th width="10%">Links</th>
</tr>
[importantupdatecontents]
</tbody>
</table>
</div>
<!--ImportantEnd-->
<!--ModerateStart-->
<div ID=Moderate>
<p><b>Moderate Priority Updates</b></p>
<table>
<tbody>
<tr>
<th width="20%">Title</th>
<th width="70%">Description</th>
<th width="10%">Links</th>
</tr>
[moderateupdatecontents]
</tbody>
</table>
</div>
<!--ModerateEnd-->
<!--LowStart-->
<div ID=Low>
<p><b>Low Priority Updates</b></p>
<table>
<tbody>
<tr>
<th width="20%">Title</th>
<th width="70%">Description</th>
<th width="10%">Links</th>
</tr>
[lowupdatecontents]
</tbody>
</table>
</div>
<!--LowEnd-->
<!--OthersStart-->
<div ID=Others>
<p><b>Others Priority Updates</b></p>
<table>
<tbody>
<tr>
<th width="20%">Title</th>
<th width="70%">Description</th>
<th width="10%">Links</th>
</tr>
[othersupdatecontents]
</tbody>
</table>
</div>
<!--OthersEnd-->
</body>
</html>
Hecho esto, ya no os debería dar problemas.
Fuente | Microsoft Script Center