@echo off
rem *** Author: T. Wittrock, RZ Uni Kiel ***

verify other 2>nul
setlocal enableextensions
if errorlevel 1 goto NoExtensions

%~d0
cd "%~p0"

set CTUPDATE_VERSION=3.22
set WSUS_LOGFILE=%SystemRoot%\ctupdate.log
echo Starting update (v. %CTUPDATE_VERSION%)
echo %DATE% %TIME% - Info: Starting update (v. %CTUPDATE_VERSION%) on %COMPUTERNAME% (user: %USERNAME%) >> %WSUS_LOGFILE%

:EvalParam
if "%1"=="" goto NoParam
if /i "%1"=="/nobackup" set BACKUP_MODE=/nobackup
if /i "%1"=="/instie7" set INSTALL_IE7=/instie7
if /i "%1"=="/autoreboot" set BOOT_MODE=/autoreboot
if /i "%1"=="/showlog" set SHOW_LOG=/showlog
if /i "%1"=="/all" set LIST_MODE_ID=/all
shift /1
goto EvalParam
:NoParam

if "%TEMP%"=="" goto NoTemp
pushd "%TEMP%"
if errorlevel 1 goto NoTempDir
popd

set CSCRIPT_PATH=%SystemRoot%\system32\cscript.exe
if not exist %CSCRIPT_PATH% goto NoCScript

set REG_PATH=..\bin\reg.exe
if "%BOOT_MODE%"=="/autoreboot" (if not exist %REG_PATH% goto NoReg)
if "%SHOW_LOG%"=="/showlog" (if not exist %REG_PATH% goto NoReg)

rem *** Check number of automatic recalls ***
if "%USERNAME%"=="WSUSUpdateAdmin" (
  if exist "%TEMP%\wsusadmin-recall.2" goto EndlessLoop
  if exist "%TEMP%\wsusadmin-recall.1" (
    ren "%TEMP%\wsusadmin-recall.1" wsusadmin-recall.2
  ) else (
    echo recall > "%TEMP%\wsusadmin-recall.1"
  )
)

rem *** Determine OS properties ***
echo Determining OS properties...
%CSCRIPT_PATH% //Nologo //E:vbs DetermineOSProperties.vbs
if errorlevel 1 goto NoOSVars

rem *** Set environment variables for OS properties ***
if not exist "%TEMP%\SetOSEnvVars.cmd" goto NoOSVars
call "%TEMP%\SetOSEnvVars.cmd"
del "%TEMP%\SetOSEnvVars.cmd"
if "%OS_LANGUAGE%"=="" goto UnsupLang

rem *** Set target environment variables ***
call SetTargetEnvVars.cmd %INSTALL_IE7%
if errorlevel 1 goto EoF
if "%OS_NAME%"=="" goto NoOSName

rem *** Echo OS properties ***
echo Found windows version: %OS_VERSION% (%OS_NAME% %OS_LANGUAGE%)
echo Found service pack version: %SP_VERSION%
rem echo Found windows update agent version: %WUA_VERSION_MAJOR%.%WUA_VERSION_MINOR%.%WUA_VERSION_BUILD%.%WUA_VERSION_REVISION%
rem echo Found windows installer version: %MSI_VERSION_MAJOR%.%MSI_VERSION_MINOR%.%MSI_VERSION_BUILD%.%MSI_VERSION_REVISION%
rem echo Found windows script host version: %SCRIPT_VERSION_MAJOR%.%SCRIPT_VERSION_MINOR%.%SCRIPT_VERSION_BUILD%.%SCRIPT_VERSION_REVISION%
rem echo Found internet explorer version: %IE_VERSION_MAJOR%.%IE_VERSION_MINOR%.%IE_VERSION_BUILD%.%IE_VERSION_REVISION%

echo %DATE% %TIME% - Info: Found windows version %OS_VERSION% (%OS_NAME% %OS_LANGUAGE%) >> %WSUS_LOGFILE%
echo %DATE% %TIME% - Info: Found service pack version %SP_VERSION% >> %WSUS_LOGFILE%
echo %DATE% %TIME% - Info: Found windows update agent version %WUA_VERSION_MAJOR%.%WUA_VERSION_MINOR%.%WUA_VERSION_BUILD%.%WUA_VERSION_REVISION% >> %WSUS_LOGFILE%
echo %DATE% %TIME% - Info: Found windows installer version %MSI_VERSION_MAJOR%.%MSI_VERSION_MINOR%.%MSI_VERSION_BUILD%.%MSI_VERSION_REVISION% >> %WSUS_LOGFILE%
echo %DATE% %TIME% - Info: Found windows script host version %SCRIPT_VERSION_MAJOR%.%SCRIPT_VERSION_MINOR%.%SCRIPT_VERSION_BUILD%.%SCRIPT_VERSION_REVISION% >> %WSUS_LOGFILE%
echo %DATE% %TIME% - Info: Found internet explorer version %IE_VERSION_MAJOR%.%IE_VERSION_MINOR%.%IE_VERSION_BUILD%.%IE_VERSION_REVISION% >> %WSUS_LOGFILE%

