====== wsusclient ======
The following script was developed starting from a VBScript snippet from Microsoft
(source: http://msdn.microsoft.com/en-us/library/aa387102%28VS.85%29.aspx )
and serves to force installing available updates from a WSUS server.
It is similar in intent to [[userspace:windows_updates|WSUS Updates]] and [[userspace:windows_updates_wsus_required|]] but sufficiently different to justify a separate entry.
The script comes in two parts,
* ''setup.ins'' will first install needed (on Win XP) updates for the update service itself and for windows installer. The files ''WindowsXP-KB898461-x86-ENU.exe'', ''WindowsXP-KB942288-v3-x86.exe'', and ''WindowsUpdateAgent30-x86.exe'' from Microsoft are needed for that),
* ''update.ins'' will install the updates.
The WSUS configuration can be controlled via properties //targetgroup// and //wsusurl//.
This script has been tested on Windows XP (32bit) and Windows 7 (64bit). It has grown over time and has probably accumulated some weirdness.
It should probably only be used after thorough inspection and adaptation.
===== setup.ins =====
[Actions]
DefVar $NTVersion$
DefVar $ExitCode$
DefVar $WuAuVer$
DefVar $CurrentWsusUrl$
DefVar $WsusUrl$
DefVar $TargetGroup$
DefVar $NeedReboot$
DefVar $Failed$
DefVar $LogDir$
;------------------------
Set $LogDir$ = "%SystemDrive%\tmp"
;------------------------
set $WsusUrl$ = GetProductProperty("wsusurl","http://wsus/")
set $TargetGroup$ = GetProductProperty("targetgroup","")
;------------------------
set $NeedReboot$ = "False"
set $Failed$ = "False"
ShowBitmap "%scriptpath%\sys_wsus.png" "WSUS-Client"
Set $NTVersion$ = GetNTVersion
if ( $NTVersion$ = "WinXP" )
if (GetRegistryStringValue32("[HKEY_LOCAL_MACHINE\Software\HRZMR] wsusclientreboot") = "")
dosinanicon_wsusclientcleanup_xp
if (GetRegistryStringValue("[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\KB898461] DisplayName") = "")
Message "Install Package Installer for Windows"
winbatchinstall_KB898461
Sub_check_exitcode
endif
if (GetRegistryStringValue("[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\KB942288-v3] DisplayName") = "")
Message "Install Windows Installer 4.5"
winbatchinstall_KB942288-v3
Sub_check_exitcode
endif
set $WuAuVer$ = getValue("file version with dots", getFileInfoMap("%System%\wuauclt.exe"))
if (CompareDotSeparatedNumbers("7.4.7600.226",$WuAuVer$) = "1")
Message "Install Windows Update Agent 3.0"
winbatchinstall_wuau
Sub_check_exitcode
endif
if ($Failed$ = "True")
LogError "Installation einer Komponente fehlgeschlagen."
IsFatalError
else
Registry_MarkReboot
comment "Fortsetzung nach Neustart"
exitWindows /ImmediateReboot
endif
endif
endif
[Registry_MarkReboot]
OpenKey [HKEY_LOCAL_MACHINE\Software\HRZMR]
Set "wsusclientreboot"="setup"
[Registry_UnmarkReboot]
OpenKey [HKEY_LOCAL_MACHINE\Software\HRZMR]
DeleteVar "wsusclientreboot"
[winbatchinstall_KB898461]
%scriptpath%\WindowsXP-KB898461-x86-ENU.exe -n -q -z
[winbatchinstall_KB942288-v3]
%scriptpath%\WindowsXP-KB942288-v3-x86.exe -n -q -z
[winbatchinstall_wuau]
%scriptpath%\WindowsUpdateAgent30-x86.exe /quiet /norestart
[Sub_check_exitcode]
comment "Test for installation success via exit code"
set $ExitCode$ = getLastExitCode
; informations to exit codes see
; http://msdn.microsoft.com/en-us/library/aa372835(VS.85).aspx
; http://msdn.microsoft.com/en-us/library/aa368542.aspx
if ($ExitCode$ = "0")
comment "Looks good: setup program gives exitcode zero"
else
comment "Setup program gives a exitcode unequal zero: " + $ExitCode$
if ($ExitCode$ = "1605")
comment "ERROR_UNKNOWN_PRODUCT 1605 This action is only valid for products that are currently installed."
comment "Uninstall of a not installed product failed - no problem"
else
if ($ExitCode$ = "1641")
comment "looks good: setup program gives exitcode 1641"
comment "ERROR_SUCCESS_REBOOT_INITIATED 1641 The installer has initiated a restart. This message is indicative of a success."
Set $NeedReboot$ = "True"
else
if ($ExitCode$ = "3010")
comment "looks good: setup program gives exitcode 3010"
comment "ERROR_SUCCESS_REBOOT_REQUIRED 3010 A restart is required to complete the install. This message is indicative of a success."
Set $NeedReboot$ = "True"
else
logError "Fatal: Setup program gives an unknown exitcode unequal zero: " + $ExitCode$
Set $Failed$ = "True"
endif
endif
endif
endif
[dosinanicon_wsusclientcleanup_xp]
net stop wuauserv
net stop bits
msiexec /unregserver
regsvr32 /s /u wuapi.dll
regsvr32 /s /u wuaueng1.dll
regsvr32 /s /u wuaueng.dll
regsvr32 /s /u wucltui.dll
regsvr32 /s /u wups2.dll
regsvr32 /s /u wups.dll
regsvr32 /s /u wuweb.dll
rmdir /s /q %windir%\SoftwareDistribution
reg delete HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\WindowsUpdate /f
reg delete HKLM\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate /f
if exist %windir%\WindowsUpdate.log.%date%.bak del %windir%\WindowsUpdate.log.%date%.bak
if exist %windir%\WindowsUpdate.log ren %windir%\WindowsUpdate.log WindowsUpdate.log.%date%.bak
msiexec /regserver
regsvr32 /s wuapi.dll
regsvr32 /s wuaueng1.dll
regsvr32 /s wuaueng.dll
regsvr32 /s wucltui.dll
regsvr32 /s wups2.dll
regsvr32 /s wups.dll
regsvr32 /s wuweb.dll
net start wuauserv
===== update.ins =====
[Actions]
DefVar $NTVersion$
DefVar $ExitCode$
DefVar $WuAuVer$
DefVar $CurrentWsusUrl$
DefVar $WsusUrl$
DefVar $TargetGroup$
DefVar $CurrentTargetGroup$
DefVar $NeedReboot$
DefVar $ResultsFile$
DefVar $FoundCount$
DefVar $DownloadCount$
DefVar $NewDownloadCount$
DefVar $InstallCount$
DefVar $LogDir$
DefStringList $Results$
DefVar $winDomain$
DefVar $SystemType$
;------------------------
Set $LogDir$ = "%SystemDrive%\tmp"
;------------------------
Set $WsusUrl$ = GetProductProperty("wsusurl","http://wsus/")
sub_get_winDomain
Set $TargetGroup$ = GetProductProperty("targetgroup","")
If ($TargetGroup$ = "")
set $TargetGroup$ = $winDomain$
Endif
Set $SystemType$ = GetSystemType
;------------------------
set $NeedReboot$ = "False"
set $InstallCount$ = "0"
;------------------------
ShowBitmap "%scriptpath%\sys_wsus.png" "WSUS-Client"
Set $NTVersion$ = GetNTVersion
Set $CurrentWsusUrl$ = GetRegistryStringValue("[HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate] WUServer")
; Surprisingly GetRegistryStringValue will also read DWORD values from the
; registry and convert them to decimal strings:
If GetRegistryStringValue("[HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate] TargetGroupEnabled") = "1"
Set $CurrentTargetGroup$ = GetRegistryStringValue("[HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate] TargetGroup")
Else
Set $CurrentTargetGroup$ = ""
Endif
if not ( ($CurrentWsusUrl$ = $WsusUrl$) and ($CurrentTargetGroup$ = $TargetGroup$) )
Message "Configure WSUS client"
dosinanicon_stop_wuauserv
registry_wsus_passive
if not ( $TargetGroup$ = "" )
registry_wsus_targetgroup
endif
dosinanicon_start_wuauserv
endif
dosinanicon_check_wuauserv
If FileExists($LogDir$ + "\wuauservnotrunning")
LogError "WUAUServ laeuft nicht!"
isFatalError
Else
Set $ResultsFile$ = $LogDir$ + "\_wsus_results.log"
Message "Kontaktiere WSUS " + $WsusUrl$ + "..."
execwithvbs_count_updates "wscript" PASS //NoLogo //E:VBScript
Set $Results$ = loadTextFile($ResultsFile$)
Set $FoundCount$ = getValue("Found",$Results$)
Set $DownloadCount$ = getValue("Downloaded",$Results$)
Set $NewDownloadCount$ = getValue("DownloadNeeded",$Results$)
If not ($FoundCount$ = "0")
If not ($NewDownloadCount$ = "0")
Message $NewDownloadCount$ + "/" + $FoundCount$ + " Updates müssen heruntergeladen werden..."
execwithvbs_download_updates "wscript" PASS //NoLogo //E:VBScript
Set $Results$ = loadTextFile($ResultsFile$)
Set $FoundCount$ = getValue("Found",$Results$)
Set $DownloadCount$ = getValue("DownloadCount",$Results$)
Set $NewDownloadCount$ = getValue("NewDownloadCount",$Results$)
Endif
Message $DownloadCount$ + "/" + $FoundCount$ + " Updates heruntergeladen, installiere..."
If ( $NTVersion$ = "WinXP" )
dosinanicon_stop_uphclean
Endif
execwithvbs_install_updates "wscript" PASS //NoLogo //E:VBScript
Set $Results$ = loadTextFile($ResultsFile$)
Set $FoundCount$ = getValue("Found",$Results$)
Set $InstallCount$ = getValue("Installed",$Results$)
Set $NeedReboot$ = getValue("NeedReboot",$Results$)
If ( $NTVersion$ = "WinXP" )
dosinanicon_start_uphclean
Endif
Message $InstallCount$ + " von " + $FoundCount$ + " Updates installiert..."
Endif
If ($NeedReboot$ = "NULL")
if not (GetRegistryStringValue32("[HKEY_LOCAL_MACHINE\Software\HRZMR] wsusclientreboot") = "error")
LogError "Update script crashed. Will retry once after reboot..."
Registry_MarkReboot_Error
exitWindows /ImmediateReboot
else
Registry_UnMarkReboot
LogError "Update script crashed AGAIN. Giving up..."
isFatalError
endif
Else
Registry_UnMarkReboot
If ($NeedReboot$ = "True")
comment "Fortsetzung nach Neustart"
Registry_MarkReboot
exitWindows /ImmediateReboot
endif
If not (GetRegistryStringValue("[HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate\AU] AUOptions") = "4")
dosinanicon_stop_wuauserv
registry_wsus_active
dosinanicon_start_wuauserv
Endif
if ($NTVersion$ = "WinXP")
dosinanicon_scrap_uninstdirs_xp
endif
If ($SystemType$="64 Bit System")
execwith_rescan "%systemroot%\cmd64.exe" /c
Else
execwith_rescan "%system%\cmd.exe" /c
Endif
SleepSeconds 5
If Not ($InstallCount$="0")
comment "We did install at least one update in this session, so let's reboot just to be safe."
exitWindows /Reboot
Endif
Endif
Endif
[Registry_MarkReboot]
OpenKey [HKEY_LOCAL_MACHINE\Software\HRZMR]
Set "wsusclientreboot"="update"
[Registry_MarkReboot_Error]
OpenKey [HKEY_LOCAL_MACHINE\Software\HRZMR]
Set "wsusclientreboot"="error"
[Registry_UnmarkReboot]
OpenKey [HKEY_LOCAL_MACHINE\Software\HRZMR]
DeleteVar "wsusclientreboot"
[registry_wsus_passive]
openkey [HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate]
set "WUServer"=REG_SZ:"$WsusUrl$"
set "WUStatusServer"=REG_SZ:"$WsusUrl$"
set "ElevateNonAdmins"=REG_DWORD:1
set "TargetGroup"=REG_SZ:""
set "TargetGroupEnabled"=REG_DWORD:0
openkey [HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate\AU]
set "ElevateNonAdmins"=REG_DWORD:1
set "NoAUShutdownOption"=REG_DWORD:0
set "NoAUAsDefaultShutdownOption"=REG_DWORD:0
set "UseWUServer"=REG_DWORD:1
set "RescheduleWaitTimeEnabled"=REG_DWORD:1
set "RescheduleWaitTime"=REG_DWORD:1
set "NoAutoRebootWithLoggedOnUsers"=REG_DWORD:0
set "DetectionFrequencyEnabled"=REG_DWORD:1
set "DetectionFrequency"=REG_DWORD:6
set "AutoInstallMinorUpdates"=REG_DWORD:1
set "RebootWarningTimeoutEnabled"=REG_DWORD:1
set "RebootWarningTimeout"=REG_DWORD:30
set "RebootRelaunchTimeoutEnabled"=REG_DWORD:1
set "RebootRelaunchTimeout"=REG_DWORD:120
set "NoAutoUpdate"=REG_DWORD:0
set "ScheduledInstallDay"=REG_DWORD:0
set "ScheduledInstallTime"=REG_DWORD:3
set "AUOptions"=REG_DWORD:2
[registry_wsus_targetgroup]
openkey [HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate]
set "TargetGroupEnabled"=REG_DWORD:1
set "TargetGroup"=REG_SZ:"$TargetGroup$"
[registry_wsus_active]
openkey [HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate\AU]
set "AUOptions"=REG_DWORD:4
[dosinanicon_stop_wuauserv]
net stop wuauserv
[dosinanicon_start_wuauserv]
net start wuauserv
[dosinanicon_check_wuauserv]
sc query wuauserv|find "RUNNING"
if errorlevel 1 goto REPAIR
goto DONE
:REPAIR
regsvr32 /s wuapi.dll
regsvr32 /s wuaueng1.dll
regsvr32 /s wuaueng.dll
regsvr32 /s wucltui.dll
regsvr32 /s wups2.dll
regsvr32 /s wups.dll
regsvr32 /s wuweb.dll
net start wuauserv
sc query wuauserv|find "RUNNING"
if errorlevel 1 goto FAIL
:DONE
del $LogDir$\wuauservnotrunning
goto END
:FAIL
copy NUL $LogDir$\wuauservnotrunning
:END
[dosinanicon_stop_uphclean]
net stop uphclean
[dosinanicon_start_uphclean]
net start uphclean
[execwith_rescan]
wuauclt.exe /detectnow
wuauclt.exe /reportnow
[dosinanicon_scrap_uninstdirs_xp]
setlocal
cd /d %windir%
attrib -h $NtUn* /d /s
for /d %%d in ($NtUn*) do rmdir /s /q %%d
endlocal
[execwithvbs_count_updates]
rem This is derived from:
rem http://msdn.microsoft.com/en-us/library/aa387102(VS.85).aspx
rem "Searching, Downloading, and Installing Updates"
On Error Resume Next
dim fso : Set fso = CreateObject("Scripting.FileSystemObject")
dim Results: Set Results = fso.CreateTextFile("$ResultsFile$",True,False)
rem Results will contain return values to be read into a String List
Set wuS = CreateObject("Microsoft.Update.Session")
Set updateSearcher = wuS.CreateupdateSearcher()
Set searchResult = updateSearcher.Search("IsInstalled=0 and Type='Software'")
downloaded=0
downloadneeded=0
found = searchResult.Updates.Count
For I = 0 To found-1
Set update = searchResult.Updates.Item(I)
If update.IsDownloaded = true Then
downloaded = downloaded + 1
Else
downloadneeded = downloadneeded + 1
End If
Next
Results.WriteLine "Found=" & found
Results.WriteLine "Downloaded=" & downloaded
Results.WriteLine "DownloadNeeded=" & downloadneeded
Results.Close
WScript.Quit
[execwithvbs_download_updates]
rem This is derived from:
rem http://msdn.microsoft.com/en-us/library/aa387102(VS.85).aspx
rem "Searching, Downloading, and Installing Updates"
On Error Resume Next
dim fso : Set fso = CreateObject("Scripting.FileSystemObject")
dim Results: Set Results = fso.CreateTextFile("$ResultsFile$",True,False)
rem Results will contain return values to be read into a String List
Set wuS = CreateObject("Microsoft.Update.Session")
Set updateSearcher = wuS.CreateupdateSearcher()
Set searchResult = updateSearcher.Search("IsInstalled=0 and Type='Software'")
found = searchResult.Updates.Count
Set updatesToDownload = CreateObject("Microsoft.Update.UpdateColl")
olddownloads=0
For I = 0 To found-1
Set update = searchResult.Updates.Item(I)
If update.IsDownloaded = true Then
olddownloads = olddownloads + 1
Else
updatesToDownload.Add(update)
End If
Next
Set downloader = wuS.CreateUpdateDownloader()
downloader.Updates = updatesToDownload
downloader.Download()
downloaded = 0
For I = 0 To found-1
set update = searchResult.Updates.Item(I)
If update.IsDownloaded = true Then
downloaded = downloaded + 1
End If
Next
Results.WriteLine "Found=" & found
Results.WriteLine "DownloadCount=" & downloaded
Results.WriteLine "NewDownloadCount=" & ( downloaded - olddownloads )
Results.Close
WScript.Quit
[execwithvbs_install_updates]
rem This is derived from:
rem http://msdn.microsoft.com/en-us/library/aa387102(VS.85).aspx
rem "Searching, Downloading, and Installing Updates"
On Error Resume Next
dim fso : Set fso = CreateObject("Scripting.FileSystemObject")
dim Results: Set Results = fso.CreateTextFile("$ResultsFile$",True,False)
rem Results will contain return values to be read into a String List
Set wuS = CreateObject("Microsoft.Update.Session")
Set updateSearcher = wuS.CreateupdateSearcher()
Set searchResult = updateSearcher.Search("IsInstalled=0 and Type='Software'")
found = searchResult.Updates.Count
Set wuC = CreateObject("Microsoft.Update.UpdateColl")
downloaded=0
For I = 0 To found-1
set update = searchResult.Updates.Item(I)
If update.IsDownloaded = true Then
downloaded=downloaded+1
wuC.Add(update)
End If
Next
Set installer = wuS.CreateUpdateInstaller()
installer.Updates = wuC
Set installationResult = installer.Install()
installed = 0
For I = 0 to wuC.Count - 1
if installationResult.GetUpdateResult(I).ResultCode = 2 Then
installed = installed + 1
end if
Next
Results.WriteLine "Found=" & downloaded
Results.WriteLine "Installed=" & installed
If installationResult.RebootRequired Then
Results.WriteLine "NeedReboot=True"
Else
Results.WriteLine "NeedReboot=False"
End If
rem We need to do this as conversion of bools to text is localized,
rem so we would sometimes get "Wahr" or "Falsch" instead of "True" and "False".
Results.Close
WScript.Quit
[sub_get_winDomain]
markErrorNumber
opsiservicecall_authenticated
if errorsOccuredSinceMark > 0
comment "nicht authentisiert"
set $winDomain$ = ""
else
Set $Results$ = getReturnListFromSection('opsiservicecall_getGeneralConfig_hash')
set $winDomain$ = getValue("clientconfig.windows.domain",$Results$)
endif
[opsiservicecall_authenticated]
"method": "authenticated"
"params": [
]
[opsiservicecall_getGeneralConfig_hash]
"method": "getGeneralConfig_hash"
"params": [
"%HostID%"
]
--- //[[ratzka@hrz.uni-marburg.de|WRatzka]] 2013/02/06 17:42//