Use RestAPI to find servers that have JAVA installed

Oracle plan to change the way that Java is licenced. This will impose a requirement to survey estates for targets which are running Java. While a change request has been submitted to add reporting of Java version/edition in to iQSonar, as a temporary work around we can use the RestAPI to find scanned devices which report Java as part of their installed_applications.

The following PowerShell script is provided as is - the end user is expected to change the three variables at the top of the file to reflect their own iQSonar installation, and run the script in a PowerShell window on their iQSonar host.

Find Java
#
# We need to find devices which have Java installed on them
# 

# The RestAPI uses HTTP authentication. Set $user and $pass to the username and password needed for your iQSonar instance
# set the $host to the IPAddress, name or FQDN of the iQSonar server
$user    = "admin"
$pass    = "password"
$sonar	 = "Your iQSonar Host"

$secpass = ConvertTo-SecureString $pass -AsPlainText -Force
$credential = New-Object System.Management.Automation.PSCredential($user,$secpass)
 
#
# To find out how many devices there are, ask for the first device and look at the header for the device count
# offset=1 means start with first device. fetch_size=1 means only return one record.
$uri     = -join ("http://", $sonar, "/api/v1/devices/?offset=1&fetch_size=1")
$r = Invoke-WebRequest $uri -Credential $credential
 
# $r.headers has HTML headers, $r.content has text content
$deviceCount = $r.headers.'X-fetch-count'

$fs     = 100			# fetch_size - change this up or down depending on the size of your estate and how much RAM your server has.
$offset = 1				# offset
$seen   = 1;			# first offset is 1, not 0
while ( $seen -lt $devicecount)
{
	# Outer loop, grab a batch (defined by fetch_size) of devices
	$url = -join ("http://", $sonar, "/api/v1/devices/?offset=", $offset,  "&fetch_size=", $fs)
	$devices = Invoke-RestMethod $url -Credential $credential
	$i = 1
	while ($i -lt $devices.count)
	{
		# inner loop - process individual devices in this batch
		$GotJava = 0;
		$thisDevice = $devices[$i]
		$thisSoftware = -join($thisDevice.self, "/installed_software/")
		$currSoftware = Invoke-RestMethod $thisSoftware -Credential $credential
		if ($currSoftware.count -gt 0)
		{
			$j=0;
			$devOutput = -join( $thisDevice.host_name, $thisDevice.":")
			while ($j -lt $currSoftware.count)
			{
				$app = $currSoftware[$j];
				if ( ($app.name -like '*java*') -or
					 ($app.name -like '*jre*') -or
					 ($app.name -like '*jdk*') )
				{
					$devOutput = -join ($devOutput, "`r`n  ", $app.name)
					$GotJava = $GotJava + 1
				}
				$j = $j + 1
			}
		}
		if ($GotJava) 
		{
			write-host $devOutput
		}
		$i = $i + 1;		# keep track for inner loop
		$seen = $seen + 1;  # keep track for outer loop
	}
	# Finished this batch
	$offset = $seen
}