Table of Contents

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.

By — Scorcher 2012/10/04 14:05

always.ins

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 >= "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 ;) )

script.cmd

script.cmd
cscript.exe P:\95_wsusupdates\wsus_updates.vbs

Über die script.cmd wird die Datei wsus_updates.vbs aufgerufen

wsus_updates.vbs

wsus_updates.vbs
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.

Windows Updates (Alternative)

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!

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

[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%"
]

control

[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"]

Neuerungen / News:

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)