This shows you the differences between two versions of the page.
userspace:windows_updates [2013/08/15 19:17] tobias [Windows Updates (Alternative)] |
userspace:windows_updates [2021/08/23 08:37] |
||
---|---|---|---|
Line 1: | Line 1: | ||
- | ====== WSUS Updates ====== | ||
- | |||
- | 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. | ||
- | |||
- | |||
- | * Tested with opsi 4.0.2 | ||
- | * Tested with Winst Version 4.11.2.5 | ||
- | * Tested with Windows XP SP3 | ||
- | |||
- | By --- // | ||
- | |||
- | ==== always.ins ==== | ||
- | |||
- | <code winst always.ins> | ||
- | [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 >= " | ||
- | |||
- | 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(" | ||
- | Set $LogDir$ = " | ||
- | |||
- | ; ---------------------------------------------------------------- | ||
- | ; - Please edit the following values | ||
- | ; ---------------------------------------------------------------- | ||
- | ; | ||
- | ; therefore please: only lower letters, no umlauts, | ||
- | ; no white space use ' | ||
- | Set $ProductId$ | ||
- | Set $Version$ | ||
- | Set $MinimumSpace$ | ||
- | Set $LicenseRequired$ = " | ||
- | Set $LicensePool$ | ||
- | Set $Inst_Prg$ | ||
- | Set $Uninst_Prg$ | ||
- | Set $Inst_Cmd32$ | ||
- | |||
- | ; ---------------------------------------------------------------- | ||
- | |||
- | if not(HasMinimumSpace (" | ||
- | LogError "Not enough space on %SystemDrive%, | ||
- | isFatalError | ||
- | ; Stop process and set installation status to failed | ||
- | else | ||
- | comment "Show product picture" | ||
- | ShowBitmap " | ||
- | |||
- | if $LicenseRequired$ = " | ||
- | comment " | ||
- | Sub_get_licensekey | ||
- | endif | ||
- | |||
- | comment " | ||
- | |||
- | if (($INST_SystemType$ = "x86 System" | ||
- | Message " | ||
- | 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 | ||
- | |||
- | |||
- | ==== script.cmd ==== | ||
- | <code - script.cmd> | ||
- | cscript.exe P: | ||
- | </ | ||
- | Über die script.cmd wird die Datei wsus_updates.vbs aufgerufen | ||
- | |||
- | |||
- | ==== wsus_updates.vbs ==== | ||
- | <code vb wsus_updates.vbs> | ||
- | Set updateSession = CreateObject(" | ||
- | Set updateSearcher = updateSession.CreateupdateSearcher() | ||
- | |||
- | WScript.Echo " | ||
- | |||
- | Set searchResult = _ | ||
- | updateSearcher.Search(" | ||
- | |||
- | |||
- | 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.Echo "STOP SAV..." | ||
- | WshShell.Run "net stop SAVService", | ||
- | WScript.Sleep 10000 | ||
- | |||
- | End If | ||
- | |||
- | |||
- | WScript.Echo vbCRLF & " | ||
- | |||
- | Set updatesToDownload = CreateObject(" | ||
- | |||
- | 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 & " | ||
- | |||
- | Set downloader = updateSession.CreateUpdateDownloader() | ||
- | downloader.Updates = updatesToDownload | ||
- | downloader.Download() | ||
- | |||
- | WScript.Echo | ||
- | |||
- | For I = 0 To searchResult.Updates.Count-1 | ||
- | Set update = searchResult.Updates.Item(I) | ||
- | If update.IsDownloaded Then | ||
- | | ||
- | End If | ||
- | Next | ||
- | |||
- | Set updatesToInstall = CreateObject(" | ||
- | |||
- | WScript.Echo | ||
- | " | ||
- | |||
- | For I = 0 To searchResult.Updates.Count-1 | ||
- | set update = searchResult.Updates.Item(I) | ||
- | If update.IsDownloaded = true Then | ||
- | | ||
- | | ||
- | End If | ||
- | Next | ||
- | |||
- | WScript.Echo " | ||
- | Set installer = updateSession.CreateUpdateInstaller() | ||
- | installer.Updates = updatesToInstall | ||
- | Set installationResult = installer.Install() | ||
- | |||
- | ' | ||
- | WScript.Echo " | ||
- | installationResult.ResultCode | ||
- | WScript.Echo " | ||
- | installationResult.RebootRequired & vbCRLF | ||
- | WScript.Echo " | ||
- | "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 "" | ||
- | WScript.Echo " | ||
- | Set WSHShell = WScript.CreateObject(" | ||
- | WshShell.Run " | ||
- | WScript.Sleep 10000 | ||
- | WshShell.Run " | ||
- | Else | ||
- | WScript.Echo "" | ||
- | WScript.Echo "No reboot needed" | ||
- | Set WSHShell = WScript.CreateObject(" | ||
- | WScript.Echo "START SAV" & vbCRLF | ||
- | WshShell.Run "net start SAVService", | ||
- | WshShell.Run " | ||
- | 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. | ||
- | |||
- | |||
- | ====== Windows Updates (Alternative) ====== | ||
- | This Script is maintained by: --- // | ||
- | |||
- | 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:// | ||
- | 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:// | ||
- | |||
- | 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! | ||
- | |||
- | ====== Folgendes muss beachtet werden: ====== | ||
- | - 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. | ||
- | |||
- | ==== Setup.ins ==== | ||
- | <code winst> | ||
- | [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$ = " | ||
- | Set $ProductID$ = " | ||
- | Set $INST_SystemType$ = GetSystemType | ||
- | Set $NumberOfNeededReboots$ = GetProductProperty(" | ||
- | |||
- | ShowBitmap " | ||
- | |||
- | |||
- | ; ------------- Create Reboot flag registry key ---------------------------------------------- | ||
- | |||
- | if (GetRegistryStringValue32(" | ||
- | set $RebootCounter$ = " | ||
- | else | ||
- | Set $RebootCounter$ = GetRegistryStringValue32(" | ||
- | endif | ||
- | |||
- | ; | ||
- | |||
- | comment $RebootCounter$ | ||
- | comment $NumberOfNeededReboots$ | ||
- | if ($RebootCounter$ INT<= $NumberOfNeededReboots$) | ||
- | |||
- | if ($INST_SystemType$ = "64 Bit System" | ||
- | DOSBatch_install_updates_x64 | ||
- | else | ||
- | DOSBatch_install_updates_x86 | ||
- | endif | ||
- | |||
- | ; | ||
- | winbatch_psactivate | ||
- | set $counterString$ = getOutStreamFromSection(' | ||
- | set $CounterVar$ = takeString(0, | ||
- | set $trim$ = trim($CounterVar$) | ||
- | set $outstanding$ = $trim$ | ||
- | opsiServiceCall_report_pending_updates | ||
- | |||
- | if $trim$ = " | ||
- | comment "Keine Updates Verfuegbar" | ||
- | set $RebootCounter$ = calculate($NumberOfNeededReboots$+" | ||
- | Registry_SaveRebootCounter | ||
- | ExitWindows /Reboot | ||
- | else | ||
- | set $RebootCounter$ = calculate($RebootCounter$+" | ||
- | opsiServiceCall_report_reboot | ||
- | Registry_SaveRebootCounter | ||
- | ExitWindows / | ||
- | comment " | ||
- | endif | ||
- | |||
- | else | ||
- | set $RebootCounter$ = " | ||
- | Registry_SaveRebootCounter | ||
- | Comment " | ||
- | endif | ||
- | |||
- | |||
- | |||
- | |||
- | ; ----------- Sections ------------------------------------------------------------------------------------- | ||
- | |||
- | [DOSBatch_install_updates_x64] | ||
- | %scriptpath%/ | ||
- | |||
- | [DOSBatch_install_updates_x86] | ||
- | %scriptpath%/ | ||
- | |||
- | [winbatch_psactivate] | ||
- | powershell Set-ExecutionPolicy RemoteSigned | ||
- | |||
- | [execWith_powershell] | ||
- | $Session= New-Object -ComObject Microsoft.Update.Session | ||
- | $Searcher = $Session.CreateUpdateSearcher() | ||
- | $list = $Searcher.Search(' | ||
- | write-host $list.updates.count | ||
- | |||
- | [Registry_SaveRebootCounter] | ||
- | openKey [$WinstRegKey$] | ||
- | set " | ||
- | |||
- | [opsiServiceCall_report_pending_updates] | ||
- | " | ||
- | " | ||
- | " | ||
- | " | ||
- | " | ||
- | " | ||
- | ] | ||
- | |||
- | [opsiServiceCall_report_reboot] | ||
- | " | ||
- | " | ||
- | " | ||
- | " | ||
- | " | ||
- | " | ||
- | ] | ||
- | </ | ||
- | ===control=== | ||
- | <code winst> | ||
- | [Package] | ||
- | version: 1 | ||
- | depends: | ||
- | incremental: | ||
- | |||
- | [Product] | ||
- | type: localboot | ||
- | id: windowsupdates | ||
- | name: Windows Updates | ||
- | description: | ||
- | advice: | ||
- | version: 1.5 | ||
- | priority: -89 | ||
- | licenseRequired: | ||
- | productClasses: | ||
- | setupScript: | ||
- | uninstallScript: | ||
- | updateScript: | ||
- | alwaysScript: | ||
- | onceScript: | ||
- | customScript: | ||
- | userLoginScript: | ||
- | |||
- | [ProductProperty] | ||
- | type: unicode | ||
- | name: ausstehend | ||
- | multivalue: False | ||
- | editable: True | ||
- | description: | ||
- | values: [" | ||
- | default: [" | ||
- | |||
- | [ProductProperty] | ||
- | type: unicode | ||
- | name: rebootcounter | ||
- | multivalue: False | ||
- | editable: True | ||
- | description: | ||
- | values: [" | ||
- | default: [" | ||
- | |||
- | [ProductProperty] | ||
- | type: unicode | ||
- | name: numberofneededreboots | ||
- | multivalue: False | ||
- | editable: True | ||
- | description: | ||
- | values: [" | ||
- | default: [" | ||
- | |||
- | |||
- | </ | ||
- | |||
- | ==== Neuerungen / News: ==== | ||
- | --- // | ||
- | |||
- | - Report pending Updates to Configed (realised with Produtctproperty) | ||
- | |||
- | - Reboot counter (reported to Configed) | ||
- | |||
- | - Maximum Reboots (Property) (Prevents continuous loop) |