Upgrade von Java 7 auf Java 8 – scriptbasiertes Deployment per exe/MSI

java7-java8u25-upgrade-silent-deployment-msiJava 8 ist mittlerweile bei Update 25 angekommen und ein Upgrade von 7u67 auf 8u25 ist sicher eine gute Idee. Also wollte ich mein bestehendes Verteilungsscript für Java im Unternehmen auf die neue Version umstellen. Das war jedoch nicht so einfach und die Verteilung musste umgebaut werden. Demnach hier das Update der Verteilung.

exe Installer

Die .exe Installer, die auf der Java Homepage zur Verfügung stehen, funktionieren gut für die Verteilung:

start /w %wd%\%version%-64.exe /s WEB_JAVA=1 REBOOT=REALLYSUPPRESS /norestart REBOOT=SUPPRESS

MSI Installer

Sollte eine Verteilung über MSI gewünscht werden, geht das natürlich auch. Dazu einfach den .exe Installer per Doppelklick starten und die MSI aus dem Ordner AppData\LocalLow\Sun\Java\[Version] ziehen.
java-8-update-cmd-ordner-msi

Das MSI Paket muss jedoch erst angepasst werden, es werden sonst verschiedene 16XX msiexec Fehlercodes zurückgeliefert.
Hier sind zwei Seiten, mit denen ich gearbeitet habe: diese Seite und diese Seite.
Da sollten keine Fragen offen bleiben.

Den fertigen Installer kann man jetzt mit folgender Zeile verscripten:

msiexec /i %wd%\%version%-32.msi /qn INSTALL_SILENT=1 WEB_ANALYTICS=0 EULA=0 REBOOT=0

Die aktuellen Parameter für die 8er Version findet ihr hier.

Alte Versionen aufräumen

Neu in meinem Script ist die Deinstallation alter Versionen. Dies ist mit 3 Methoden machbar: über WMIC (Windows Management Instrumentation Commandline), einen generellen

msiexec /x{GUID}

Befehl oder mit der Installations-MSI.

WMIC:

Über den WMIC-Befehl

wmic product where "[filter product]" call uninstall" können Programme gezielt deinstalliert werden. Folgender Code deinstalliert Java-Produkte:
[crayon-5851b00cbfa96616214862 lang="shell" ]
wmic product where "name like 'Java %%'" call uninstall /nointeractive
wmic product where "name like 'Java%%'" call uninstall /nointeractive
wmic product where "name like 'Java(tm) %%'" call uninstall /nointeractive
wmic product where "name like 'J2SE Runtime Environment%%'" call uninstall /nointeractive

Mittlerweile setze ich ausschließlich auf die WMIC Variante, da diese zuverlässig und einfacher zu warten ist als die anderen Methoden.

GUID:

msiexec /x{26A24AE4-039D-4CA4-87B4-2F83217055FF} /qn /norestart

Wobei die GUID dieses Format hat:
[/crayon]

{26A24AE4-039D-4CA4-87B4-2F8YY1XXXXFF}

wobei YY die Prozessorbits sind (32/64) und XXXX die Versionsnummer: 7065 für 7u65 oder 8011 für 8u11.

Die GUIDs aller 7er und 8er Versionen, inklusive Batchbefehle, findet ihr auf dieser IT-Ninja Seite (ganz unten).
Hier wäre die aufgeräumte Variante:

Code anzeigenDen Code könnt ihr bequem mit den Links/Rechts Pfeiltasten horizontal bewegen.

