Скрипт Powershell для обновления Java до последней версии

У нас есть приложение, которое зависит от Java, и мы работаем над установщиком SCCM для отправки клиентам.

Из-за того, что Java обновляется почти ежемесячно (а старые обновления истекают через 30 дней после этого), мы ищем способ, чтобы установщик SCCM оставался обновленным до последней версии Java. У нас есть возможность запустить скрипт Powershell из нашего установщика SCCM, но мы не нашли способа написать скрипт, который будет автоматически загружать и устанавливать последнюю версию Java.

Кто-нибудь знает, возможно ли это, и как мы можем это сделать?

Заранее спасибо!!

4 ответа

Решение

Вероятно, вы можете использовать ссылки, доступные на этой странице для загрузки: http://java.com/en/download/manual.jsp

Кроме того, вы можете выполнить загрузку один раз и поместить ее в общую папку, чтобы использовать простые методы для копирования файла из UNC-пути, например

\\fileserver\folder\installerpackage.exe

Просто будьте готовы к головным болям. Разобравшись с удалением и обновлением Java на десятках машин, я могу сказать, что это не всегда чистая деинсталляция / переустановка. Если они не улучшили деинсталлятор, есть большая вероятность, что вы в конечном итоге попадете в ситуацию, когда установщик Java считает, что он установлен, но это не так. Я также видел противоположное, где он думает, что он не установлен, но он есть.

Пожалуйста, посмотрите на это для загрузки файла с powershell и для установки java без вывода сообщений. Например:

Invoke-WebRequest $address -OutFile $destination
# $addressis the http-address of the installer
# $destination is a Path where the the downloadoutput should saved to
$destination /s
# with the '/s' Parameter you are starting the installer silent

Если вы можете получить ссылку для скачивания, вы сможете загрузить и установить Java. Но я понятия не имею, как вы можете получить ссылку. Надеюсь, это немного поможет.

Для начала вам нужно получить последнюю версию Download Link(32-битную версию).

$JavaFile = [pscustomobject]@{
    JavaVersion = ''
    FileName = ''
    DownloadURL =  $((Invoke-WebRequest 'http://www.java.com/en/download/manual.jsp').links | where innerHTML -like "Windows Offline" | select href).href
} 

Для 64-битного URL используйте:

$JavaFile = [pscustomobject]@{
    JavaVersion = ''
    FileName = ''
    DownloadURL =  $((Invoke-WebRequest 'http://www.java.com/en/download/manual.jsp').links | where innerHTML -like "Windows Offline (64-bit)" | select href).href
} 

Итак, теперь мы хотим проверить, загрузили ли мы уже файл. Мы можем сделать это, проверив файл журнала. Поэтому сначала создайте javahistorylog.log для хранения используемых ссылок. С помощью следующей функции мы можем проверить журнал на наличие ссылок.

function CheckHistory ($fileurl,$path){
    $history=Get-Content "$path"
    $r = $false
    Foreach ($historicurl in $history){
        if ($historicurl -eq $fileurl){
            $r = $true
        }
    }
    return $r
}

Если он не был найден, мы можем продолжить скачивание файла.

