herrmanndominic
Goto Top

Powershell String Suchen mit Wildcard und Ersetzen

Hallo zusammen,

ich bräuchte Unterstützung bei einem Powershell Script.

Ich habe ein Java Rollout per GPO über ein PowerShell Script eingerichtet.
Im Anschluss an das Update, muss die Systemvariable PFAD aktualisiert werden.

Leider stehen in dieser Variable noch einige andere Pfade, sodass ich diesen nicht einfach leeren und mit dem aktuellen Pfad überschreiben kann.

1. Ist Situation vor einem Java Update:

C:\Program Files (x86)\Common Files\\\;C:\Windows\system32;C:\Windows;C:\Windows\System32\;C:\Windows\System32\WindowsPowerShell\v1.0\;C:\Program Files (x86)\\Viewer\bin;C:\Program Files (x86)\\\bin;C:\Program Files (x86)\Java\jre1.8.0_60\bin

2. Soll:

Suchen nach dem String \jre*\ und ersetzen gegen die aktuelle Version:

C:\Program Files (x86)\Common Files\\\;C:\Windows\system32;C:\Windows;C:\Windows\System32\;C:\Windows\System32\WindowsPowerShell\v1.0\;C:\Program Files (x86)\\Viewer\bin;C:\Program Files (x86)\\\bin;C:\Program Files (x86)\Java\jre1.8.0_77\bin

Mein bisheriges Script:

# Script zum Suchen und Ersetzten von Strings in Registry Keys


$RegistryPath = "HKLM:\SYSTEM\CurrentControlSet\Control\Session Manager\Environment"  
$RegistryKey = "Path"  

# Auslesen des Inhaltes eines Registry Keys
$Ist = (Get-ItemProperty -Path $RegistryPath -Name $RegistryKey).Path 

# Suchstring
$SearchStr = "jre*"  

if ($Ist -match $SearchStr)

    {
    write-host "Suchstring $SearchStr gefunden"  
    $Ist -replace $SearchStr,$jreVersion
    
    }
    
else

    {
    write-host "Nicht gefunden"  
    $Soll = Set-ItemProperty -Path "$RegistryPath" -Name "$RegistryKey" -Type ExpandString -Value "$Ist;C:\Program Files (x86)\Java\jre1.8.0_99\bin"  
    }

Das Ergebnis sieht leider folgendermaßen aus:

C:\Program Files (x86)\Common Files\\\;C:\Windows\system32;C:\Windows;C:\Windows\System32\;C:\Windows\System32\WindowsPowerShell\v1.0\;C:\Program Files (x86)\\Viewer\bin;C:\Program Files (x86)\\\bin;C:\Program Files (x86)\Java\jre1.8.0_771.8.0_99\bin

Es wird also nur das jre ersetzt. Ich möchte gerne, das alles zwichen den beiden Backslashs ersetzt wird.

Habt ihr eine Idee?

Content-ID: 305239

Url: https://administrator.de/contentid/305239

Ausgedruckt am: 19.11.2024 um 08:11 Uhr

129413
129413 24.05.2016 aktualisiert um 09:57:36 Uhr
Goto Top
Hi,
das ist bei aktuellen Java-Versionen doch gar nicht mehr nötig. Die tragen doch automatisch folgenden universellen Pfad in PATH ein:
C:\ProgramData\Oracle\Java\javapath

Dort zeigen Symlinks auf die aktuellen Version.

Gruß skybird

p.s. das hatten wir doch vor kurzem schon mal hier
Windows 7 - PATH - ändern
colinardo
Lösung colinardo 24.05.2016 aktualisiert um 10:37:58 Uhr
Goto Top
Hallo herrmanndominic!
Da kann ich @129413 nur zustimmen, die aktuellen Versionen setzen diesen universellen Pfad in die PATH Umgebungsvariable ein.

Willst du dein Vorhaben trotzdem so umsetzen, warum auch immer, sollte dir folgendes Skript helfen:
# reg key je nach OS Architecture anpassen
if ((gwmi win32_operatingsystem).OSArchitecture -eq '64-Bit'){  
    $key = 'HKLM:\SOFTWARE\Wow6432Node\JavaSoft\Java Runtime Environment'  
}else{
    $key = 'HKLM:\SOFTWARE\JavaSoft\Java Runtime Environment'  
}
try{
    # Hauptversion holen
    $main = (Get-ItemProperty $key -Name CurrentVersion).CurrentVersion
    # Pfad zur aktuellen Version extrahieren
    $currentpath = (Get-ItemProperty ($key + "\$main")).JavaHome  
}catch{}