rem *** Check proper disc content ***
echo Checking proper disc content...
if not exist ..\%OS_NAME%\nul goto WrongOS
if not exist ..\%OS_NAME%\%OS_LANGUAGE%\nul goto WrongLang

rem *** Check user's privileges ***
echo Checking user's privileges...
if not exist ..\bin\IfAdmin.exe goto NoIfAdmin
..\bin\IfAdmin.exe
if not errorlevel 1 goto NoAdmin

rem *** Check windows service pack version ***
echo Checking windows service pack version...
if /i %SP_VERSION% LSS %SP_VERSION_TARGET% goto ListSPId

rem *** Check windows update agent version ***
echo Checking windows update agent version...
if /i %WUA_VERSION_MAJOR% LSS %WUA_VERSION_TARGET_MAJOR% goto InstallWUA
if /i %WUA_VERSION_MAJOR% GTR %WUA_VERSION_TARGET_MAJOR% goto SkipWUAInst
if /i %WUA_VERSION_MINOR% LSS %WUA_VERSION_TARGET_MINOR% goto InstallWUA
if /i %WUA_VERSION_MINOR% GTR %WUA_VERSION_TARGET_MINOR% goto SkipWUAInst
if /i %WUA_VERSION_BUILD% LSS %WUA_VERSION_TARGET_BUILD% goto InstallWUA
if /i %WUA_VERSION_BUILD% GTR %WUA_VERSION_TARGET_BUILD% goto SkipWUAInst
if /i %WUA_VERSION_REVISION% GEQ %WUA_VERSION_TARGET_REVISION% goto SkipWUAInst
:InstallWUA
set WUA_FILENAME=..\wsus\WindowsUpdateAgent*.exe
dir /B %WUA_FILENAME% > nul 2>&1
if errorlevel 1 goto NoWUAInst
for /F %%i in ('dir /B %WUA_FILENAME%') do (
  echo Installing most recent windows update agent...
  call InstallUpdate.cmd ..\wsus\%%i /noretry /wuforce /quiet /norestart
  if errorlevel 1 goto InstError
  set RECALL=1
)
:SkipWUAInst

rem *** Check windows installer version ***
echo Checking windows installer version...
if /i %MSI_VERSION_MAJOR% LSS %MSI_VERSION_TARGET_MAJOR% goto InstallMSI
if /i %MSI_VERSION_MAJOR% GTR %MSI_VERSION_TARGET_MAJOR% goto SkipMSIInst
if /i %MSI_VERSION_MINOR% LSS %MSI_VERSION_TARGET_MINOR% goto InstallMSI
if /i %MSI_VERSION_MINOR% GTR %MSI_VERSION_TARGET_MINOR% goto SkipMSIInst
if /i %MSI_VERSION_BUILD% LSS %MSI_VERSION_TARGET_BUILD% goto InstallMSI
if /i %MSI_VERSION_BUILD% GTR %MSI_VERSION_TARGET_BUILD% goto SkipMSIInst
if /i %MSI_VERSION_REVISION% GEQ %MSI_VERSION_TARGET_REVISION% goto SkipMSIInst
:InstallMSI
set MSI_FILENAME=..\msi\WindowsInstaller*.exe
dir /B %MSI_FILENAME% > nul 2>&1
if errorlevel 1 goto NoMSIInst
for /F %%i in ('dir /B %MSI_FILENAME%') do (
  echo Installing most recent windows installer...
  call InstallUpdate.cmd ..\msi\%%i /noretry /quiet %BACKUP_MODE% /norestart
  if errorlevel 1 goto InstError
  set RECALL=1
)
:SkipMSIInst

