Registry Env:Path parse and manipulate a string with multiple values

This topic contains 7 replies, has 3 voices, and was last updated by  js 2 weeks, 5 days ago.

  • Author
    Posts
  • #83375

    Chris H
    Participant

    Fairly new to the Powershell community and have dove in over my head working days and searching endlessly to find a way to change the ENV:Path string. ("HKLM:\System\currentControlSet\Control\Session Manager\Environment" -Name Path).path

    I need to remove or replace the old Java path c:\program files (x86)\Java\jre1.8.0_151 with the new c:\program files (x86)\Java\jre1.8.0_152 and make it permanent within the Path string that is c:\Windowssystem32;c:\Windows;c:\Windows\System32\Wbem;c:\Windows\System32\WindowsPowershell\v1.0\;c:\Program Files (x86)\Java\jre1.8.0._151;c:\Program Files (x86\ATI Technologies\ATI.ACE\Core-static;. it goes on but you get the point. I could add to the end of the string but then the string over time will become long with outdated paths.
    All I have so far is this:
    $JavaInstall = test-path "HKLM:\SOFTWARE\WOW6432Node\JavaSoft\"
    If ($JavaInstall -eq $True)
    {
    $CurrentJava = Get-Itempropertyvalue -Name CurrentVersion -path "HKLM:\SOFTWARE\WOW6432Node\JavaSoft\Java Runtime Environment\"
    $CurrentHome = Get-itempropertyvalue -Name JavaHome -path "HKLM:\SOFTWARE\WOW6432Node\JavaSoft\Java Runtime Environment\$CurrentJava"
    $CurrentHklmPath = (Get-ItemProperty -Path "HKLM:\System\CurrentControlSet\Control\Session Manager\Environment" -Name PATH).path

    Ive tried splitting into arrays with split("{;}") with no luck using foreach but that's where it all goes wrong. If I write-host I get the array list but cant figure how to remove the path and put it all back together.

  • #83377

    Don Jones
    Keymaster

    I would probably stick with the -split, enumerate them to find the one I wanted, change it, and then -join the array back into a string.

    Alternately, if this is completely deterministic, you could just -replace the one you want to change without splitting into an array.

  • #83384

    js
    Participant

    How about using .replace() to replace without regular expressions (the backslashes and parentheses)
    (https://stackoverflow.com/questions/24287537/how-to-replace-literal-strings-in-powershell):

    $env:path = $env:path.replace('c:\program files (x86)\Java\jre1.8.0_151', 'c:\program files (x86)\Java\jre1.8.0_152')
    

    Sigh, oh that's not permanent unless you set it in the registry or do this (https://stackoverflow.com/questions/714877/setting-windows-powershell-path-variable):

    [Environment]::SetEnvironmentVariable("Path", $env:Path, [System.EnvironmentVariableTarget]::Machine )
    
  • #83389

    Chris H
    Participant

    Don: Issue is this is where I am lost. Would it be
    For ($i=0, $i -lt $CurrentHkmlPath; $i++) {}
    or foreach ($path in $currentHkmlPath) {}
    and even then how do i find the string value within the array and change it.

    JS: Thought that was a great idea but no change. Even if, the full path of java would be unknown in the future for a replace. i.e _151 to _152 _153. After the java upgrade the non current version is of unknown path. Lets say I upgrade 152 to 155 in the future. Need a way to search partial, change to current have it be permanent. From what I have read using Env:path would only result in current session and not write permanent. I may be wrong. I'm somewhat new to diving in this deep.

    • #83419

      js
      Participant

      I updated how to save it. I guess you can get into regular expressions. "." means any character. You can work out the right regular expressions on this page: https://regex101.com/ You'd have to put an extra backslash before any other backslash or parenthesis.

  • #83392

    Don Jones
    Keymaster

    I'd use a ForEach.

    $newstring = @()
    $pieces = $mystring -split “;”
    ForEach ($thing in $pieces) {
     If ($thing -eq “whatever I am looking for”) {
      $newstring += “whatever I want instead”
     } else {
      $newstring += $thing
     }
    }
    $final = $newstring -join “;”
    

    Or use -like instead of -eq if you need to do wildcard matches.

  • #83416

    Chris H
    Participant

    Thank you Don, so much!! That works perfectly!!! and it all makes since. I'm am very Grateful for your swift replies and your help with a resolve.

    Thank you again

    Chris H.

    • #83428

      js
      Participant

      Maybe you can use -replace like this, where a dot means any one character:

      $env:path = $env:path -replace 'jre1.8.0_1..','jre1.8.0_152'
      [Environment]::SetEnvironmentVariable("Path", $env:path, [System.EnvironmentVariableTarget]::Machine)
      

      Why do you need to do it, though? I have c:\programdata\oracle\java\javapath in the PATH always pointing to java.exe/javaw.exe/javaws.exe. Although I've had problems with Eclipse.

      Oh, I didn't know -match worked like this with arrays:

      $env:path -split ';' -match 'java'
      
      C:\ProgramData\Oracle\Java\javapath
      C:\Program Files (x86)\Java\jdk1.8.0_73\bin
      

You must be logged in to reply to this topic.