# Wenn Version gefunden wurde ersetze die "System"-Umgebungsvariable PATH 
if ($currentpath){
    [System.Environment]::SetEnvironmentVariable('PATH',([System.Environment]::GetEnvironmentVariable('PATH',2) -replace '[^;]+\\jre[^;]+',$currentpath), 2)  
}
(Natürlich mit Admin-Rechten auszuführen (Startskript/Task))

Grüße Uwe
herrmanndominic
herrmanndominic 26.05.2016 um 16:09:49 Uhr
Goto Top
Hallo zusammen,

danke für eure Hilfe. Ich habe eure Code Beispiele in folgendes Script umgesetzt:

$RegistryPath = "HKLM:\SYSTEM\CurrentControlSet\Control\Session Manager\Environment"  
$RegistryKey = "Path"  

# Ließt den Inhalt des Registry Keys aus
$Ist = (Get-ItemProperty -Path $RegistryPath -Name $RegistryKey).Path 


# Aktueller Java Pfad, wenn eine neue Version deployed wird.
$JavaPath = "C:\Program Files (x86)\Java\jre1.8.0_77\bin"  

# Suchstring für die foreach Schleife
$SearchStr = "\\java\\*"  

# Erzeugt ein Array aus dem Inhalt, separiert durch das ;
$ar=$ist.Split(";")  

# Dieser Marker steht per Default auf $false und wird geändert, falls die foreach Schleife einen Treffer hat.
$marker = $false

foreach ($item in $ar)
{
    if($item -match $SearchStr)
    {
        # Sucht nach dem String [^;]+\\jre[^;] und ersetzt diesen durch den aktuellen $JavaPath String
        [System.Environment]::SetEnvironmentVariable('PATH',([System.Environment]::GetEnvironmentVariable('PATH',2) -replace '[^;]+\\jre[^;]+',$JavaPath), 2)  
                
        # Nachdem der o.a. Command ausgeführt wurde, wird der KeyType von REG_EXPAND_SZ automatisch in REG_SZ geändert
        # Die beiden nachfolgenden Commands lesen erneut den Inhalt des Keys aus....
        $Value = (Get-ItemProperty -Path $RegistryPath -Name $RegistryKey).Path
        
        #...und ändern den KeyType wieder auf REG_EXPAND_SZ und schreiben den Inhalt zurück
        Set-ItemProperty -Path "$RegistryPath" -Name "$RegistryKey" -Type ExpandString -Value "$Value"  
        
        # Setzt den Marker File auf $True, damit, falls kein entsprechender Java String vorhanden ist, der aktuelle String hinzugefügt wird
        $marker = $True
    }
}
    
if($marker -eq $false)
    {
        # Füllt den Path Key am Anfang mit dem aktuellen Java Pfad ($JavaPath) und hängt alle vorher ausgelesenen Einträge wieder an
        Set-ItemProperty -Path "$RegistryPath" -Name "$RegistryKey" -Type ExpandString -Value "$JavaPath;$Ist"       
    }
129413
129413 26.05.2016 aktualisiert um 18:30:09 Uhr
Goto Top
Wieso du doppelt gemoppelt zusätzlich noch nach
$SearchStr = "\\java\\*"
suchst verstehe wer will ??? Das alles macht doch schon der Regex
'[^;]+\\jre[^;]+'
von @colinardo face-smile denn kannst du ja wenn du willst stattdessen noch ausbauen zu
'[^;]+\\java\\jre[^;]+'
Dein doppeltes Konstrukt ist also vollkommen überflüssig.
colinardo
colinardo 26.05.2016 aktualisiert um 19:10:38 Uhr
Goto Top
Eben, das Skript war ja dadurch schon komplett und funktionsfähig, da braucht es kein unzuverlässiges Registry-Gebastel wenn es doch die passenden Funktionen zum Setzen der System-Umgebungsvariablen gibt face-smile

Außerdem wird bei der Variante die aktuell installierte Java-Version schon von selbst ausgelesen, so kann es nicht zum Setzen eines falschen Pfades kommen falls das Java doch noch nicht korrekt deployed wurde.

Naja jeder wie ers mag ...
herrmanndominic
herrmanndominic 27.05.2016 um 09:15:05 Uhr
Goto Top
Ihr habt natürlich recht, dass man einiges optimieren könnte. Ich stehe aber noch am Anfang im Umgang mit PS. Das Script von colinardo hatte nicht auf Anhieb funktioniert.
Daher habe ich mich vorerst damit begnügt, ein paar Zeilen für mein Script zu verwenden, damit das Script erstmal soweit funktioniert und genutzt werden kann.
Wenn ich mehr Zeit habe, werde ich mir colinardo's Script genauer anschauen und anschließend einbauen, damit dynamisch auf die Version reagiert wird.

Vielen Dank für euren Support