MyITGuy
3/22/2014 - 2:36 PM

Java Control Panel Applet Utility

Java Control Panel Applet Utility

<#
    .SYNOPSIS 
	Add and remove Java Control Panel applet entries in the Windows Control Panel.
    .DESCRIPTION
	The JavaCPL function collects control panel applet information from the registry. It uses this information to analyze currently visible entries and their status. Based on this information entries can be removed, added or modified.
    .PARAMETER Add
	Add available Java Control Panel applets to the Windows Control Panel. Existing Java Control Panel applets will not be affected.
    .PARAMETER Remove
	Remove Java Control Panel applets that are not installed from the Windows Control Panel. Available Java Control Panel applets will remain.
    .PARAMETER All
	Used with the Remove parameter; Remove all Java Control Panel applets, available and unavailable, from the Windows Control Panel.
    .PARAMETER Reset
	Remove all Java Control Panel applets from, then add all available Java Control Panel applets to, the Windows Control Panel.
	.EXAMPLE
	javacpl.ps1 -Verbose
	View Java and Windows Control Panel information verbose logging.
	.EXAMPLE
	javacpl.ps1 -Remove -Verbose
	Removes Java Control Panel applets from the Windows Control Panel that are not installed with verbose logging.
	.EXAMPLE
	javacpl.ps1 -Remove -All -Verbose
	Removes all known Java Control Panel applets from the Windows Control Panel with verbose logging.
	.EXAMPLE
	javacpl.ps1 -Add -Verbose
	Adds Java Control Panel applets to the Windows Control Panel that are installed, but not available, with verbose logging.
	.EXAMPLE
	javacpl.ps1 -Reset -Verbose
	Performs a '-Remove -All' then a  Java Control Panel applets from the Windows Control Panel with verbose logging.
    .INPUTS
    .OUTPUTS
    .NOTES
		The validation of Java Control Panel applets consists of 3 areas:
		
		NotInstalled: The Java Control Panel exists in the registry, but not on the file system.
		NotAvailable: The Java Control Panel exists in the registry and file system, but not in the Windows Control Panel.
		Available   : The Java Control Panel exists in the registry, file system and Windows Control Panel.
	.LINK
  #>
[CmdletBinding(SupportsShouldProcess=$True,DefaultParameterSetName="None")]
param (
	[Parameter(ParameterSetName="Add",Mandatory=$false)]
	[switch]$Add,
	[Parameter(ParameterSetName="Remove",Mandatory=$false)]
	[switch]$Remove,
	[Parameter(ParameterSetName="Remove",Mandatory=$false)]
	[switch]$All,
	[Parameter(ParameterSetName="Reset",Mandatory=$false)]
	[switch]$Reset
)
# Validation of parameters
if (($All) -and !($Remove)) {
	Write-Host "All parameter without Remove parameter prohibited." -ForegroundColor Yellow
	return
}

# Add, Remove and Reset require Adminsitrator role
if (($Remove) -or ($Add) -or ($Reset)) {
	$CurrentWindowsIdentity = [System.Security.Principal.WindowsIdentity]::GetCurrent()
	$CurrentWindowsPrincipal = New-Object System.Security.Principal.WindowsPrincipal($CurrentWindowsIdentity)
	$IsAdministratorWindowsBuiltInRole = $CurrentWindowsPrincipal.IsInRole([System.Security.Principal.WindowsBuiltInRole]::Administrator)
	if ($IsAdministratorWindowsBuiltInRole -eq $false) {
		Write-Host "Access is denied. The requested operation requires elevation." -ForegroundColor Red
		exit 0x000002E4
	}
}

$ParamSetName = $PsCmdLet.ParameterSetName
Write-Verbose "ParamSetName: $ParamSetName"

function Get-FileVersion {
	param(
		[string]$FilePath
	)
	$FilePath = $FilePath.Replace('"','')
	if ((Test-Path -Path $FilePath -PathType Leaf) -eq $true) {
		[System.Diagnostics.FileVersionInfo]::GetVersionInfo($FilePath).FileVersion
	}
}

function Get-ProductVersion {
	param(
		[string]$FilePath
	)
	$FilePath = $FilePath.Replace('"','')
	if ((Test-Path -Path $FilePath -PathType Leaf) -eq $true) {
		[System.Diagnostics.FileVersionInfo]::GetVersionInfo($FilePath).ProductVersion
	}
}

$OutputObjects = New-Object -TypeName PSObject
$OutputObjects = @()