REM 7er Versionen
msiexec.exe /qn /norestart /X{26A24AE4-039D-4CA4-87B4-2F83217067FF}
msiexec.exe /qn /norestart /X{26A24AE4-039D-4CA4-87B4-2F86417067FF}
msiexec.exe /qn /norestart /X{26A24AE4-039D-4CA4-87B4-2F83217065FF}
msiexec.exe /qn /norestart /X{26A24AE4-039D-4CA4-87B4-2F86417065FF}
msiexec.exe /qn /norestart /X{26A24AE4-039D-4CA4-87B4-2F83217060FF}
msiexec.exe /qn /norestart /X{26A24AE4-039D-4CA4-87B4-2F86417060FF}
msiexec.exe /qn /norestart /X{26A24AE4-039D-4CA4-87B4-2F83217055FF}
msiexec.exe /qn /norestart /X{26A24AE4-039D-4CA4-87B4-2F86417055FF}
msiexec.exe /qn /norestart /X{26A24AE4-039D-4CA4-87B4-2F83217051FF}
msiexec.exe /qn /norestart /X{26A24AE4-039D-4CA4-87B4-2F86417051FF}
msiexec.exe /qn /norestart /X{26A24AE4-039D-4CA4-87B4-2F83217045FF}
msiexec.exe /qn /norestart /X{26A24AE4-039D-4CA4-87B4-2F86417045FF}
msiexec.exe /qn /norestart /X{26A24AE4-039D-4CA4-87B4-2F83217040FF}
msiexec.exe /qn /norestart /X{26A24AE4-039D-4CA4-87B4-2F86417040FF}
msiexec.exe /qn /norestart /X{26A24AE4-039D-4CA4-87B4-2F83217025FF}
msiexec.exe /qn /norestart /X{26A24AE4-039D-4CA4-87B4-2F86417025FF}
msiexec.exe /qn /norestart /X{26A24AE4-039D-4CA4-87B4-2F83217021FF}
msiexec.exe /qn /norestart /X{26A24AE4-039D-4CA4-87B4-2F86417021FF}
msiexec.exe /qn /norestart /X{26A24AE4-039D-4CA4-87B4-2F83217017FF}
msiexec.exe /qn /norestart /X{26A24AE4-039D-4CA4-87B4-2F86417017FF}
msiexec.exe /qn /norestart /X{26A24AE4-039D-4CA4-87B4-2F83217015FF}
msiexec.exe /qn /norestart /X{26A24AE4-039D-4CA4-87B4-2F86417015FF}
msiexec.exe /qn /norestart /X{26A24AE4-039D-4CA4-87B4-2F83217013FF}
msiexec.exe /qn /norestart /X{26A24AE4-039D-4CA4-87B4-2F86417013FF}
msiexec.exe /qn /norestart /X{26A24AE4-039D-4CA4-87B4-2F83217011FF}
msiexec.exe /qn /norestart /X{26A24AE4-039D-4CA4-87B4-2F86417011FF}
msiexec.exe /qn /norestart /X{26A24AE4-039D-4CA4-87B4-2F83217010FF}
msiexec.exe /qn /norestart /X{26A24AE4-039D-4CA4-87B4-2F86417010FF}
msiexec.exe /qn /norestart /X{26A24AE4-039D-4CA4-87B4-2F83217009FF}
msiexec.exe /qn /norestart /X{26A24AE4-039D-4CA4-87B4-2F86417009FF}
msiexec.exe /qn /norestart /X{26A24AE4-039D-4CA4-87B4-2F83217007FF}
msiexec.exe /qn /norestart /X{26A24AE4-039D-4CA4-87B4-2F86417007FF}
msiexec.exe /qn /norestart /X{26A24AE4-039D-4CA4-87B4-2F86417006FF}
msiexec.exe /qn /norestart /X{26A24AE4-039D-4CA4-87B4-2F83217006FF}
msiexec.exe /qn /norestart /X{26A24AE4-039D-4CA4-87B4-2F86417005FF}
msiexec.exe /qn /norestart /X{26A24AE4-039D-4CA4-87B4-2F83217005FF}
msiexec.exe /qn /norestart /X{26A24AE4-039D-4CA4-87B4-2F86417004FF}
msiexec.exe /qn /norestart /X{26A24AE4-039D-4CA4-87B4-2F83217004FF}
msiexec.exe /qn /norestart /X{26A24AE4-039D-4CA4-87B4-2F86417003FF}
msiexec.exe /qn /norestart /X{26A24AE4-039D-4CA4-87B4-2F83217003FF}
msiexec.exe /qn /norestart /X{26A24AE4-039D-4CA4-87B4-2F86417002FF}
msiexec.exe /qn /norestart /X{26A24AE4-039D-4CA4-87B4-2F83217002FF}
msiexec.exe /qn /norestart /X{26A24AE4-039D-4CA4-87B4-2F86417001FF}
msiexec.exe /qn /norestart /X{26A24AE4-039D-4CA4-87B4-2F83217001FF}
msiexec.exe /qn /norestart /X{26A24AE4-039D-4CA4-87B4-2F86417000FF}
msiexec.exe /qn /norestart /X{26A24AE4-039D-4CA4-87B4-2F83217000FF}

