Jump to content

PS: Java-Version ermitteln und deinstallieren


Direkt zur Lösung Gelöst von MurdocX,
Der letzte Beitrag zu diesem Thema ist mehr als 180 Tage alt. Bitte erstelle einen neuen Beitrag zu Deiner Anfrage!

Empfohlene Beiträge

Hallo,

 

ich möchte Java deinstallieren, wenn die installierte Version von der Version "Java 8 Update 101" abweicht.

Ermitteln kann ich die Version mit Powershell über eine WMI-Abfrage:

$ausgabe1 = "Java"
$ausgabe2 = "8 Update 101"
$java_version = (Get-WmiObject -Class Win32_Product | Where { $_.Name -like $ausgabe1, $ausgabe2 }).IdentifyingNumber

 

Das Ergebnis lautet dann:

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

 

Die Variablen $ausgabe1 und $ausgabe2 wählte ich nur, weil ich das Teilergebnis "Java" benötige, von dem aber dann das Teilergebnis "8 Update 101" abweichen muss, damit von der abweichenden Version die "IdentifyingNumber" als Uninstall String zu MsiExec übergeben werden kann, also "MsiExec.exe /qn /norestart /X $java_version".

Ich hoffe, keinen Denkfehler begangen zu haben, denn wenn die Abfrage funktioniert, würde jede Java-Version <> "8 Update 101" deinstalliert werden und danach kann ich dann das Setup von "jre-8u101-windows-i586.exe" aufrufen.

Leider weiß ich nicht, wie ich beide Ausgaben UND-verknüpfen kann. Alle meine Versuche liefen entweder auf Syntaxfehler hinaus bzw. es wurden mir Uninstall Strings aller anderen Software geliefert, was im Falle einer Deinstallation fatal wäre. Geht das irgendwie oder ist mein Vorhaben rein von meiner Logik her gar nicht realisierbar?

Danke vorab für jede konstr. Hilfe.

Link zu diesem Kommentar

Hallo,

Wenn ich dich richtig verstanden habe, würde ich es so strukturieren.

$myName = "Java" #da unten mit "-eq" gearbeitet wird, ist der genaue String erforderlich. Sonst nimm "-like"
$myVersion = "8 Update 101" #ggf mit Platzhalter "*" arbeiten

$Products = @((Get-WmiObject -Class Win32_Product | Where { $_.Name -eq $myName -and $_.Version -notlike $myVersion })

Foreach ($Product in $Products){
    $Product.IdentifyingNumber
    $Product.Version
    
    #Msiexec......
    
    #aber Win32_Product() hat auch eine eigenen uninstall-Methode
    #$Product.Uninstall()  #https://msdn.microsoft.com/en-us/library/aa394378(v=vs.85).aspx 
}

blub

Link zu diesem Kommentar

Hallo blub,

 

vielen Dank für deine Mühe, aber ich bekomme beim Ausführen einen Syntaxfehler, da ein ")" fehlt:

Fehlende schließende ")" im Unterausdruck.
At line:14 char:2

Streiche ich eines der zwei "(" in der Variable $Products und leite die Ausgabe in Write-Host um, bekomme ich keine Ausgabe. Irgendwie funktioniert die Anweisung nicht so wie gewünscht.

Testweise installiert sind "Java 7 Update 5" und "Java 8 Update 92".

Das Script sieht so aus:

$myName = "Java" 
$myVersion = "8 Update 101" 

$Products = @(Get-WmiObject -Class Win32_Product | Where { $_.Name -like $myName -and $_.Version -notlike $myVersion })

Foreach ($Product in $Products){
    $Product.IdentifyingNumber
    $Product.Version
    
    Write-Host $Products
    
}

Hast du evtl. eine Idee, wo das Problem liegen könnte?

Danke vorab.

 

 

P.S.: Kleines Update: Falls .Version in der Variable $Products "8 Update 101" erwartet, wird das Script so nicht funktionieren, denn als Version wird "8.0.1010.13" ausgegeben. Allerdings funktioniert das Script damit auch nicht wie erwartet. Ganz ohne Filter werden diese Werte für die aktuellste Java-Version ausgegeben:

Win32_Product.IdentifyingNumber="{26A24AE4-039D-4CA4-87B4-2F32180101F0}",Name="Java 8 Update 101",Version="8.0.1010.13"
bearbeitet von ibicis
Link zu diesem Kommentar
  • Beste Lösung

Hallo,

 

ich würde die Versionen anhand des Versionseintrag unterscheiden und das ganze nicht so kompliziert machen. 

 

Hier wird erst mal alles gesammelt was vorhanden ist.  Danach Filtern wir nach allem mit dem Namen "Java" und einer älteren Version als die angegebene.

$objJavaProgramList = Get-WmiObject -Class Win32_Product | Where-Object {$_.Name -like 'Java*' -and $_.Version -lt '8.0.1010.13'} 

Nun können wir im nächsten Schritt alle gesammelten alten Versionen entfernen. Dies kannst du mit einem ForEach durchführen.

ForEach ($objJavaProgramItem in $objJavaProgramList)
{
  $objJavaProgramItem.Uninstall()
}

Anstatt ".Uninstall()" zu verwenden, kannst du deine msiexec.exe Routine durchführen. Das "x" würde ich auch nicht an das Ende setzten, da das eventuell als Protokollierungsoption gewertet werden könnte.

 

So würde ich das ungefähr umsetzen  ;)