function Add-OutputObject {
	param (
		[string]$ControlPanelName,
		[string]$ControlPanelPath,
		[string]$CLSIDPath,
		[string]$CLSID,
		[string]$CLSIDName,
		[string]$InfoTip,
		[string]$SystemControlPanelCategory,
		[string]$DefaultIcon,
		[string]$Command,
		[string]$JavaVersion,
		[string]$JavaVersionFriendlyName,
		[string]$Status
	)
	$OutputObject = New-Object -TypeName PSObject -Property @{
		ControlPanelName = $ControlPanelName
		ControlPanelPath = $ControlPanelPath
		CLSIDPath = $CLSIDPath
		CLSID = $CLSID
		CLSIDName = $CLSIDName
		InfoTip = $InfoTip
		SystemControlPanelCategory = $SystemControlPanelCategory
		DefaultIcon = $DefaultIcon
		Command = $Command
		JavaVersion = $JavaVersion
		JavaVersionFriendlyName = $JavaVersionFriendlyName
		Status = $Status
	};
	$script:OutputObjects += $OutputObject
}

function Remove-Applet {
	param (
		$Applet,
		$Verbose = $PSBoundParameters['Verbose']
	)
	try {
		Remove-Item -Path "$($Applet.ControlPanelPath)" -Recurse -ErrorAction SilentlyContinue | Out-Null
		Remove-Item -Path "$($Applet.CLSIDPath)" -Recurse -ErrorAction SilentlyContinue | Out-Null
	} catch {}
	if (((Test-Path -Path "$($Applet.ControlPanelPath)") -eq $false) -and ((Test-Path -Path "$($Applet.CLSIDPath)") -eq $false)) {
		if ($Verbose) {Write-Host "VERBOSE: Removed $($Applet.ControlPanelName)" -ForegroundColor Green}
		return $true
	} else {
		if ($Verbose) {Write-Host "VERBOSE: Could not remove: $($Applet.ControlPanelName)" -ForegroundColor Red}
		return $false
	}
}

function Add-Applet {
	param (
		$Applet,
		$Verbose = $PSBoundParameters['Verbose']
	)
	try {
		New-Item -Path "$($Applet.ControlPanelPath)" -Value "$($Applet.JavaVersionFriendlyName)" -ErrorAction SilentlyContinue | Out-Null
		New-Item -Path "$($Applet.CLSIDPath)" -Value "$($Applet.JavaVersionFriendlyName)" -ErrorAction SilentlyContinue | Out-Null
		Set-ItemProperty -Path "$($Applet.CLSIDPath)" -Name "InfoTip" -Value "$($Applet.InfoTip)" -ErrorAction SilentlyContinue | Out-Null
		Set-ItemProperty -Path "$($Applet.CLSIDPath)" -Name "System.ControlPanel.Category" -Value "$($Applet.SystemControlPanelCategory)" -ErrorAction SilentlyContinue | Out-Null
		New-Item -Path "$($Applet.CLSIDPath)\DefaultIcon" -Value "$($Applet.DefaultIcon)" -ErrorAction SilentlyContinue | Out-Null
		New-Item -Path "$($Applet.CLSIDPath)\Shell\Open\Command" -Value "$($Applet.Command)" -Force -ErrorAction SilentlyContinue | Out-Null
	} catch {}
	if (((Test-Path -Path "$($Applet.ControlPanelPath)") -eq $true) -and ((Test-Path -Path "$($Applet.CLSIDPath)") -eq $true)) {
		if ($Verbose) {Write-Host "VERBOSE: Added $($Applet.ControlPanelName)" -ForegroundColor Green}
		return $true
	} else {
		if ($Verbose) {Write-Host "VERBOSE: Could not add: $($Applet.ControlPanelName)" -ForegroundColor Red}
		return $false
	}
}

