Mit diesem Script wird bei jedem Start per always.ins (wahlweise auch nur einmalig oder bei der Neuinstallation per setup.ins) der interne WSUS Server nach neuen Updates gefragt. So kann ein Client schon bei der Installation durchgepatcht werden. Evtl funktioniert das script auch ohne WSUS. Habe ich allerdings nicht getestet. Als Betriebssystem habe ich Windows XP SP3 verwendet.
By — Scorcher 2012/10/04 14:05
[Initial] setLogLevel=9 ; Log Errors in Logfile but don't abort: ExitOnError=false ; Show syntax errors in the script: ScriptErrorMessages=on ; Dont trace step by step through the script: TraceMode=off ; let started programs run in front of the winst window StayOnTop=false [Actions] requiredWinstVersion >= "4.10.8.6" DefVar $ProductId$ DefVar $Version$ DefVar $LogDir$ DefVar $Inst_Cmd32$ DefVar $Inst_Prg$ DefVar $MinimumSpace$ DefVar $INST_architecture$ DefVar $INST_SystemType$ DefVar $LicenseRequired$ DefVar $LicensePool$ DefVar $Uninst_Prg$ Set $INST_SystemType$ = GetSystemType set $INST_architecture$ = GetProductProperty("install_architecture","system specific") Set $LogDir$ = "%SystemDrive%\tmp" ; ---------------------------------------------------------------- ; - Please edit the following values - ; ---------------------------------------------------------------- ;$ProductId$ should be the name of the product in opsi ; therefore please: only lower letters, no umlauts, ; no white space use '-' as a seperator Set $ProductId$ = "Windows Updates - WSUS" Set $Version$ = "1.0" Set $MinimumSpace$ = "500 MB" Set $LicenseRequired$ = "false" Set $LicensePool$ = "p_" + $ProductId$ Set $Inst_Prg$ = "script.cmd" Set $Uninst_Prg$ = "" Set $Inst_Cmd32$ = "" ; ---------------------------------------------------------------- if not(HasMinimumSpace ("%SystemDrive%", $MinimumSpace$)) LogError "Not enough space on %SystemDrive%, " + $MinimumSpace$ + " on drive %SystemDrive% needed for " + $ProductId$ isFatalError ; Stop process and set installation status to failed else comment "Show product picture" ShowBitmap "%ScriptPath%\" + $ProductId$ + ".png" $ProductId$ if $LicenseRequired$ = "true" comment "Licensing required, reserve license and get license key" Sub_get_licensekey endif comment "installing" if (($INST_SystemType$ = "x86 System") and ($INST_architecture$ = "system specific")) or ($INST_architecture$ = "both") or ($INST_architecture$ = "32 only") Message "Installing " + "Windows Updates" + " - This may take a lot of time..." comment "Start setup program. This may take a lot of time ..." Winbatch_install_32 endif endif [Winbatch_install_32] %ScriptPath%\$Inst_Prg$ ExitWindows /Reboot
Start einer Command auf dem Zielsystem (damit der Befehl in einer cmd ausgeführt wird und der Nutzer auch sieht was an seinem PC passiert ;) )
cscript.exe P:\95_wsusupdates\wsus_updates.vbs
Über die script.cmd wird die Datei wsus_updates.vbs aufgerufen
Set updateSession = CreateObject("Microsoft.Update.Session") Set updateSearcher = updateSession.CreateupdateSearcher() WScript.Echo "Searching for updates..." & vbCRLF Set searchResult = _ updateSearcher.Search("IsInstalled=0 and Type='Software'") WScript.Echo "List of applicable items on the machine:" For I = 0 To searchResult.Updates.Count-1 Set update = searchResult.Updates.Item(I) WScript.Echo I + 1 & "> " & update.Title Next If searchResult.Updates.Count = 0 Then WScript.Echo "There are no applicable updates." WScript.Quit Else Set WSHShell = WScript.CreateObject("WScript.Shell") WScript.Echo "STOP SAV..." & vbCRLF WshShell.Run "net stop SAVService", TRUE WScript.Sleep 10000 End If WScript.Echo vbCRLF & "Creating collection of updates to download:" Set updatesToDownload = CreateObject("Microsoft.Update.UpdateColl") For I = 0 to searchResult.Updates.Count-1 Set update = searchResult.Updates.Item(I) WScript.Echo I + 1 & "> adding: " & update.Title updatesToDownload.Add(update) Next WScript.Echo vbCRLF & "Downloading updates..." Set downloader = updateSession.CreateUpdateDownloader() downloader.Updates = updatesToDownload downloader.Download() WScript.Echo vbCRLF & "List of downloaded updates:" For I = 0 To searchResult.Updates.Count-1 Set update = searchResult.Updates.Item(I) If update.IsDownloaded Then WScript.Echo I + 1 & "> " & update.Title End If Next Set updatesToInstall = CreateObject("Microsoft.Update.UpdateColl") WScript.Echo vbCRLF & _ "Creating collection of downloaded updates to install:" For I = 0 To searchResult.Updates.Count-1 set update = searchResult.Updates.Item(I) If update.IsDownloaded = true Then WScript.Echo I + 1 & "> adding: " & update.Title updatesToInstall.Add(update) End If Next 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 If installationResult.RebootRequired = true Then WScript.Echo "" & vbCRLF WScript.Echo "System reboot now" & vbCRLF Set WSHShell = WScript.CreateObject("WScript.Shell") WshShell.Run "wuauclt /reportnow" WScript.Sleep 10000 WshShell.Run "C:\WINDOWS\system32\shutdown.exe -r -t 10" Else WScript.Echo "" & vbCRLF WScript.Echo "No reboot needed" & vbCRLF Set WSHShell = WScript.CreateObject("WScript.Shell") WScript.Echo "START SAV" & vbCRLF WshShell.Run "net start SAVService", TRUE WshShell.Run "wuauclt /reportnow", TRUE End If
Den Code für die wsus_updates.vbs habe ich aus dem Internet zusammengesucht. Bei der Installation wird zusätzlich (zur besseren Performance) der Symantec Antivirus Dienst angehalten. Bei mir funktioniert das so sehr gut.
Verbesserungsvorschläge und Optimierungen sind jederzeit willkommen.
This Script is maintained by: — tobias 2013/03/01 18:06
This is an alternative way to install all Windows & Office Updates on the fly after Windows installation. The script is based on WUInstall Pro (http://wuinstall.com/) - but i think it will work with the free version too (maybe with small changes) It's Important that you have a WSUS Server in your Network because the checkroutine uses an WSUS to check for outstanding updates.
Update: The option /use_wsus is only available in WuInstallPRO!
The option /use_wsus is only needed by users who do not have a ActiveDirectory with an active WSUS Group policy. If you do not have an ActiveDirectory you can set the option via registry.
Ich habe eine weitere Variante entwickelt um Updates automatisiert nach der OS Installation auf den Client zu bringen. Mein Script basiert auf dem Programm WUInstall (http://wuinstall.com/) getestet und entwickelt habe ich das Script mit der Pro Version - ich denke es wird auch mit der Free Version funktionieren.
Das Script startet WUInstall welches ALLE Updates vom WSUS installiert alternativ auch aus dem Internet. Anschließend überprüft das Script ob weitere Updates ausstehen und startet den Rechner bei Bedarf neu um anschließend erneut Updates nach Updates zu suchen.
Das Script ist getestet auf Windows 7 x64 und x86 sollte aber auch auf Windows XP funktionieren wenn dort die Powershell installiert ist!
- Wenn Optionale Updates angeboten werden, werden diese nicht automatisch installiert und das Powershellscript wird nie 0 zurückgeben!
- Das Script hat eine Geringe Priorität, daher wird es nahezu als letztes ausgeführt. Das ist wichtig damit alle Produkte die darüber mit Updates versorgt werden, diese auch enthalten.
[ACTIONS] ; -------- Define Variables ------------------------- DefVar $WinstRegKey$ DefVar $RebootRegVar$ DefStringList $counterString$ DefVar $CounterVar$ DefVar $trim$ DefVar $INST_SystemType$ Defvar $outstanding$ DefVar $ProductId$ DefVar $RebootCounter$ DefVar $NumberOfNeededReboots$ Set $WinstRegKey$ = "HKLM\SOFTWARE\opsi.org\winst" Set $ProductID$ = "Windows Updates" Set $INST_SystemType$ = GetSystemType Set $NumberOfNeededReboots$ = GetProductProperty("NumberOfNeededReboots", "15") ShowBitmap "%ScriptPath%\WU.png" $ProductId$ ; ------------- Create Reboot flag registry key ---------------------------------------------- if (GetRegistryStringValue32("["+$WinstRegKey$+"] "+"RebootFlag") = "") set $RebootCounter$ = "0" else Set $RebootCounter$ = GetRegistryStringValue32("["+$WinstRegKey$+"] "+"RebootFlag") endif ;-------------------------- Patch Routine ---------------------------------------------------- comment $RebootCounter$ comment $NumberOfNeededReboots$ if ($RebootCounter$ INT<= $NumberOfNeededReboots$) if ($INST_SystemType$ = "64 Bit System") DOSBatch_install_updates_x64 else DOSBatch_install_updates_x86 endif ;---------------------------- Check pending updates --------------------------------------- winbatch_psactivate set $counterString$ = getOutStreamFromSection('execWith_powershell "Powershell"') set $CounterVar$ = takeString(0,$CounterString$) set $trim$ = trim($CounterVar$) set $outstanding$ = $trim$ opsiServiceCall_report_pending_updates if $trim$ = "0" comment "Keine Updates Verfuegbar" set $RebootCounter$ = calculate($NumberOfNeededReboots$+"+1") Registry_SaveRebootCounter ExitWindows /Reboot else set $RebootCounter$ = calculate($RebootCounter$+"+1") opsiServiceCall_report_reboot Registry_SaveRebootCounter ExitWindows /ImmediateReboot comment "weitere Updates verfuegbar reboot wurde initialisiert und Zaehler um 1 erhoeht" endif else set $RebootCounter$ = "0" Registry_SaveRebootCounter Comment "Maximale Anzahl durchlaeufe erreicht, RebootCounter (Rebootflag) zurueckgesetzt auf 0" endif ; ----------- Sections ------------------------------------------------------------------------------------- [DOSBatch_install_updates_x64] %scriptpath%/WUInstallX64.exe /install /use_wsus http://xxxx.15 /logfile_append c:/tmp/wuinstall.log [DOSBatch_install_updates_x86] %scriptpath%/WUInstallX86.exe /install /use_wsus http://xxxx.15 /logfile_append c:/tmp/wuinstall.log [winbatch_psactivate] powershell Set-ExecutionPolicy RemoteSigned [execWith_powershell] $Session= New-Object -ComObject Microsoft.Update.Session $Searcher = $Session.CreateUpdateSearcher() $list = $Searcher.Search('IsInstalled = 0 and IsHidden = 0') write-host $list.updates.count [Registry_SaveRebootCounter] openKey [$WinstRegKey$] set "RebootFlag" = "$RebootCounter$" [opsiServiceCall_report_pending_updates] "method": "setProductProperty" "params": [ "windowsupdates", "ausstehend", "$outstanding$", "%hostid%" ] [opsiServiceCall_report_reboot] "method": "setProductProperty" "params": [ "windowsupdates", "rebootcounter", "$RebootCounter$", "%hostid%" ]
[Package] version: 1 depends: incremental: False [Product] type: localboot id: windowsupdates name: Windows Updates description: Installiert Windowsupdates advice: version: 1.5 priority: -89 licenseRequired: False productClasses: setupScript: setup.ins uninstallScript: updateScript: alwaysScript: onceScript: customScript: userLoginScript: [ProductProperty] type: unicode name: ausstehend multivalue: False editable: True description: Noch ausstehende Updates (nicht editieren) values: ["0"] default: ["0"] [ProductProperty] type: unicode name: rebootcounter multivalue: False editable: True description: Anzahl bisheriger Neustarts (nicht editieren) values: ["0"] default: ["0"] [ProductProperty] type: unicode name: numberofneededreboots multivalue: False editable: True description: Startet Rechner bei bedarf auf mehrmals neu values: ["0", "10", "11", "12", "13", "14", "15", "3", "4", "5", "6", "7", "8", "9"] default: ["15"]
— tobias 2013/08/15 21:00
- Report pending Updates to Configed (realised with Produtctproperty)
- Reboot counter (reported to Configed)
- Maximum Reboots (Property) (Prevents continuous loop)