Start-Process -FilePath "msiexec.exe" -ArgumentList "/x $($objJavaProgramItem.IdentifyingNumber) /qn /norestart"

Nun genug der Musterlösung....  :o

bearbeitet von MurdocX
Link zu diesem Kommentar

Hallo MurdocX,

 

vielen Dank. Alle Codeschnipsel zu einem Script zusammengefügt scheinen genau das zu machen, was ich möchte. Der Operator -lt war mir gänzlich unbekannt, nun weiß ich, was er bewirkt.

 

Die Uninstall-Routine entfernt zuverlässig die JAVA-Installation. Worin liegt der Vorteil, den Job an msiexec zu übergeben? Ich tat dies nur aus Unwissenheit über die ProgramItem.Uninstall-Funktion.

Link zu diesem Kommentar

Hallo MurdocX,

 

vielen Dank. Alle Codeschnipsel zu einem Script zusammengefügt scheinen genau das zu machen, was ich möchte. Der Operator -lt war mir gänzlich unbekannt, nun weiß ich, was er bewirkt.

 

Danke, das freut mich zu hören. Dann ist das damit ja die Lösung ;-)

 

Worin liegt der Vorteil, den Job an msiexec zu übergeben?

 

Du könntest noch das ein oder andere Protokollieren. ( Bsp. msiexec.exe /? ) Wenn die Uninstall()-Funktion von dem WMI-Objekt sauber funktioniert, dann würde ich diese auch so einsetzen.

 

Um auch den Rest der Forum-Benutzer glücklich zu machen, können wir das Ganze noch auf einen "Einzeiler" zusammenkürzen ;-)

Get-WmiObject -Class Win32_Product | Where-Object { $_.Name -like 'Java*' -and $_.Version -lt '8.0.1010.13' } | ForEach-object { Write-host ":: Entferne $($_.Name), Versionsstand: $($_.Version)"; $_.Uninstall() }

 

Link zu diesem Kommentar

Auch wenn es schon gelöst ist, will ich das Tool noch mit in die Diskussion werfen: http://wsus.de/uninstall2install

Der Vorteil daran ist, es können per msiexec /X alle vorhandenen Versionen deinstalliert werden. Im Artikel ist Java als Beispiel genannt, kann natürlich mit allen anderen Programmen gemacht werden, die über msiexec installiert/deinstalliert werden. Zusätzlich kann ich Uninstall2Install schön über den WPP auf den WSUS pumpen und darüber den Clients zur Verfügung stellen.

Link zu diesem Kommentar

Mit dem -lt Operator für Strings musst du sehr aufpassen, ob der wirklich immer das macht und machen wird, was du erwartest!

 

zählt Java z.b. die letzte Nummer/String immer zweistellig? ( ich würde mir die Java-Versionierung jedenfalls genau ansehen)

'8.0.1010.2' -lt '8.0.1010.13' ->false

oder

'8.0.1010.02' -lt '8.0.1010.13' ->true

 

 