# Create object for entries
$CLSIDs = @()
# Get 64-bit entries
$CLSIDs += (Get-ChildItem -Path "Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\ControlPanel\NameSpace" -ErrorAction SilentlyContinue | ? {$_.PSChildName -match("^(\{){0,1}[0-9a-fA-F]{8}\-[0-9a-fA-F]{4}\-[0-9a-fA-F]{4}\-[0-9a-fA-F]{4}\-[0-9a-fA-F]{12}(\}){0,1}$")} | Select @{Name="CLSID";Expression={$_.PSChildName}},@{Name="ControlPanelPath";Expression={$_.PSPath}})
# Add 32-bit entries
$CLSIDs += (Get-ChildItem -Path "Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Explorer\ControlPanel\NameSpace" -ErrorAction SilentlyContinue | ? {($_.PSChildName -match("^(\{){0,1}[0-9a-fA-F]{8}\-[0-9a-fA-F]{4}\-[0-9a-fA-F]{4}\-[0-9a-fA-F]{4}\-[0-9a-fA-F]{12}(\}){0,1}$") -eq $true) -and (($CLSIDs | Select CLSID) -notmatch $_.PSChildName)} | Select @{Name="CLSID";Expression={$_.PSChildName}},@{Name="ControlPanelPath";Expression={$_.PSPath}})
$CLSIDs += (Get-ChildItem -Path "Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Explorer\ControlPanelWOW64\NameSpace" -ErrorAction SilentlyContinue | ? {($_.PSChildName -match("^(\{){0,1}[0-9a-fA-F]{8}\-[0-9a-fA-F]{4}\-[0-9a-fA-F]{4}\-[0-9a-fA-F]{4}\-[0-9a-fA-F]{12}(\}){0,1}$") -eq $true) -and (($CLSIDs | Select CLSID) -notmatch $_.PSChildName)} | Select @{Name="CLSID";Expression={$_.PSChildName}},@{Name="ControlPanelPath";Expression={$_.PSPath}})
$CLSIDs = $CLSIDs | Sort-Object -Property CLSID -Unique
if ($PSBoundParameters['Verbose']) {Write-Verbose "Discoverd Control Panel Applets:`t`t`t`t`t`t`t$(($CLSIDs | Measure).Count)"}

foreach ($CLSID In $CLSIDs) {	
	$CLSIDPath = "Microsoft.PowerShell.Core\Registry::HKEY_CLASSES_ROOT\CLSID\$($CLSID.CLSID)"
	$Path = "$($CLSIDPath)\Shell\Open\Command"
	$Status = "NotInstalled"
	if ((Test-Path -Path $Path) -eq $false) {
		$CLSIDPath = "Microsoft.PowerShell.Core\Registry::HKEY_CLASSES_ROOT\Wow6432Node\CLSID\$($CLSID.CLSID)"
		$Path = "$($CLSIDPath)\Shell\Open\Command"
	}
	if ((Test-Path -Path $Path) -eq $true) {
		$Command = (Get-ItemProperty -Path $Path -Name "" -ErrorAction SilentlyContinue | Where-Object {($_."(default)").Replace('"','').ToLower().EndsWith("javacpl.exe") -eq $true} | Select -ExpandProperty "(default)")
	}

	if ($Command) {
		$JavaVersion = Get-ProductVersion -FilePath $Command
		if ($JavaVersion) {
			$JavaVersionFriendlyName = "Java $($JavaVersion.Split('.')[0]) Update $(($JavaVersion.Split('.')[2]).TrimEnd('0'))"
			$Status = "NotAvailable"
		}
		$ControlPanelPath = $CLSID.ControlPanelPath
		$ControlPanelName = (Get-ItemProperty -Path $ControlPanelPath -Name "" -ErrorAction SilentlyContinue | Select -ExpandProperty "(default)")
		$CLSIDName = (Get-ItemProperty -Path $CLSIDPath -Name "" -ErrorAction SilentlyContinue | Select -ExpandProperty "(default)")
		$InfoTip = (Get-ItemProperty -Path $CLSIDPath -Name "InfoTip" -ErrorAction SilentlyContinue | Select -ExpandProperty "InfoTip")
		$SystemControlPanelCategory = (Get-ItemProperty -Path $CLSIDPath -Name "System.ControlPanel.Category" -ErrorAction SilentlyContinue | Select -ExpandProperty "System.ControlPanel.Category")
		$Path = "$($CLSIDPath)\DefaultIcon"
		if ((Test-Path -Path $Path) -eq $true) {
			$DefaultIcon = (Get-ItemProperty -Path $Path -Name "" -ErrorAction SilentlyContinue | Select -ExpandProperty "(default)")
		}
		Add-OutputObject -ControlPanelName $ControlPanelName -ControlPanelPath $ControlPanelPath -CLSIDPath $CLSIDPath -CLSID "$($CLSID.CLSID)" -CLSIDName $CLSIDName -InfoTip $InfoTip -SystemControlPanelCategory $SystemControlPanelCategory -DefaultIcon $DefaultIcon -Command $Command -JavaVersion $JavaVersion -JavaVersionFriendlyName $JavaVersionFriendlyName -Status $Status
	}
	Clear-Variable CLSID -ErrorAction SilentlyContinue
	Clear-Variable Path -ErrorAction SilentlyContinue
	Clear-Variable ControlPanelPath -ErrorAction SilentlyContinue
	Clear-Variable ControlPanelName -ErrorAction SilentlyContinue
	Clear-Variable CLSIDPath -ErrorAction SilentlyContinue
	Clear-Variable CLSIDName -ErrorAction SilentlyContinue
	Clear-Variable InfoTip -ErrorAction SilentlyContinue
	Clear-Variable SystemControlPanelCategory -ErrorAction SilentlyContinue
	Clear-Variable DefaultIcon -ErrorAction SilentlyContinue
	Clear-Variable Command -ErrorAction SilentlyContinue
}