$JavaFile.FileName = "tempinstaller$(get-date -Format yyMMddmm).exe"
Invoke-WebRequest $JavaFile.DownloadURL -OutFile ("$TempDownloadLocation\"+ $JavaFile.FileName) -ev $DLErr
if($DLErr){Exit}

После загрузки мы можем внести некоторые изменения в setup.exe. Сначала получите версию и сохраните имя.

$TempFileName = $JavaFile.FileName
$JavaFile.JavaVersion = get-item ("$TempDownloadLocation\"+ $JavaFile.FileName) | select -ExpandProperty versioninfo | select -ExpandProperty productversion

Второй набор и сгенерировать имя из оригинального файла имя проп.

$JavaFile.FileName = "jre1."+(((Select-String -Pattern '[0-9]u[0-9]+' -InputObject (get-item ("$TempDownloadLocation\$TempFileName")   | select -ExpandProperty versioninfo | select -ExpandProperty originalfilename)) |
ForEach-Object -Process {
  $_.Matches
} |
ForEach-Object -Process {
  $_.Value
}) -replace 'u', '.0_')

Теперь переименуйте файл.

Rename-Item -Path "$TempDownloadLocation\$TempFileName" -NewName ($JavaFile.FileName+".exe")

обновить историю

if(Test-Path -path ("$TempDownloadLocation\"+$JavaFile.FileName+".exe")){
    add-content "$TempDownloadLocation\javahistorylog.log" $JavaFile.DownloadURL
}

Теперь мы можем подумать о получении MSI-файла для сборки SW-пакета.

MSI будет расположен по адресу:

$MsiFilePathTemp = "$env:LOCALAPPDATA\Oracle\Java\" -replace 'Local', 'LocalLow'

Мы можем получить MSI, выполнив настройку и справившись с MSI:

Start-Process -FilePath ("$TempDownloadLocation\"+$JavaFile.FileName+".exe") -ArgumentList '/s'
while(!(Test-Path ("$MsiFilePathTemp\"+$JavaFile.FileName+"\"+$JavaFile.FileName+".msi")))
{
  Start-Sleep -Seconds 1.5
}
Copy-Item -Path ("$MsiFilePathTemp\"+$JavaFile.FileName+"\"+$JavaFile.FileName+".msi") -Destination $MsiFilePathOut -Force -ErrorVariable $CDR
if($CDR){
    exit
}

Теперь остановите процесс и удалите файл.exe

Get-Process -Name $JavaFile.FileName | Stop-Process
While (Get-Process -Name $JavaFile.FileName -ErrorAction SilentlyContinue)
{
  Start-Sleep -Seconds 2
}
Remove-Item -Path ("$TempDownloadLocation\"+$JavaFile.FileName+".exe") -Force
$MSIFile = ("$MsiFilePathOut\"+$JavaFile.FileName+".msi")

Теперь у вас есть $MSIFile это путь к msi, который вы могли бы использовать для создания своего пакета SCCM.

Я столкнулся с аналогичной проблемой в одном из моих проектов, который имел зависимость от Java, и его пришлось обновить с Java 8 до Java 17. Ниже приведен сценарий Windows Powershell. Вы можете заменить свою конкретную версию.

      $version = "17.0.2";
$zip_url = "https://download.java.net/java/GA/jdk17.0.2/dfd4a8d0985749f896bed50d7138ee7f/8/GPL/openjdk-17.0.2_windows-x64_bin.zip";
$sha_url = "https://download.java.net/java/GA/jdk17.0.2/dfd4a8d0985749f896bed50d7138ee7f/8/GPL/openjdk-17.0.2_windows-x64_bin.zip.sha256"

$java_folder = "C:\ProgramFiles\windows\Java_Temurin-Hotspot_jdk\17.0.2"

# Windows seems to auto-rename folders like "20.0.0" to "20".
$jdk_folder = $java_folder

$bin_folder = $jdk_folder + '\bin'

# Create Java folder.
New-Item -ItemType directory -Path $java_folder -Force
Set-Location $java_folder

# Download JDK ZIP & SHA256 Files
$jdk_zip_file = 'jdk.zip'
$jdk_sha_file = 'sha.sha256'

Invoke-WebRequest -Uri $zip_url -OutFile $jdk_zip_file
Invoke-WebRequest -Uri $sha_url -OutFile $jdk_sha_file

# Extract Archive
Expand-Archive -Path $jdk_zip_file
Remove-Item -Path $jdk_zip_file
Remove-Item -Path $jdk_sha_file

$currentPath = [Environment]::GetEnvironmentVariable('Path', 'Machine')
$newPath = $currentPath + ';' + $bin_folder

# Set the Java bin directory as the default
[Environment]::SetEnvironmentVariable('Path', $newPath, 'Machine')

[Environment]::SetEnvironmentVariable('JAVA_HOME', $jdk_folder, 'Machine')
[Environment]::SetEnvironmentVariable('JDK_HOME', $jdk_folder, 'Machine')
[Environment]::SetEnvironmentVariable('JRE_HOME', $jdk_folder, 'Machine')
 
# To verify the updated JAVA_HOME & Path Environment variables
$javaHome = [Environment]::GetEnvironmentVariable('JAVA_HOME', 'Machine')
Write-Output "JAVA_HOME Variable: $javaHome"

$pathVar = [Environment]::GetEnvironmentVariable('Path', 'Machine')
Write-Output "Path Variable: $pathVar"

java -version

В некоторых случаях может случиться так, что на вашем компьютере установлена ​​более старая версия Java, и, несмотря на вашу установку, старая версия по-прежнему преобладает. В этом конкретном случае вы можете удалить существующий путь из переменной среды Path, чтобы убедиться, что ваш проект использует более новую версию. Вот скрипт для этого

      # Define the path you want to remove
$pathToRemove = "C:\ProgramFiles\windows\Java_Temurin-Hotspot_jdk\8.0.382-5\x64\bin"

# Split the current PATH into individual paths
$paths = $currentPath -split ';'

# Filter out the path you want to remove
$filteredPaths = $paths | Where-Object { $_ -ne $pathToRemove }

# Join the filtered paths back into a single string
$updatedPath = $filteredPaths -join ';'
  

Надеюсь, что это работает для вас.

Другие вопросы по тегам