die erste Nummer/ String aus deinem Beispiel ist ebenso eine Zeitbombe.

'10.0.1010.13' -lt '8.0.1010.13' -> true

 

-lt, -gt sind ansich für numerische Werte. -Like und -Match ggf. mit "regular expressions" sind für Strings

Link zu diesem Kommentar

Hallo,

 

danke an alle für die Tipps, danke an blub für die Erklärung - habe daher aus -lt -ne gemacht. Damit werden zwar auch höhere Versionen deinstalliert, was aber praktisch keine Bedeutung hat.

Ein wenig - ich sage mal - "ungünstig", ist der Umstand, dass wieder einmal viele Wege nach Rom führen. Auf diese Weise so etwas wie eine Systematik für PS zu bekommen ist schwierig. Für mich ist PS leider nach wie vor wie ein Sportwagen mit 1000 PS, dem aber nur eine japanischsprachige Bedienungsanleitung beiliegt - ich kann das Teil im ersten Gang fahren, weil er bereits eingelegt ist. Alle anderen Gänge sind nur über ein Touch Panel schaltbar. War jetzt nicht die originellste Analogie, bringt aber auf den Punkt, worauf ich hinaus will.

Link zu diesem Kommentar

Powershell ist eine OO-Programmiersprache mit sehr viel Power, das hast du richtig erkannt. Allerdings ist die Logik dahinter nicht anderst, als bei anderen Sprachen. Kannst du eine, kannst du "quasi" alle. 

 

Es wäre allgemein sicher von Nützen, wenn du dich mal mit einer Programmiersprache deiner Wahl auseinandersetzt.

 

Hier hilft auch viel lesen von anderen Skripten und versuchen diese zu verstehen. Am Besten mal in der ISE debuggen und die Variablen nach den einzelnen Vorgängen auslesen. 

Link zu diesem Kommentar

Hallo nochmal,

 

ich dachte, die if else-Bedingungen bekomme ich allein hin, aber leider wird das Setup immer ausgeführt, egal ob eine ältere oder die neueste Java-version drauf installiert ist. Mein bisheriges Script:

$java_setup = (\\fileserver\install\Java8u101\jre-8u101-windows-i586.exe /s)
if
($objJavaProgramList = Get-WmiObject -Class Win32_Product | Where-Object {$_.Name -like 'Java*' -and $_.Version -ne '8.0.1010.13'})
{
ForEach ($objJavaProgramItem in $objJavaProgramList)
    {
    $objJavaProgramItem.Uninstall()
    }
        {    
        $java_setup
        }
}
else
{
exit
}

Was habe ich nicht verstanden bzw. was mache ich falsch, danke vorab?

Link zu diesem Kommentar

Hallo nochmal,

 

ich dachte, die if else-Bedingungen bekomme ich allein hin, aber leider wird das Setup immer ausgeführt, egal ob eine ältere oder die neueste Java-version drauf installiert ist. Mein bisheriges Script:

$java_setup = (\\fileserver\install\Java8u101\jre-8u101-windows-i586.exe /s)
if
($objJavaProgramList = Get-WmiObject -Class Win32_Product | Where-Object {$_.Name -like 'Java*' -and $_.Version -ne '8.0.1010.13'})
{
ForEach ($objJavaProgramItem in $objJavaProgramList)
    {
    $objJavaProgramItem.Uninstall()
    }
        {    
        $java_setup
        }
}
else
{
exit
}

Was habe ich nicht verstanden bzw. was mache ich falsch, danke vorab?

 

 

Ich habe die unnötigen Leerzeilen mal entfernt und strukturiert. Das ist wichtig, damit man den Code im Nachgang auch wieder lesen kann. Das Debugging wird wesentlich erleichtert. Am Besten gleich angewöhnen. Das Ergebnis sieht das so aus: 

$java_setup = (\\fileserver\install\Java8u101\jre-8u101-windows-i586.exe /s)


if ($objJavaProgramList = Get-WmiObject -Class Win32_Product | Where-Object {$_.Name -like 'Java*' -and $_.Version -ne '8.0.1010.13'})
{
  ForEach ($objJavaProgramItem in $objJavaProgramList)
  {
    $objJavaProgramItem.Uninstall()
  }
  {    
    $java_setup
  }
}
else
{
  exit
}