# Java Control Panel applet locations from registry
$DiscoverdCPLs = @()
if ([IntPtr]::Size -eq 8) {
	# 64-bit OS
	$DiscoverdCPLs += (Get-ChildItem -Path "Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SOFTWARE\JavaSoft\Java Runtime Environment" -ErrorAction SilentlyContinue | % {Get-ItemProperty -Path $_.PSPath -Name JavaHome -ErrorAction SilentlyContinue} | Select @{Name="JavaCplFile";Expression={"$($_.JavaHome)\bin\javacpl.exe"}},@{Name="Version";Expression={$_.PSChildName}},@{Name="Architecture";Expression={[int]64}} | Sort JavaCplFile -Unique)
	$DiscoverdCPLs += (Get-ChildItem -Path "Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\JavaSoft\Java Runtime Environment" -ErrorAction SilentlyContinue | % {Get-ItemProperty -Path $_.PSPath -Name JavaHome -ErrorAction SilentlyContinue} | Select @{Name="JavaCplFile";Expression={"$($_.JavaHome)\bin\javacpl.exe"}},@{Name="Version";Expression={$_.PSChildName}},@{Name="Architecture";Expression={[int]32}} | Sort JavaCplFile -Unique)
} elseif ([IntPtr]::Size -eq 4) {
	# 32-bit OS
	$DiscoverdCPLs += (Get-ChildItem -Path "Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SOFTWARE\JavaSoft\Java Runtime Environment" -ErrorAction SilentlyContinue | % {Get-ItemProperty -Path $_.PSPath -Name JavaHome -ErrorAction SilentlyContinue} | Select @{Name="JavaCplFile";Expression={"$($_.JavaHome)\bin\javacpl.exe"}},@{Name="Version";Expression={$_.PSChildName}},@{Name="Architecture";Expression={[int]32}} | Sort JavaCplFile -Unique)
}
$DiscoverdCPLs = $DiscoverdCPLs | Sort-Object -Property JavaCplFile -Unique | ? {(Test-Path -Path "$($_.JavaCplFile)" -PathType Leaf) -eq $true}

