ibicis 10 Geschrieben 6. August 2016 Melden Teilen Geschrieben 6. August 2016 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. Zitieren Link zu diesem Kommentar
blub 115 Geschrieben 6. August 2016 Melden Teilen Geschrieben 6. August 2016 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 Zitieren Link zu diesem Kommentar
ibicis 10 Geschrieben 7. August 2016 Autor Melden Teilen Geschrieben 7. August 2016 (bearbeitet) 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 7. August 2016 von ibicis Zitieren Link zu diesem Kommentar
Beste Lösung MurdocX 949 Geschrieben 7. August 2016 Beste Lösung Melden Teilen Geschrieben 7. August 2016 (bearbeitet) 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 7. August 2016 von MurdocX Zitieren Link zu diesem Kommentar
ibicis 10 Geschrieben 8. August 2016 Autor Melden Teilen Geschrieben 8. August 2016 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. Zitieren Link zu diesem Kommentar
MurdocX 949 Geschrieben 8. August 2016 Melden Teilen Geschrieben 8. August 2016 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() } Zitieren Link zu diesem Kommentar
Sunny61 806 Geschrieben 8. August 2016 Melden Teilen Geschrieben 8. August 2016 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. Zitieren Link zu diesem Kommentar
blub 115 Geschrieben 8. August 2016 Melden Teilen Geschrieben 8. August 2016 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 Zitieren Link zu diesem Kommentar
ibicis 10 Geschrieben 8. August 2016 Autor Melden Teilen Geschrieben 8. August 2016 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. Zitieren Link zu diesem Kommentar
MurdocX 949 Geschrieben 8. August 2016 Melden Teilen Geschrieben 8. August 2016 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. Zitieren Link zu diesem Kommentar
ibicis 10 Geschrieben 9. August 2016 Autor Melden Teilen Geschrieben 9. August 2016 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? Zitieren Link zu diesem Kommentar
MurdocX 949 Geschrieben 9. August 2016 Melden Teilen Geschrieben 9. August 2016 (bearbeitet) 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 9. August 2016 von MurdocX Zitieren Link zu diesem Kommentar
ibicis 10 Geschrieben 9. August 2016 Autor Melden Teilen Geschrieben 9. August 2016 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. Zitieren Link zu diesem Kommentar
MurdocX 949 Geschrieben 9. August 2016 Melden Teilen Geschrieben 9. August 2016 (bearbeitet) "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 9. August 2016 von MurdocX Zitieren Link zu diesem Kommentar
ibicis 10 Geschrieben 9. August 2016 Autor Melden Teilen Geschrieben 9. August 2016 Hallo MurdocX, vielen Dank, aber das interessiert mein Script leider überhaupt nicht. Das Setup wird aufgerufen, egal ob Java der aktuellen Version entspricht oder nicht. Ich dachte erst, es läge evtl. daran, dass ich es "als Administrator ausführe", aber auch unter meinem Account ausgeführt startet die Installation. Zitieren Link zu diesem Kommentar
Empfohlene Beiträge
Schreibe einen Kommentar
Du kannst jetzt antworten und Dich später registrieren. Falls Du bereits ein Mitglied bist, logge Dich jetzt ein.