Du hast einen Block der keine Funktion besitzt....  { $java_Setup }... Nachdem ForEach mit "}" beendet wurde, macht der Rest keinen Sinn ;-) Setze es einfach unter "....Uninstall()"

 

In der Powershell solltest du die Programme über "Start-Process" starten, damit die übergebenen Argumente "/s" nicht falsch oder gar nicht interpretiert werden. (Bsp. Start-Process -FilePath -ArgumentList )

bearbeitet von MurdocX
Link zu diesem Kommentar

Hallo MurdocX,

 

danke für deine Tipps. Die Variable $java_setup habe ich nun entsprechend formatiert.

Ich habe die Setupanweisung nun wie empfohlen direkt unter die Deinstallation gelegt, was aber leider dasselbe Verhalten auslöst (ich hatte es vor meinem Posting aber auch schon getan mit demselben Ergebnis). 

$java_setup = Start-Process -FilePath "\\fileserver\install\Java8u101\jre-8u101-windows-i586.exe" -ArgumentList /s
if
($objJavaProgramList = Get-WmiObject -Class Win32_Product | Where-Object {$_.Name -like 'Java*' -and $_.Version -ne '8.0.1010.13'})
{
ForEach ($objJavaProgramItem in $objJavaProgramList)
{
$objJavaProgramItem.Uninstall()
$java_setup
}
}
else
{
exit
}

So richtig verstehe ich es aktuell gerade nicht.

 

Ich habe mal die Install-Uninstall-Routinen in echos umgewandelt - PS verhält sich dann völlig korrekt und antwortet mit "Keine Installation notwendig.":

$java_setup = echo "Ich installiere nun."
if
($objJavaProgramList = Get-WmiObject -Class Win32_Product | Where-Object {$_.Name -like 'Java*' -and $_.Version -ne '8.0.1010.13'})
{
ForEach ($objJavaProgramItem in $objJavaProgramList)
    {
    $objJavaProgramItem.Uninstall()
    $java_setup
    }
}
else
{
echo "Keine Installation notwendig."
}

Führe ich aber die Routine wie geplant aus, wird Java immer wieder neu installiert, was man an 2 Prozessen erkennen kann, die dann laufen oder indem ich den /s-Schalter weglasse - dann kommt das Install-GUI.

Ehrlich gesagt kann ich mir darauf überhaupt keinen Reim machen.

Link zu diesem Kommentar

"Start-Process" ist auch eine Anweisung die direkt ausgeführt wird. Falls das Cmdlet eine Ausgabe (Ergebnis) hat, dann wird diese in die Variable $java_setup abgelegt.

 

Start-Process - TechNet

https://technet.microsoft.com/de-de/library/hh849848.aspx

 

Lass die Variable einfach weg und schreibe das "Start-Process" unter deine Uninstall-Routine

 

Um der UAC noch genüge zu tun, musst du noch den Parameter "-Verb RunAs" in "Start-Process" mit einbauen. Sonst wird deine Anwendung als Benutzer und nicht als Administrator ausgeführt.

 

PS: Für zwischen Ausgaben kannst du "Write-Host" benutzen. Bsp:

Write-Host "Installiere nun..."

bearbeitet von MurdocX
Link zu diesem Kommentar
Der letzte Beitrag zu diesem Thema ist mehr als 180 Tage alt. Bitte erstelle einen neuen Beitrag zu Deiner Anfrage!

Schreibe einen Kommentar

Du kannst jetzt antworten und Dich später registrieren. Falls Du bereits ein Mitglied bist, logge Dich jetzt ein.

Gast
Auf dieses Thema antworten...

×   Du hast formatierten Text eingefügt.   Formatierung jetzt entfernen

  Only 75 emoji are allowed.

×   Dein Link wurde automatisch eingebettet.   Einbetten rückgängig machen und als Link darstellen

×   Dein vorheriger Inhalt wurde wiederhergestellt.   Editor-Fenster leeren

×   Du kannst Bilder nicht direkt einfügen. Lade Bilder hoch oder lade sie von einer URL.

×
×
  • Neu erstellen...