REM 8er Versionen (Update: 17.03.2016, Uninstall bis Update 71, aktuell ist 73)
msiexec.exe /qn /norestart /X{26A24AE4-039D-4CA4-87B4-2F83218071F0}
msiexec.exe /qn /norestart /X{26A24AE4-039D-4CA4-87B4-2F86418071FF}
msiexec.exe /qn /norestart /X{26A24AE4-039D-4CA4-87B4-2F83218066F0}
msiexec.exe /qn /norestart /X{26A24AE4-039D-4CA4-87B4-2F86418066FF}
msiexec.exe /qn /norestart /X{26A24AE4-039D-4CA4-87B4-2F83218065F0}
msiexec.exe /qn /norestart /X{26A24AE4-039D-4CA4-87B4-2F86418065FF}
msiexec.exe /qn /norestart /X{26A24AE4-039D-4CA4-87B4-2F83218060F0}
msiexec.exe /qn /norestart /X{26A24AE4-039D-4CA4-87B4-2F86418060FF}
msiexec.exe /qn /norestart /X{26A24AE4-039D-4CA4-87B4-2F83218051F0}
msiexec.exe /qn /norestart /X{26A24AE4-039D-4CA4-87B4-2F86418051FF}
msiexec.exe /qn /norestart /X{26A24AE4-039D-4CA4-87B4-2F83218045F0}
msiexec.exe /qn /norestart /X{26A24AE4-039D-4CA4-87B4-2F86418045FF}
msiexec.exe /qn /norestart /X{26A24AE4-039D-4CA4-87B4-2F83218040F0}
msiexec.exe /qn /norestart /X{26A24AE4-039D-4CA4-87B4-2F86418040FF}
msiexec.exe /qn /norestart /X{26A24AE4-039D-4CA4-87B4-2F83218031F0}
msiexec.exe /qn /norestart /X{26A24AE4-039D-4CA4-87B4-2F86418031FF}
msiexec.exe /qn /norestart /X{26A24AE4-039D-4CA4-87B4-2F83218020F0}
msiexec.exe /qn /norestart /X{26A24AE4-039D-4CA4-87B4-2F86418020FF}
msiexec.exe /qn /norestart /X{26A24AE4-039D-4CA4-87B4-2F83218011FF}
msiexec.exe /qn /norestart /X{26A24AE4-039D-4CA4-87B4-2F86418011FF}
msiexec.exe /qn /norestart /X{26A24AE4-039D-4CA4-87B4-2F83218005FF}
msiexec.exe /qn /norestart /X{26A24AE4-039D-4CA4-87B4-2F86418005FF}
msiexec.exe /qn /norestart /X{26A24AE4-039D-4CA4-87B4-2F83218000FF}
msiexec.exe /qn /norestart /X{26A24AE4-039D-4CA4-87B4-2F86418000FF}
REM ... usw

MSI:

Die MSIs erhaltet ihr aus dem AppData\LocalLow\Sun\Java\[Version] Ordner.
java-8-update-cmd-ordner
Damit dann:

msiexec /x "%wd%\uninstall\jre1.7.0_67\jre1.7.0_67.msi" /qn /norestart

Alternative Deinstallationen / Uninstaller

Man kann aus der Registry auf jeden Fall die aktuellste Version auslesen, HKEY_LOCAL_MACHINE\SOFTWARE\JavaSoft\Java Runtime Environment.
Problem: hier steht nur die aktuellste Version drin. Ich habe beispielsweise 7u71 und 8u25 installiert, da drin ist nur die 8er gelistet. Ist also schonmal riskant damit zu arbeiten.
Alternativ könnte man im Windows Uninstall Key (HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall) nach Java Versionsnummern suchen, hier wird es erklärt. Aber auch hier müsste man alle Versionsnummern durchprobieren und auf Funde reagieren.
Es gibt bereits ein Script, das mit dieser Uninstall Key Methode sucht und deinstalliert. Ist zwar vbs, aber egal. Hier auf IT-Ninja gleich das erste.
Außerdem gibt es auch weitere Java Uninstaller/Cleanup Tools wie z.B. JavaRA (mehr dazu).
Die Möglichkeiten sind also vielseitig.

