PowerShell: install Oracle Java 21

learning to install silently install Oracle Java 21 SDK
- Search for a
.msifile containingjdk-21in its name. - Install it silently to the target directory.
- Set
JAVA_HOMEand updatePATH. - Handle errors gracefully.
# PowerShell Script: Auto-detect and install Oracle Java 21 SDK (64-bit) from local MSI
# Requirements:
# - Run as Administrator
# - MSI file must already be downloaded in $searchDir
# Folder where the MSI file is located
$searchDir = "C:\Path\To\Downloaded\Java"
# Target installation directory
$installDir = "C:\JavaApps"
try {
# Validate search directory
if (-not (Test-Path -Path $searchDir -PathType Container)) {
throw "Search directory not found: $searchDir"
}
# Find the MSI file for Java 21 (64-bit)
$msiFile = Get-ChildItem -Path $searchDir -Filter "*.msi" -File |
Where-Object { $_.Name -match "jdk-21.*x64" } |
Sort-Object LastWriteTime -Descending |
Select-Object -First 1
if (-not $msiFile) {
throw "No Oracle Java 21 64-bit MSI file found in: $searchDir"
}
$msiPath = $msiFile.FullName
Write-Host "Found MSI: $msiPath" -ForegroundColor Cyan
# Ensure target directory exists
if (-not (Test-Path -Path $installDir -PathType Container)) {
New-Item -Path $installDir -ItemType Directory -Force | Out-Null
}
Write-Host "Installing Oracle Java 21 SDK to $installDir ..." -ForegroundColor Cyan
# Run MSI installation silently with custom directory
$arguments = "/i `"$msiPath`" INSTALLDIR=`"$installDir`" /qn /norestart"
$process = Start-Process -FilePath "msiexec.exe" -ArgumentList $arguments -Wait -PassThru
if ($process.ExitCode -eq 0) {
Write-Host "Java 21 SDK installed successfully to $installDir" -ForegroundColor Green
} else {
throw "MSI installation failed with exit code $($process.ExitCode)"
}
# Set JAVA_HOME and update PATH
$javaHome = $installDir
[Environment]::SetEnvironmentVariable("JAVA_HOME", $javaHome, [System.EnvironmentVariableTarget]::Machine)
$currentPath = [Environment]::GetEnvironmentVariable("Path", [System.EnvironmentVariableTarget]::Machine)
if ($currentPath -notlike "*$javaHome\bin*") {
[Environment]::SetEnvironmentVariable("Path", "$currentPath;$javaHome\bin", [System.EnvironmentVariableTarget]::Machine)
}
Write-Host "JAVA_HOME set to $javaHome and PATH updated." -ForegroundColor Yellow
Write-Host "You may need to restart your terminal or log off/on for changes to take effect." -ForegroundColor Yellow
} catch {
Write-Host "Error: $_" -ForegroundColor Red
exit 1
}
How to Use
- Save this script as
InstallJava21Auto.ps1. - Change the
$searchDirvariable to the folder where your downloaded MSI is stored. - Open PowerShell as Administrator.
when running it use the following:
Set-ExecutionPolicy Bypass -Scope Process -Force .\InstallJava21Auto.ps1
JDK
param(
[string]$MsiPath = "C:\Path\To\jdk-21_windows-x64_bin.msi", # Path to MSI
[string]$LogPath = "C:\Path\To\jdk21_install.log", # Path to log file
[string]$InstallDir = "C:\Program Files\Java\jdk-21", # Install location
[switch]$SetEnv # Use -SetEnv to set JAVA_HOME & PATH
)
# --- Check if MSI exists ---
if (-Not (Test-Path $MsiPath)) {
Write-Host "ERROR: MSI file not found at $MsiPath" -ForegroundColor Red
exit 1
}
# --- Install JDK 21 silently ---
Write-Host "Starting Oracle JDK 21 installation..."
Start-Process msiexec.exe -ArgumentList @(
"/i `"$MsiPath`"",
"/qn", # Quiet mode
"/norestart", # No auto-restart
"INSTALLDIR=`"$InstallDir`"",
"/L*v `"$LogPath`""
) -Wait
# --- Verify installation ---
$javaExe = Join-Path $InstallDir "bin\java.exe"
if (Test-Path $javaExe) {
Write-Host "Oracle JDK 21 installed successfully." -ForegroundColor Green
Write-Host "Log file saved to: $LogPath"
} else {
Write-Host "Installation may have failed. Check log file: $LogPath" -ForegroundColor Yellow
exit 1
}
# --- Optionally set JAVA_HOME and update PATH ---
if ($SetEnv) {
Write-Host "Setting JAVA_HOME and updating PATH..."
# Set JAVA_HOME system-wide
setx JAVA_HOME "`"$InstallDir`"" /M | Out-Null
# Update PATH if not already present
$currentPath = [Environment]::GetEnvironmentVariable("Path", "Machine")
if ($currentPath -notlike "*$InstallDir\bin*") {
$newPath = "$currentPath;$InstallDir\bin"
setx Path "`"$newPath`"" /M | Out-Null
Write-Host "PATH updated to include $InstallDir\bin"
} else {
Write-Host "PATH already contains $InstallDir\bin"
}
Write-Host "JAVA_HOME set to $InstallDir" -ForegroundColor Cyan
} else {
Write-Host "Skipping environment variable setup (JAVA_HOME & PATH not changed)." -ForegroundColor Yellow
}
<#
only
.\Install-JDK21.ps1
with set path
.\Install-JDK21.ps1 -SetEnv
#>
Uninstall JDK
How It Works
- Registry Search – Looks in both 64-bit and 32-bit uninstall registry keys.
- Pattern Match – Matches
Java SE Development Kit 21to target only JDK 21. - Silent Execution – Uses
/qn /norestartfor MSI or/sfor EXE uninstallers. - Logging – Writes all actions and errors to
C:\Temp\Java21JDK_Uninstall.log. - Error Handling – Catches and logs unexpected errors.
<#
.SYNOPSIS
Silently uninstalls Oracle Java 21 JDK (64-bit) and logs the process.
.DESCRIPTION
This script searches the registry for Oracle Java 21 JDK 64-bit installations,
executes the uninstall command silently, and logs all actions and errors.
.NOTES
Author: Your Name
Tested on: Windows 10/11, PowerShell 5.1+
#>
# =========================
# CONFIGURATION
# =========================
$LogFile = "C:\Temp\Java21JDK_Uninstall.log"
$ProductNamePattern = "Java SE Development Kit 21" # Exact match pattern for Oracle JDK 21
$SilentArgs = "/qn /norestart" # MSI silent uninstall arguments
# =========================
# LOGGING FUNCTION
# =========================
function Write-Log {
param (
[string]$Message,
[string]$Level = "INFO"
)
$timestamp = Get-Date -Format "yyyy-MM-dd HH:mm:ss"
$logEntry = "$timestamp [$Level] $Message"
Add-Content -Path $LogFile -Value $logEntry
Write-Output $logEntry
}
# =========================
# MAIN SCRIPT
# =========================
try {
Write-Log "=== Starting Oracle Java 21 JDK 64-bit Uninstall ==="
# Search registry for installed products
$UninstallKeys = @(
"HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall",
"HKLM:\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall"
)
$Found = $false
foreach ($KeyPath in $UninstallKeys) {
Get-ChildItem -Path $KeyPath -ErrorAction SilentlyContinue | ForEach-Object {
$DisplayName = (Get-ItemProperty -Path $_.PSPath -ErrorAction SilentlyContinue).DisplayName
$UninstallString = (Get-ItemProperty -Path $_.PSPath -ErrorAction SilentlyContinue).UninstallString
if ($DisplayName -and $DisplayName -like "*$ProductNamePattern*") {
Write-Log "Found: $DisplayName"
Write-Log "Uninstall command: $UninstallString"
if ($UninstallString) {
$Found = $true
# Handle MSI-based uninstall
if ($UninstallString -match "msiexec\.exe") {
$cmd = "$UninstallString $SilentArgs"
}
else {
# For EXE uninstallers, append silent flags if supported
$cmd = "$UninstallString /s"
}
Write-Log "Executing: $cmd"
$process = Start-Process -FilePath "cmd.exe" -ArgumentList "/c $cmd" -Wait -PassThru -WindowStyle Hidden
if ($process.ExitCode -eq 0) {
Write-Log "Uninstall successful for $DisplayName" "SUCCESS"
}
else {
Write-Log "Uninstall failed for $DisplayName with exit code $($process.ExitCode)" "ERROR"
}
}
}
}
}
if (-not $Found) {
Write-Log "No Oracle Java 21 JDK 64-bit installation found." "WARN"
}
Write-Log "=== Uninstall process completed ==="
}
catch {
Write-Log "Unexpected error: $_" "ERROR"
}