rem *** Check windows script host version ***
if /i "%OS_NAME%" NEQ "w2k" goto SkipScriptInst
echo Checking windows script host version...
if /i %SCRIPT_VERSION_MAJOR% LSS %SCRIPT_VERSION_TARGET_MAJOR% goto InstallScript
if /i %SCRIPT_VERSION_MAJOR% GTR %SCRIPT_VERSION_TARGET_MAJOR% goto SkipScriptInst
if /i %SCRIPT_VERSION_MINOR% LSS %SCRIPT_VERSION_TARGET_MINOR% goto InstallScript
if /i %SCRIPT_VERSION_MINOR% GTR %SCRIPT_VERSION_TARGET_MINOR% goto SkipScriptInst
if /i %SCRIPT_VERSION_BUILD% LSS %SCRIPT_VERSION_TARGET_BUILD% goto InstallScript
if /i %SCRIPT_VERSION_BUILD% GTR %SCRIPT_VERSION_TARGET_BUILD% goto SkipScriptInst
if /i %SCRIPT_VERSION_REVISION% GEQ %SCRIPT_VERSION_TARGET_REVISION% goto SkipScriptInst
:InstallScript
set WSH_FILENAME=..\w2k\%OS_LANGUAGE%\windows2000-kb917344-x86-%OS_LANGUAGE%_*.exe
dir /B %WSH_FILENAME% > nul 2>&1
if errorlevel 1 (
  echo Warning: File %WSH_FILENAME% not found.
  echo %DATE% %TIME% - Warning: File %WSH_FILENAME% not found >> %WSUS_LOGFILE%
) else (
  echo Installing most recent windows script host...
  for /F %%i in ('dir /B %WSH_FILENAME%') do (
    if "%BACKUP_MODE%"=="/nobackup" (
      call InstallUpdate.cmd ..\w2k\%OS_LANGUAGE%\%%i /noretry /exitonerror /q /z /n
    ) else (
      call InstallUpdate.cmd ..\w2k\%OS_LANGUAGE%\%%i /noretry /exitonerror /q /z
    )
    if errorlevel 1 goto InstError
    set RECALL=1
  )
)
:SkipScriptInst

rem *** Check internet explorer version ***
echo Checking internet explorer version...
if /i %IE_VERSION_MAJOR% LSS %IE_VERSION_TARGET_MAJOR% goto InstallIE
if /i %IE_VERSION_MAJOR% GTR %IE_VERSION_TARGET_MAJOR% goto SkipIEInst
if /i %IE_VERSION_MINOR% LSS %IE_VERSION_TARGET_MINOR% goto InstallIE
if /i %IE_VERSION_MINOR% GTR %IE_VERSION_TARGET_MINOR% goto SkipIEInst
if /i %IE_VERSION_BUILD% LSS %IE_VERSION_TARGET_BUILD% goto InstallIE
if /i %IE_VERSION_BUILD% GTR %IE_VERSION_TARGET_BUILD% goto SkipIEInst
if /i %IE_VERSION_REVISION% GEQ %IE_VERSION_TARGET_REVISION% goto SkipIEInst
:InstallIE
goto IE%OS_NAME%

:IEw2k
set IE_FILENAME=..\win\%OS_LANGUAGE%\ie6setup\ie6setup.exe
if not exist %IE_FILENAME% (
  echo Warning: File %IE_FILENAME% not found. 
  echo %DATE% %TIME% - Warning: File %IE_FILENAME% not found >> %WSUS_LOGFILE%
  goto SkipIEInst 
)
echo Installing internet explorer 6...
call InstallUpdate.cmd %IE_FILENAME% /noretry /q:a /r:n
if errorlevel 1 goto InstError
set RECALL=1
goto SkipIEInst 

:IEwxp
set IE_FILENAME=..\%OS_NAME%\%OS_LANGUAGE%\ie7-windowsxp-x86-%OS_LANGUAGE%_*.exe
goto IEwxp2k3

:IEw2k3
set IE_FILENAME=..\%OS_NAME%\%OS_LANGUAGE%\ie7-windowsserver2003-x86-%OS_LANGUAGE%_*.exe
goto IEwxp2k3

:IEwxp2k3
if "%OS_ACTIVATION_REQUIRED%"=="1" (
  echo Warning: Unable to install internet explorer 7 because of missing Windows activation. 
  echo %DATE% %TIME% - Warning: Unable to install internet explorer 7 because of missing Windows activation >> %WSUS_LOGFILE%
  goto SkipIEInst 
)
dir /B %IE_FILENAME% > nul 2>&1
if errorlevel 1 (
  echo Warning: File %IE_FILENAME% not found. 
  echo %DATE% %TIME% - Warning: File %IE_FILENAME% not found >> %WSUS_LOGFILE%
  goto SkipIEInst 
)
for /F %%i in ('dir /B %IE_FILENAME%') do (
  echo Installing internet explorer 7...
  call InstallUpdate.cmd ..\%OS_NAME%\%OS_LANGUAGE%\%%i /noretry /quiet /update-no %BACKUP_MODE% /norestart
  if errorlevel 1 goto InstError
  set RECALL=1
  goto SkipIEInst 
)