Noch ein paar grundlegende Hinweise zur Installation und Deinstallation von Java per MSI auf dieser aktuellen Hilfeseite oder aus der (veralteten) Java Hilfe.

Deployment Script

Die neue Variable

cleanup

ermöglicht das Überspringen der Deinstallation der alten Java-Versionen.

cleanup=1

räumt dagegen alle Versionen (auch die aktuell installierte) einmal auf und installiert frisch. Das Cleanup ist standardmäßig deaktiviert.
Update: 16.08.2016: Version 8u101 getestet und läuft.
Info: Das im Skript verwendete Programm VersionCompare ist eine Eigenprogrammierung und hier als Download verfügbar.

Code anzeigenDen Code könnt ihr bequem mit den Links/Rechts Pfeiltasten horizontal bewegen.

@echo on && color 9f && setlocal
set wd=\\lea\Deployment\Software\Java
set tools=\\lea\Deployment\Sonstiges\tools
set cleanup=0
set versionEL=9
set javaEL32=9
set javaEL64=9
set javaregEL32=9
set javaregEL64=9
set retry=0
set instversion=0
set uninst=x
set pa=%processor_architecture%
REM:: ### HIER VERSION NACH UPDATE ANPASSEN ###
set main=8
set update=101
REM:: ############
set version=%main%u%update%
set alllog=%wd%\java-all.log

REM:: Clientfilter: nur die Computer aus der allowedPCs.txt dürfen installieren
REM::for /f %%f in (%wd%\allowedPCs.txt) do if "%computername%"=="%%f" goto check
REM::goto end

REM:: Clientfilter: die Computer aus der deniedPCs.txt dürfen nicht installieren
for /f %%f in (%wd%\deniedPCs.txt) do if "%computername%"=="%%f" goto end

:check
REM:: alte Kontrollen: Registry, Programmordner
REM:: 1) for /f "tokens=1,2,3 delims= " %%a in ('reg query "HKEY_LOCAL_MACHINE\SOFTWARE\JavaSoft\Java Runtime Environment" /v "Java7FamilyVersion"^|findstr "Java7FamilyVersion"') do set instversion=%%c
REM::    if not "%instversion%"=="1.%main%.0_%update%" goto cleanup
REM:: 2) if not exist "%programfiles%\Java\jre1.%main%.0_%update%" goto install
REM:: Aktuelle Kontrolle: Version aus java -version entnehmen und mit VersionCompare vergleichen
for /f "tokens=3" %%g in ('java -version 2^>^&1 ^| findstr /i "version"') do set instversion=%%g
if "%instversion%" == "0" goto check2
if "%instversion%" == "" goto check2
set instversion=%instversion:~1,-1%
for /f "delims=._ tokens=1-4" %%v in ("%instversion%") do (
	set instmain=%%w
	set instupdate=%%y
)
goto compare

:check2
REM:: workaround if java -version check doesn't work
echo %date% %time:~0,8% - %computername% kann die Version nicht durch java -version bestimmen >> %alllog% 
for /f "tokens=1-3" %%i in ('%tools%\sigcheck %ProgramData%\Oracle\Java\javapath\java.exe') do ( if "%%i %%j"=="File version:" set instversion=%%k )
if "%instversion%" == "0" set cleanup=1 & goto cleanup
if "%instversion%" == "" set cleanup=1 & goto cleanup
set instversion=%instversion: =%
set instversion=%instversion:~0,6%
for /f "delims=. tokens=1-4" %%v in ("%instversion%") do (
	set instmain=%%v
	set instupdate=%%x
)
goto compare

:compare
echo %date% %time:~0,8% - %computername% hat %instmain%.%instupdate% (%instversion%) installiert >> %alllog% 
REM:: compare installed and desired versions now
%tools%\VersionCompare.exe "%instmain%.%instupdate%" "%main%.%update%"
set versionEL=%errorlevel%
if "%versionEL%"=="-1" goto cleanup
if "%versionEL%"=="0" echo %date% %time:~0,8% - %computername% hat bereits %instversion% installiert >> %alllog% & goto end
if "%versionEL%"=="1" echo %date% %time:~0,8% - %computername% hat bereits %instversion% (neuer) installiert >> %alllog% & goto end
goto end

