Installer automatiquement les patchs critiques de Windows Update en Vbscript
Comment télécharger et installer automatiquement les patchs critiques et de sécurité de Windows Update en VbScript
Au préalable, si vous avez besoin de paramétrer Windows Update pour :
• Ne pas authoriser la mise à jour automatique
• Rechercher les mises à jours mais laisser choisir pour téléchargement et installation
• Décocher "Recevoir les mises à jour recommandées de la même façon que vous recevez les mises à jour importantes"
• Ne pas authoriser tous les utilisateurs à installer les mises à jour (donc il faudra être admin)
Alors entrez les commandes suivantes :
REG ADD "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\WindowsUpdate\Auto Update" /v "NoAutoUpdate" /t REG_DWORD /d 0 /f
REG ADD "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\WindowsUpdate\Auto Update" /v "AUOptions" /t REG_DWORD /d 2 /f
REG ADD "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\WindowsUpdate\Auto Update" /v "IncludeRecommendedUpdates" /t REG_DWORD /d 0 /f
REG ADD "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\WindowsUpdate\Auto Update" /v "ElevateNonAdmins" /t REG_DWORD /d 0 /f
Lien vers le fichier : cliquez ici
Pour télécharger les maj mais ne pas installer
REG ADD "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\WindowsUpdate\Auto Update" /v "AUOptions" /t REG_DWORD /d 3 /f
Lien vers le fichier : cliquez ici
On peut donc faire un bat qui pose ces clés de registre et qui lance le .vbs situé dans le même répertoire
cd /d %~dp0
REG ADD "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\WindowsUpdate\Auto Update" /v "NoAutoUpdate" /t REG_DWORD /d 0 /f
REG ADD "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\WindowsUpdate\Auto Update" /v "AUOptions" /t REG_DWORD /d 3 /f
REG ADD "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\WindowsUpdate\Auto Update" /v "IncludeRecommendedUpdates" /t REG_DWORD /d 0 /f
REG ADD "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\WindowsUpdate\Auto Update" /v "ElevateNonAdmins" /t REG_DWORD /d 0 /f
cscript.exe VbsWindowsUpdate.vbs -reboot 0
Lien vers le fichier : cliquez ici
Et une tâche planifiée déclenche le bat
Le script vbs qui télécharge les patchs critiques et de sécurité puis qui les installe
'Version du 23/02/2015 : ajout du passage de paramètres
'Version du 12/02/2015 : ajout de l'écriture d'un fichier de log
'VbScript inspiré à partir de celui-ci :
'https://msdn.microsoft.com/en-us/library/aa387102%28VS.85%29.aspx
Dim objFSO, objTextFile
Dim NomFichier, CheminFichier, CheminScriptActuel, ScriptFileName, Position
Dim ActualDay, MyDay, MyMonth, varTime
Dim WSHShell, vCOMPUTERNAME
Dim varTypeDePatchsAinstaller, varReboot
'Déclaration des constantes
Const ForReading = 1
Const ForWritting = 2
Const ForAppending = 8
varTypeDePatchsAinstaller = "" 'Valeur par défaut
varReboot = "" 'Valeur par défaut
call ParseCommand() 'Parse the command line.
MyDay = Day(Now)
MyMonth = Month(Now)
If Len(MyDay) = 1 Then MyDay = "0" & MyDay
If Len(MyMonth) = 1 Then MyMonth = "0" & MyMonth
ActualDay = Year(Now) & "-" & MyMonth & "-" & MyDay
varTime = Time
varTime = Replace(varTime, ":", "-") 'Remplacement des : par - car : est un caractère interdit dans les noms de fichiers
Set WSHShell = CreateObject("WScript.Shell")
vCOMPUTERNAME = WSHShell.ExpandEnvironmentStrings("%COMPUTERNAME%")
ScriptFileName = wscript.scriptname
Position = InstrRev(ScriptFileName,".")
if (Position > 0) Then ScriptFileName = Left(ScriptFileName, Position - 1)
NomFichier = ScriptFileName & "_Log_" & vCOMPUTERNAME & "_" & ActualDay & "_" & varTime & ".txt"
CheminScriptActuel = Left(wscript.scriptfullname,Len(wscript.scriptfullname)-Len(wscript.scriptname)-1)
CheminFichier = CheminScriptActuel & "\" & NomFichier 'Déclaration du chemin et du nom du fichier
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objTextFile = objFSO.OpenTextFile(CheminFichier, ForWritting, True)
Set updateSession = CreateObject("Microsoft.Update.Session")
Set updateSearcher = updateSession.CreateupdateSearcher()
'ServerSelection values
ssDefault = 0
ssManagedServer = 1
ssWindowsUpdate = 2
ssOthers = 3
Set updateSession = CreateObject("Microsoft.Update.Session")
'updateSession.ClientApplicationID = "MSDN Sample Script"
Set updateSearcher = updateSession.CreateUpdateSearcher()
updateSearcher.ServerSelection = ssWindowsUpdat
objTextFile.WriteLine("Recherche des updates...")
'On lance une recherche sur les softs non installés non cachés (de ce que j'en comprends)
Set searchResult = updateSearcher.Search("IsInstalled=0 and Type='Software' and IsHidden=0")
objTextFile.WriteLine("Recherche effectuee")
'Affichage du résultat
objTextFile.WriteLine("Liste des patchs disponibles :")
For I = 0 To searchResult.Updates.Count-1
Set update = searchResult.Updates.Item(I)
objTextFile.WriteLine(I + 1 & "> " & update.Title)
Next
'Si pas de résultat, arret du script
If searchResult.Updates.Count = 0 Then
objTextFile.WriteLine("There are no applicable updates.")
WScript.Quit
End If
'Si résultat, création d'une collection contenant les patchs à télécharger
objTextFile.WriteLine("Creation de la liste des patchs à télécharger:")
Set updatesToDownload = CreateObject("Microsoft.Update.UpdateColl")
'On scrute tous les patchs disponibles pour téléchargement puis on va faire une sélection
For I = 0 to searchResult.Updates.Count-1
'IUpdate properties : https://msdn.microsoft.com/en-us/library/windows/desktop/aa386915%28v=vs.85%29.aspx
Set update = searchResult.Updates.Item(I) 'Création d'un objet qui correspond à 1 update en particulier parmis ceux disponibles au téléchargement
addThisUpdate = false 'Valeur par défaut
objTextFile.WriteLine(I + 1 & ") " & update.Title) ' "Affichage du titre du patch"
'Affichage d'infos
objTextFile.WriteLine(VbTab & "Severity : " & update.MsrcSeverity)
'WScript.Echo VbTab & "IsMandatory : " & update.IsMandatory
'WScript.Echo VbTab & "DownloadPriority : " & update.DownloadPriority
'Affichage de la catégorie
Set objCategories = update.Categories 'On stocke dans l'objet objCategories la catégorie de l'update analysé
strCatName = lcase(objCategories.Item(0).Name) 'On stocke dans une variable la première entrée contenu dans l'objet qui a les infos sur la catégorie
objTextFile.WriteLine(VbTab & "Catégorie : " & strCatName)
'If strCatName = "critical updates" Then addThisUpdate = True 'Si c'est un patch de sécurité, on le prend
'If strCatName = "security updates" Then addThisUpdate = True 'Si c'est un patch critique, on le prend
'If InStr(strCatName,"office") And InStr(update.description,"security") Then addThisUpdate = True 'Si c'est un patch office en relation avec la sécurité, on le prend
'Si le patch demande une intervention de l'utilisateur, on l'ignore
If update.InstallationBehavior.CanRequestUserInput = true Then
objTextFile.WriteLine(VbTab & " Patch ignoré car demande intervention de l'utilisateur")
Else 'Si le patch ne demande pas d'intervention de l'utilisateur
If Lcase(varTypeDePatchsAinstaller) = "all" Then 'Si on a demandé à prendre tous les patchs alors on accepte forcément celui-ci
addThisUpdate = true
Else 'Sinon on ne prend que les patchs Critical et Important
'If update.MsrcSeverity = "Critical" Or update.MsrcSeverity = "Important" Or update.MsrcSeverity = "Moderate" Or update.MsrcSeverity = "Low" Then addThisUpdate = true
If update.MsrcSeverity = "Critical" Or update.MsrcSeverity = "Important" Then addThisUpdate = true
End If
'Select case Lcase(varTypeDePatchsAinstaller)
'Case "all"
'addThisUpdate = true
'End Select
'Normalement on demande au user si il veut accepter la licence. Pour des besoins d'automatisation on dit oui tout le temps
If update.EulaAccepted = false Then
objTextFile.WriteLine(VbTab & "Acceptation automatique du Eula pour le patch " & update.Title)
update.AcceptEula() 'On accepte automatiquement le Eula
End If
'Si au final le patch a retenu une catégorie qui nous intéresse, on le retient pour téléchargement
If addThisUpdate = true Then updatesToDownload.Add(update)
End If
Next
'Si rien à télécharger, alors on quitte
If updatesToDownload.Count = 0 Then
objTextFile.WriteLine("All applicable updates were skipped.")
WScript.Quit
End If
objTextFile.WriteLine("")
'Listing des patchs retenus
objTextFile.WriteLine("Liste des patchs retenus :")
For I = 0 to updatestoDownload.Count-1
objTextFile.WriteLine(VbTab & updatestoDownload.Item(I))
'Set objCategories = updatestoDownload.Item(I).Categories 'On stocke dans l'objet objCategories la catégorie de l'update analysé
'strCatName = lcase(objCategories.Item(0).Name) 'On stocke dans une variable la première entrée contenu dans l'objet qui a les infos sur la catégorie
' Wscript.echo VbTab & strCatName
Next
'Si téléchargements à faire, go
objTextFile.WriteLine("Lancement des téléchargements ...")
'Création d'un objet Downloader et assignation des updates à télécharger
Set downloader = updateSession.CreateUpdateDownloader()
downloader.Updates = updatesToDownload
downloader.Download() 'Lancement du download
Set updatesToInstall = CreateObject("Microsoft.Update.UpdateColl") 'Création d'un objet Updates
rebootMayBeRequired = false 'Valeur par défaut. Sera ensuite à 1 si un patch demande un reboot
'On rescan l'objet Updates et on regarde ceux dispos après téléchargement. Si un patch demande reboot, on le note dans la variable rebootMayBeRequired
'Les patchs à installer sont stockés dans la collection updatesToInstall
objTextFile.WriteLine(vbCRLF & "Successfully downloaded updates:")
For I = 0 To searchResult.Updates.Count-1
set update = searchResult.Updates.Item(I)
If update.IsDownloaded = true Then
objTextFile.WriteLine(VbTab & I + 1 & "> " & update.Title)
updatesToInstall.Add(update)
If update.InstallationBehavior.RebootBehavior > 0 Then
rebootMayBeRequired = true
End If
End If
Next
'Si pas de patch à installer, alors on arrête
If updatesToInstall.Count = 0 Then
objTextFile.WriteLine("No updates were successfully downloaded.")
WScript.Quit
End If
'Si on a noté que des patchs demandent reboot, on le dit
If rebootMayBeRequired = true Then
objTextFile.WriteLine("Des patchs demandent un reboot")
End If
'On lance l'installation des updates
'Pour cela on crée l'objet "installer", on lui assigne les updates à installer qui sont stockées dans updatesToInstall puis on lance l'install
objTextFile.WriteLine("Installing updates...")
Set installer = updateSession.CreateUpdateInstaller()
installer.Updates = updatesToInstall 'Assignation des updates à installer
Set installationResult = installer.Install() 'Lancement des installations
'On affiche le résultat global des installations
objTextFile.WriteLine("Installation Result: " & installationResult.ResultCode)
'On indique si un reboot est nécessaire
objTextFile.WriteLine("Reboot Required: " & installationResult.RebootRequired)
'Affichage de la bonne installation des patchs, patch par patch
objTextFile.WriteLine("Listing of updates installed and individual installation results:" )
For I = 0 to updatesToInstall.Count - 1
'objTextFile.WriteLine(I + 1 & "> " & updatesToInstall.Item(i).Title & ": " & installationResult.GetUpdateResult(i).ResultCode)
objTextFile.WriteLine(I + 1 & "> " & updatesToInstall.Item(i).Title & ": " & installationResult.GetUpdateResult(i).ResultCode & ". HResult : " & installationResult.GetUpdateResult(i).HResult)
Next
If 1 = 2 Then
WScript.Echo vbCRLF & "Would you like to install updates now? (Y/N)"
strInput = WScript.StdIn.Readline
WScript.Echo
If (strInput = "Y" or strInput = "y") Then
WScript.Echo "Installing updates..."
Set installer = updateSession.CreateUpdateInstaller()
installer.Updates = updatesToInstall
Set installationResult = installer.Install()
'Output results of install
WScript.Echo "Installation Result: " & _
installationResult.ResultCode
WScript.Echo "Reboot Required: " & _
installationResult.RebootRequired & vbCRLF
WScript.Echo "Listing of updates installed " & _
"and individual installation results:"
For I = 0 to updatesToInstall.Count - 1
WScript.Echo I + 1 & "> " & _
updatesToInstall.Item(i).Title & _
": " & installationResult.GetUpdateResult(i).ResultCode
Next
End If
End If
'Reboot
objTextFile.WriteLine("varReboot : " & varReboot)
If Cstr(varReboot) = "1" Then
objTextFile.WriteLine("Launch reboot")
objTextFile.Close 'Fermeture du fichier
Commande = "Shutdown.exe -r -f -t 10 -d p:2:4"
WSHShell.Run Commande
End If
Set WSHShell = Nothing
Set objTextFile = Nothing
Set objFSO = Nothing
Function ParseCommand()
'
' Parses the command line and fills the script variables
' with the appropriate values.
'
Dim ArgCount
Dim objArgs
Set objArgs = Wscript.Arguments
ArgCount = 0
if objArgs.Count = 0 then
wscript.echo "No arguments specified."
wscript.echo
'call Help()
end if
While ArgCount < objArgs.Count
Select Case LCase(objArgs(ArgCount))
Case "-type"
ArgCount = ArgCount + 1
varTypeDePatchsAinstaller=LCase(objArgs(ArgCount))
wscript.echo "varTypeDePatchsAinstaller : " & varTypeDePatchsAinstaller
Case "-reboot"
ArgCount = ArgCount + 1
varReboot=LCase(objArgs(ArgCount))
wscript.echo "varReboot : " & varReboot
Case Else:
wscript.echo "Invalid command."
wscript.echo
call Help()
wscript.quit
End Select
ArgCount = ArgCount + 1
Wend
End Function
sub Help()
'
' Display command-line syntax for the script.
'
wscript.echo "Script Function details"
wscript.echo "Syntax:"
wscript.echo
wscript.echo "-type ""type of patchs to install. It may be"""
wscript.echo "Example"
wscript.echo
wscript.echo "Examples"
wscript.echo "To install of kind of patchs :"
wscript.echo "C:\MyScript.vbs -type ""all"""
wscript.echo
wscript.echo "To install only critical and security patchs :"
wscript.echo "C:\MyScript.vbs"
wscript.echo
wscript.echo "To reboot in all cases when updates finished :"
wscript.echo "C:\MyScript.vbs -reboot 1"
wscript.echo
wscript.quit
End Sub
Lien vers le fichier : cliquez ici
Juste pour trace, le code d'origine donné en exemple sur
http://ks-soft.net/cgi-bin/phpBB/viewtopic.php?t=6332&start=15&
const statusAlive = "scriptRes:Host is alive:"
const statusDead = "scriptRes:No answer:"
const statusUnknown = "scriptRes:Unknown:"
const statusNotResolved = "scriptRes:Unknown host:"
const statusOk = "scriptRes:Ok:"
const statusBad = "scriptRes:Bad:"
const statusBadContents = "scriptRes:Bad contents:"
' check this category for 'High Priority' updates
category = "UpdateClassification"
highpriority = ",Security Updates,Update Rollups,Critical Updates,"
' create instance of update.searcher (offline)
Set objSearcher = CreateObject("Microsoft.Update.Searcher")
objSearcher.Online = 1
' find and fetch collection of updates
Set objResults = objSearcher.Search("Type='Software' and IsInstalled=0")
Set colUpdates = objResults.Updates
count = 0
For i = 0 to colUpdates.Count - 1
' check categories
Set colCategories = colUpdates.Item(i).Categories
For c = 0 to colCategories.Count - 1
If colCategories.item(c).Type = category _
And InStr(highPriority, "," & colCategories.item(c).Name & ",") > 0 Then
count = count + 1
End If
Next
Next
'send results to host monitor
if count > 0 then
WScript.StdOut.Write statusBad & count & " high priority updates found!"
else
WScript.StdOut.Write statusOk & "No new high priority updates found"
End If
Lien vers le fichier : cliquez ici
Notez que sur le post suivant on explique qu'il est préférable d'utiliser la classification au lieu de la sévérité :
http://ks-soft.net/cgi-bin/phpBB/viewtopic.php?t=6332&start=15&
sid=dcbfefcb3d35c6b2720bbcba63141528
Pages Web
| Site Web | Description |
|---|---|
| MSDN | Searching, Downloading, and Installing Updates |
| Ks-soft.net forum | Post de forum avec un passage qui explique qui est préférable d'utiliser la classification au lieu de la sévérité |
| Ms technet | Explication sur la valeur des clés de registre pour paramétrer Windosw Update |
| Technet.microsoft.com | Security Bulletin Severity Rating System |
Article(s) suivant(s)
Article(s) précédent(s)
Article(s) en relation(s)