Extracting the MSI from Java’s EXE Installer, cant be done directly. Normally we would have to run the installer, go to a temp location and copy the MSI file(s).
With this script, you can just drop the Java Offline Installer (EXE) to the SourceFiles folder, run the script, then you can find the MSI file(s) in the MSIFiles folder.
Why did i create this script?
As you may know, Java releases updates quite often. We want to keep our clients up to date for security reasons. I prefer to MSI files whenever it is possible, so that is why i always extract the MSI from the Java Offline Installer EXE file.
Another reason why i started on this script, is because i am relatively new to creating PowerShell scripts, so it was also to learn something new, and try it out.
How to use the script
- Copy the script from below, and save it as Get-JavaMSI.ps1 in a empty folder.
- Run the script once, to create the folder needed. you can do so from a command line: powershell.exe -ExecutionPolicy ByPass -File Get-JavaMSI.ps1
- Go to java.com and download the version you wish to use. Remember to get the offline installer
- Save the offline installer in the SourceFiles folder, that Get-JavaMSI.ps1 created
- Now run the script again, like step 2.
This time the script, will execute the installer, copy the MSI from its temp location, and paste it in the MSIFiles folder next to the SourceFiles folder. Then it will kill the java installer again. - You can place more then one EXE, eg both the 32 and 64 bit version of Java, in the SourceFiles folder. It will still take both and extract them. (Remember you need to run this on a 64 bit Windows, if you want to extract the 64 bit version of Java.
Extract Java MSI from EXE with PowerShell
Save this script as Get-JavaMSI.ps1
# Checking if Source and MSI folder exists, if not we create them and exit If(!(Test-Path -Path "$PSScriptRoot\SourceFiles") -or !(Test-Path -Path "$PSScriptRoot\MSIFiles")) { Write-Host "One or more folder(s) does not exist. Creating them" New-Item -Path $PSScriptRoot\SourceFiles -ItemType Directory -Force | Out-Null New-Item -Path $PSScriptRoot\MSIFiles -ItemType Directory -Force | Out-Null Write-Host "Folder(s) created.. Copy the offline java EXE installer into the SourceFiles directory. Then run this script again..." } Else { $SourceFiles = Get-ChildItem -Path $PSScriptRoot\SourceFiles\*.exe # Setting the LocalLow path, using the AppData\Local and replace Local to LocalLow $LocalLowJava = "$env:LOCALAPPDATA\Oracle\Java" -replace 'Local', 'LocalLow' # Clearing the Java Temp installer folder, before we start If(Test-Path -Path $LocalLowJava) { Remove-Item -Path "$LocalLowJava\*" -Recurse } ForEach($sFile in $SourceFiles) { # grabbing the java version from the file name $jreVersion = Select-String -Pattern '[0-9]u[0-9]+' -InputObject $sFile.Name | ForEach-Object -Process { $_.Matches } | ForEach-Object -Process { $_.Value } # Converting the Java version to the temp file name structure $jreTempVersion = $jreVersion -replace 'u', '.0_' # Setting the temp MSI path If($sFile -like "*x64*") { $jreTempMSI = "$LocalLowJava\jre1.$($jreTempVersion)_x64\jre1.$($jreTempVersion)64.msi" } Else { $jreTempMSI = "$LocalLowJava\jre1.$jreTempVersion\jre1.$jreTempVersion.msi" } Write-Host -Object "Start grabbing $jreTempMSI" # Starting the Java installer Start-Process -FilePath $sFile -WindowStyle Hidden # Waiting for the MSI to be extracted by the EXE file while(!(Test-Path $jreTempMSI)) { Start-Sleep -Seconds 2 } Copy-Item -Path $jreTempMSI -Destination $PSScriptRoot\MSIFiles -Force # Kill the Java Process Get-Process -Name 'jre*windows*' | Stop-Process # Wait for the process to die While (Get-Process -Name 'jre*windows*') { Start-Sleep -Seconds 2 } } # Clearing the Java Temp installer folder, before we end If(Test-Path -Path $LocalLowJava) { Remove-Item -Path "$LocalLowJava\*" -Recurse } Write-Host -Object 'Done!' }
Please feel free to comment, if you have any suggestions to the script, things i can code better or just to say hi.
I hope this was something you could use.
Thanks for reading!
thanks for this,very useful!
I’ve added this to automate it further and download the .exe’s 😉
Function Get-RedirectedUrl {
Param (
[Parameter(Mandatory=$true)]
[String]$URL
)
$request = [System.Net.WebRequest]::Create($url)
$request.AllowAutoRedirect=$false
$response=$request.GetResponse()
If ($response.StatusCode -eq “Found”)
{
$response.GetResponseHeader(“Location”)
}
}
# download the latest JAVA JRE
$FileName86 = [System.IO.Path]::GetFileName((Get-RedirectedUrl “http://javadl.oracle.com/webapps/download/AutoDL?BundleId=218831_e9e7ea248e2c4826b92b3f075a80e441”))
$FileName64 = [System.IO.Path]::GetFileName((Get-RedirectedUrl “http://javadl.oracle.com/webapps/download/AutoDL?BundleId=218833_e9e7ea248e2c4826b92b3f075a80e441”))
$FileName86 = $FileName86.Split(“&”)[0]
$FileName64 = $FileName64.Split(“&”)[0]
Invoke-WebRequest -Uri http://javadl.oracle.com/webapps/download/AutoDL?BundleId=218831_e9e7ea248e2c4826b92b3f075a80e441 -OutFile “$PSScriptRoot\SourceFiles\$FileName86”
Invoke-WebRequest -Uri http://javadl.oracle.com/webapps/download/AutoDL?BundleId=218833_e9e7ea248e2c4826b92b3f075a80e441 -OutFile “$PSScriptRoot\SourceFiles\$FileName64”