:cleanup
if "%cleanup%"=="0" goto install
REM:: Deinstalliere 8er Versionen
taskkill /F /IM iexplorer.exe
taskkill /F /IM iexplore.exe
taskkill /F /IM firefox.exe
taskkill /F /IM chrome.exe
taskkill /F /IM jusched.exe
taskkill /F /IM jp2launcher.exe
taskkill /F /IM java.exe
taskkill /F /IM javaw.exe
taskkill /F /IM jqs.exe
wmic product where "name like 'Java %%'" call uninstall /nointeractive
wmic product where "name like 'Java%%'" call uninstall /nointeractive
wmic product where "name like 'Java(tm) %%'" call uninstall /nointeractive
wmic product where "name like 'J2SE Runtime Environment%%'" call uninstall /nointeractive
goto install

:install
if "%processor_architecture%"=="AMD64" goto inst64
REM:: .exe format: [version]u[update]-32/-64.exe, Beispiel: 7u45-32.exe, 7u45-64.exe
start /w %wd%\%version%-32.exe /s WEB_JAVA=1 SPONSORS=0 EULA=1 AUTO_UPDATE=0 INSTALL_SILENT=1 WEB_ANALYTICS=0
REM:: MSI INSTALLER CMD LINE: msiexec /i %wd%\%version%-32.msi /qn INSTALL_SILENT=1 WEB_ANALYTICS=0 EULA=0 REBOOT=0 SPONSORS=0
set javaEL32=%errorlevel%

:inst64
start /w %wd%\%version%-64.exe /s WEB_JAVA=1 SPONSORS=0 EULA=1 AUTO_UPDATE=0 INSTALL_SILENT=1 WEB_ANALYTICS=0
REM:: MSI INSTALLER CMD LINE: msiexec /i %wd%\%version%-64.msi /qn INSTALL_SILENT=1 WEB_ANALYTICS=0 EULA=0 REBOOT=0 SPONSORS=0
set javaEL64=%errorlevel%

REM:: 10 Sekunden Pause nach der Installation
ping localhost -n 10 >> nul

:verfication
REM:: existieren die Java Reg-Keys nach der Installation?
REM:: reg query "HKEY_LOCAL_MACHINE\SOFTWARE\JavaSoft\Java Runtime Environment" /f "1.%main%.0_%update%" /k
REM:: set javaregEL32=%errorlevel%
REM:: reg query "HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\JavaSoft\Java Runtime Environment" /f "1.%main%.0_%update%" /k
REM:: set javaregEL64=%errorlevel%

echo %date% %time:~0,8% - %computername%: %version%, install-errorlevel: 32: %javaEL32%, 64: %javaEL64% >> %alllog%

REM:: Error-Handling, Reaktion auf die 3 häufigsten msiexec Fehlercodes
if %javaEL32%==1618 goto retry REM:: msiexec process in use, installation already in progress
if %javaEL32%==1602 goto retry REM:: user canceled installation
if %javaEL32%==1603 goto retry REM:: fatal error, some use it for "already installed" (eg. java)
if %javaEL64%==1618 goto retry REM:: msiexec process in use, installation already in progress
if %javaEL64%==1602 goto retry REM:: user canceled installation
if %javaEL64%==1603 goto retry REM:: fatal error, some use it for "already installed" (eg. java)
goto end

:retry
if %retry%==1 goto retryfailed
echo %date% %time:~0,8% - %computername% hat nicht Errorlevel 00 erreicht, retry in 150Sek... >> %alllog%
set retry=1
REM:: 5 Minuten warten
ping localhost -n 150 > nul
goto install

:retryfailed
echo _!_ %date% %time:~0,8% - %computername% hat die Installation abgebrochen, RETRY FAILED! >> %alllog%
goto end

:end
endlocal
exit

Das funktioniert immernoch problemlos:
java7-java8u73-upgrade-silent-deployment-msi-log
(Errorcode 9 bei 32bit heißt, dass auf dem System keine 32bit Installation gefunden und diese übersprungen wurde)