:SkipIEInst
if "%RECALL%"=="1" (goto Installed) else (goto ListMissingIds)

:ListSPId
rem *** List service pack id ***
echo Listing service pack id...
if "%SP_TARGET_ID%"=="" goto NoSPTargetId
echo %SP_TARGET_ID% > "%TEMP%\MissingUpdateIds.txt"
set LIST_MODE_EXE=/skipstatics
set INSTALL_SWITCHES=/noretry /exitonerror
set UPDATE_SWITCHES=/u /z /n
set RECALL=1
goto ListInstPacks

:ListMissingIds
if /i "%AU_SERVICE_STATE%" NEQ "Running" goto NoAUService
rem *** List ids of missing updates ***
echo Listing ids of missing updates...
copy ..\wsus\wsusscn2.cab "%TEMP%" > nul
%CSCRIPT_PATH% //Nologo //E:vbs ListMissingUpdateIds.vbs %LIST_MODE_ID%
if errorlevel 1 (
  del "%TEMP%\wsusscn2.cab"
  goto NoMissingIds
) else (
  del "%TEMP%\wsusscn2.cab"
  if "%BACKUP_MODE%"=="/nobackup" (
    set UPDATE_SWITCHES=/q /z /n
  ) else (
    set UPDATE_SWITCHES=/q /z
  )
)

:ListInstPacks
rem *** List update files ***
echo Listing update files...
call ListUpdatesToInstall.cmd %LIST_MODE_EXE%
if errorlevel 1 goto ListError
if not exist "%TEMP%\UpdatesToInstall.txt" goto NoUpdates

rem *** Install updates ***
echo Installing updates...
call InstallListedUpdates.cmd %INSTALL_SWITCHES% %UPDATE_SWITCHES%
if errorlevel 1 goto InstError

:Installed
if "%RECALL%"=="1" (
  if "%BOOT_MODE%"=="/autoreboot" (
    echo Preparing automatic reboot...
    if not "%USERNAME%"=="WSUSUpdateAdmin" call PrepareRecall.cmd %~f0 %BACKUP_MODE% %INSTALL_IE7% %BOOT_MODE% %SHOW_LOG% %LIST_MODE_ID%
    %CSCRIPT_PATH% //Nologo //E:vbs Reboot.vbs
  ) else goto SuggestRecall
) else (
  if "%SHOW_LOG%"=="/showlog" call PrepareShowLogFile.cmd
  if "%BOOT_MODE%"=="/autoreboot" (
    echo Preparing automatic reboot...
    if "%USERNAME%"=="WSUSUpdateAdmin" (
      call CleanupRecall.cmd
      del /Q "%TEMP%\wsusadmin-recall.*"
    )
    %CSCRIPT_PATH% //Nologo //E:vbs Reboot.vbs
  ) else goto InstSuccess
)
goto EoF

:NoExtensions
echo.
echo ERROR: No command extensions available.
echo.
exit /b 1

:NoTemp
echo.
echo ERROR: Environment variable TEMP not set.
echo %DATE% %TIME% - Error: Environment variable TEMP not set >> %WSUS_LOGFILE%
echo.
goto Cleanup

:NoTempDir
echo.
echo ERROR: Directory "%TEMP%" not found.
echo %DATE% %TIME% - Error: Directory "%TEMP%" not found >> %WSUS_LOGFILE%
echo.
goto Cleanup

:NoCScript
echo.
echo ERROR: VBScript interpreter %CSCRIPT_PATH% not found.
echo %DATE% %TIME% - Error: VBScript interpreter %CSCRIPT_PATH% not found >> %WSUS_LOGFILE%
echo.
goto Cleanup

:NoReg
echo.
echo ERROR: Registry tool %REG_PATH% not found.
echo %DATE% %TIME% - Error: Registry tool %REG_PATH% not found >> %WSUS_LOGFILE%
echo.
goto Cleanup

:NoIfAdmin
echo.
echo ERROR: File ..\bin\IfAdmin.exe not found.
echo %DATE% %TIME% - Error: File ..\bin\IfAdmin.exe not found >> %WSUS_LOGFILE%
echo.
goto Cleanup

:NoOSVars
echo.
echo ERROR: Determination of OS properties failed.
echo %DATE% %TIME% - Error: Determination of OS properties failed >> %WSUS_LOGFILE%
echo.
goto Cleanup