foreach ($DiscoverdCPL In $DiscoverdCPLs) {
	$Command = ($DiscoverdCPL.JavaCplFile)
	$JavaVersion = Get-ProductVersion -FilePath $Command
	$Status = "NotInstalled"
	if ($JavaVersion) {
		$MajorVersion = [int]$JavaVersion.Split('.')[0]
		$UpdateVersion = [int]$DiscoverdCPL.Version.Split('_')[1]
		if ($UpdateVersion -ne 0) {
			$JavaVersionFriendlyName = "Java $($MajorVersion) Update $($UpdateVersion)"
		} else {
			$JavaVersionFriendlyName = "Java $($MajorVersion)"
		}
		$Status = "NotAvailable"
	}
	$CommandEscaped = [regex]::escape($Command)
	$Commands = ($OutputObjects | Select Command)
	if ($Commands -match $CommandEscaped) {
		foreach ($OutputObject In $OutputObjects) {
			if ($OutputObject.Command.Replace('"','') -eq $Command) {
				$OutputObject.JavaVersionFriendlyName = $JavaVersionFriendlyName
				$OutputObject.Status = "Available"
			}
		}
	} else {
		$CLSID = "{$([guid]::NewGuid().ToString().ToUpper())}"
		if (([IntPtr]::Size -eq 8) -and ($DiscoverdCPL.Architecture -eq 64)) {
			# 64-bit OS/64-bit App
			$CLSIDPath = "Microsoft.PowerShell.Core\Registry::HKEY_CLASSES_ROOT\CLSID\$($CLSID)"
			$ControlPanelPath = "Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\ControlPanel\NameSpace\$($CLSID)"
		} elseif (([IntPtr]::Size -eq 8) -and ($DiscoverdCPL.Architecture -eq 32)) {
			# 64-bit OS/32-bit App
			$CLSIDPath = "Microsoft.PowerShell.Core\Registry::HKEY_CLASSES_ROOT\Wow6432Node\CLSID\$($CLSID)"
			$ControlPanelPath = "Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Explorer\ControlPanelWOW64\NameSpace\$($CLSID)"
		} elseif (([IntPtr]::Size -eq 4) -and ($DiscoverdCPL.Architecture -eq 32)) {
			# 32-bit OS/32-bit App
			$CLSIDPath = "Microsoft.PowerShell.Core\Registry::HKEY_CLASSES_ROOT\CLSID\$($CLSID)"
			$ControlPanelPath = "Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\ControlPanel\NameSpace\$($CLSID)"
		}

		Add-OutputObject -ControlPanelName $JavaVersionFriendlyName -ControlPanelPath $ControlPanelPath -CLSIDPath $CLSIDPath -CLSID $CLSID -CLSIDName $JavaVersionFriendlyName -InfoTip "@$($Command),-2" -SystemControlPanelCategory 8 -DefaultIcon $Command -Command $Command -JavaVersion $JavaVersion -JavaVersionFriendlyName $JavaVersionFriendlyName -Status $Status
	}
}
$OutputObjects = $OutputObjects | Sort JavaVersionFriendlyname

"Java Control Panel Applets (Total):`t`t$(($OutputObjects | Measure).Count)"

$NotInstalledJavaCPLApplets = $OutputObjects | Where {$_.Status -eq "NotInstalled"}
$Count = ($NotInstalledJavaCPLApplets | Measure).Count
"Java Control Panel Applets (NotInstalled):`t$($Count)"
if (($PSBoundParameters['Verbose']) -and ($Count)) {$NotInstalledJavaCPLApplets.JavaVersionFriendlyName | % {Write-Verbose "NotInstalled: $($_)"}}

$NotAvailableJavaCPLApplets = $OutputObjects | Where {$_.Status -eq "NotAvailable"}
$Count = ($NotAvailableJavaCPLApplets | Measure).Count
"Java Control Panel Applets (NotAvailable):`t$($Count)"
if (($PSBoundParameters['Verbose']) -and ($Count)) {$NotAvailableJavaCPLApplets.JavaVersionFriendlyName | % {Write-Verbose "NotAvailable: $($_)"}}

$AvailableJavaCPLApplets = $OutputObjects | Where {$_.Status -eq "Available"}
$Count = ($AvailableJavaCPLApplets | Measure).Count
"Java Control Panel Applets (Available):`t`t$($Count)"
if (($PSBoundParameters['Verbose']) -and ($Count)) {$AvailableJavaCPLApplets.JavaVersionFriendlyName | % {Write-Verbose "Available: $($_)"}}

#Remove Java Control Panel Applets
$Applets = @()
if ($Remove) {$Applets = $NotInstalledJavaCPLApplets}
if (($All) -or ($Reset)) {$Applets = $OutputObjects}
if (($Reset) -or ($Remove)) {
	$Count = 0
	$AppletCount = ($Applets | Measure).Count
	"Java Control Panel Applets (Remove):`t`t$($AppletCount)"
	if ($AppletCount -gt 0) {
		foreach ($Applet In $Applets) {
			if ((Remove-Applet -Applet $Applet) -eq $true) {$Count += 1}
		}
	}
	"Java Control Panel Applets (Removed):`t`t$($Count)"
}

#Add Java Control Panel Applets
$Applets = @()
if (($Reset) -or ($Add)) {$Applets = $NotAvailableJavaCPLApplets}
if ($Reset) {$Applets += $AvailableJavaCPLApplets}
if (($Reset) -or ($Add)) {
	$Count = 0
	$AppletCount = ($Applets | Measure).Count
	"Java Control Panel Applets (Add):`t`t$($AppletCount)"
	if ($AppletCount -gt 0) {
		foreach ($Applet In $Applets) {
			if ((Add-Applet -Applet $Applet) -eq $true) {$Count += 1}
		}
	}
	"Java Control Panel Applets (Added):`t`t$($Count)"
}