11 Kommentare

  1. Die GUID der alten Versionen lässt sich doch bestimmt aus der Registry auslesen. Wäre das nicht hübscher, als stupide zu versuchen, alle bekannten Versionen zu deinstallieren und bei neu erscheinenden Versionen immer wieder das Script anpassen zu müssen? 😮

    1. Klar, stimmt schon, dynamisch ist immer besser.
      Man kann aus der Registry auf jeden Fall die aktuellste Version auslesen, HKEY_LOCAL_MACHINE\SOFTWARE\JavaSoft\Java Runtime Environment.
      Problem hier: hier steht nur die aktuellste Version drin. Ich habe beispielsweise 7u71 und 8u25 installiert, da drin ist nur die 8er gelistet. Ist also schonmal riskant damit zu arbeiten.
      Alternativ könnte man im Uninstall Key nach Java Versionsnummern suchen, like that. Aber auch hier müsste man alle Versionsnummern durchprobieren und auf Funde reagieren.
      Later: Hab mal recherchiert. Es gibt schon ein Script, das mit diesem Uninstall Key intelligent sucht und deinstalliert. Ist zwar vbs, aber egal. Hier auf IT-Ninja.
      Außerdem gibt es auch weitere Java Uninstaller/Cleanup Tools wie z.B. JavaRA (mehr dazu). Die Möglichkeiten sind also vielseitig.

      Für mich war der große Codeblock in dem Moment einfach schneller gemacht und getestet, musste nicht angepasst werden, läuft. Alle Uninstaller Strings sind, wenn kein Java installiert ist, in 1-2 Sekunden abgearbeitet, es ist also völlig unproblematisch wenn der Code ne Zeit lang im Script bleibt. Und es war in meinen Augen auch eher eine einmalige Aufräumaktion. Der Code fliegt also auch wieder aus dem Script raus oder wird zumindest auskommentiert/übersprungen. Soweit ich weiß deinstalliert der Java Installer ja auch ältere Versionen während der Installation. Ein komplettes Wipe aller installierten Versionen muss also nicht dauerhaft gemacht werden. War nur beim Umstieg von 7 auf 8 eine gute Idee.

      So, ich hoffe ich konnte ein paar alternative Möglichkeiten aufzeigen 😉

      Update: Hab den Artikel mal mit diesen Alternativen ergänzt.

  2. Hallo Michael,
    ich bin noch bei 8u31, bis dahin keine Probleme.
    Das Script habe ich aber letztens wieder etwas angepasst, die aktuellste Scriptversion habe ich gerade im Artikel aktualisiert. Kannst dir das ja mal ansehen und vergleichen.
    Habe die Versionsüberprüfung geändert und die Installation wieder komplett auf .exe umgestellt und ich glaube die Parameter bisschen aufgeräumt.
    Gibt es Probleme mit 8u40?
    LG

  3. Hast du schon die 8.45 getestet. Ich will die Version über das Startupskript ausrollen. Ist es da die exe oder msi Variante besser? Muss ich etwas anpassen?

    Danke für deine Hilfe

  4. Die Version habe ich noch nicht verteilt, werde ich aber entweder am Donnerstag oder nächste Woche schaffen.
    Ich habe aktuell keinen Favouriten bei der Verteilung – für mich machen .exe und .msi im Endeffekt das Gleiche. Installation, anpassbar.
    Es kommt darauf an wie Software bei euch verteilt wird: via Script (dann ist beides möglich) oder über die Gruppenrichtlinien Pakete (dann msi).
    Aber grundsätzlich, wenn über das Script ausgeführt, nehmen sich die beiden nichts. Zumindest meiner spontanen Überlegung nach.

  5. Uninstall geht mit WMIC viel leichter
    Beispiel

    #Code

    wmic product where „name like ‚Java 7%%'“ call uninstall /nointeractive

    Die Forensoftware verhackstückelt irgendwie die Anführungszeichen – also vor name stehen Anführungstriche und vor java ein hochkomma, dann kommt wieder ein Hochkomma hinter dem letzten % und direkt dahinter wieder Anführungstriche oben

Schreibe einen Kommentar