:UnsupLang
echo.
echo ERROR: Unsupported operating system language.
echo %DATE% %TIME% - Error: Unsupported operating system language >> %WSUS_LOGFILE%
echo.
goto Cleanup

:NoOSName
echo.
echo ERROR: Environment variable OS_NAME not set.
echo %DATE% %TIME% - Error: Environment variable OS_NAME not set >> %WSUS_LOGFILE%
echo.
goto Cleanup

:WrongOS
echo.
echo ERROR: Directory ..\%OS_NAME% not found. Wrong disc?
echo %DATE% %TIME% - Error: Directory ..\%OS_NAME% not found >> %WSUS_LOGFILE%
echo.
goto Cleanup

:WrongLang
echo.
echo ERROR: Directory ..\%OS_NAME%\%OS_LANGUAGE% not found. Wrong disc?
echo %DATE% %TIME% - Error: Directory ..\%OS_NAME%\%OS_LANGUAGE% not found >> %WSUS_LOGFILE%
echo.
goto Cleanup

:NoAdmin
echo.
echo ERROR: User %USERNAME% does not have administrative privileges.
echo %DATE% %TIME% - Error: User %USERNAME% does not have administrative privileges >> %WSUS_LOGFILE%
echo.
goto EoF

:NoWUAInst
echo.
echo ERROR: File %WUA_FILENAME% not found. 
echo %DATE% %TIME% - Error: File ..\wsus\WindowsUpdateAgent30-x86.exe not found >> %WSUS_LOGFILE%
echo.
goto Cleanup

:NoMSIInst
echo.
echo ERROR: File %MSI_FILENAME% not found. 
echo %DATE% %TIME% - Error: File ..\msi\WindowsInstaller-KB893803-v2-x86-%OS_LANGUAGE%.exe not found >> %WSUS_LOGFILE%
echo.
goto Cleanup

:NoSPTargetId
echo.
echo ERROR: Environment variable SP_TARGET_ID not set.
echo %DATE% %TIME% - Error: Environment variable SP_TARGET_ID not set >> %WSUS_LOGFILE%
echo.
goto Cleanup

:NoAUService
echo.
echo ERROR: Service 'automatic updates' ('wuauserv') is not running!
echo %DATE% %TIME% - Error: Service 'automatic updates' ('wuauserv') is not running >> %WSUS_LOGFILE%
echo.
goto Cleanup

:NoMissingIds
echo.
echo No missing updates found. Nothing to do!
echo %DATE% %TIME% - Info: No missing updates found >> %WSUS_LOGFILE%
echo.
goto Cleanup

:NoUpdates
echo.
echo Warning: None of the missing updates was found.
echo %DATE% %TIME% - Warning: None of the missing updates was found >> %WSUS_LOGFILE%
echo.
goto Cleanup

:ListError
echo.
echo ERROR: Listing of update files failed!
echo %DATE% %TIME% - Error: Listing of update files failed >> %WSUS_LOGFILE%
echo.
goto Cleanup

:InstError
echo.
echo ERROR: Installation failed!
echo %DATE% %TIME% - Error: Installation failed >> %WSUS_LOGFILE%
echo.
goto Cleanup

:EndlessLoop
echo.
echo ERROR: Potentially endless reboot/recall loop detected! Aborting installation.
echo %DATE% %TIME% - Error: Potentially endless reboot/recall loop detected >> %WSUS_LOGFILE%
echo.
goto Cleanup

:SuggestRecall
echo.
echo Installation successful! Please reboot your system now and recall Update afterwards.
echo %DATE% %TIME% - Info: Installation successful >> %WSUS_LOGFILE%
echo.
goto EoF

:InstSuccess
echo.
echo Installation successful! Please reboot your system now.
echo %DATE% %TIME% - Info: Installation successful >> %WSUS_LOGFILE%
echo.
goto EoF

:Cleanup
if "%USERNAME%"=="WSUSUpdateAdmin" (
  if "%SHOW_LOG%"=="/showlog" call PrepareShowLogFile.cmd
  call CleanupRecall.cmd
  del /Q "%TEMP%\wsusadmin-recall.*"
  %CSCRIPT_PATH% //Nologo //E:vbs Reboot.vbs
) else (
  if "%SHOW_LOG%"=="/showlog" start %SystemRoot%\notepad.exe %WSUS_LOGFILE%
)
goto EoF

:EoF
echo %DATE% %TIME% - Info: Ending update >> %WSUS_LOGFILE%
endlocal
cd ..
