我们有一个依赖于 Java 的应用程序,我们正在开发 SCCM 安装程序以将其推送给客户端。
由于 Java 几乎每月更新一次(旧更新将在 30 天后过期),我们正在寻找一种方法让 SCCM 安装程序保持最新 Java 版本的更新。我们能够从 SCCM 安装程序运行 Powershell 脚本,但我们还没有找到一种方法来编写自动下载并安装最新 Java 版本的脚本。
有谁知道这是否可行,以及我们该如何去做?
提前致谢!
请查看 this 来使用 powershell 下载文件,以及 this 来安装 javasilent。 例如:
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。但 atm 我不知道如何获得链接。 我希望这会有所帮助。
您可以使用此页面上提供的链接进行下载:http://java.com/en/download/manual.jsp
或者,您可以下载一次并将其放在文件共享上,这样您就可以使用简单的方法从 UNC 路径复制文件,例如
\\fileserver\folder\installerpackage.exe
做好头痛的准备。我自己曾在数十台机器上删除和升级 Java,我可以告诉您,这并不总是干净的卸载/重新安装。除非他们改进了卸载程序,否则您很可能最终会遇到 Java 安装程序认为它已安装但实际上并未安装的情况。我也看到过相反的情况,它认为它没有安装,但它确实安装了。
首先您需要获取最新的下载链接(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'
我们可以通过执行setup并复制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
,这是可用于构建 SCCM 包的 msi 路径。
我在我的一个项目中遇到了类似的问题,该项目具有 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 ';'
希望这对您有用。