I don’t have a full solution but there’s a few things to note here.
-
Never, never use ‘descendant folders’. Just don’t do it.
– Scanning the entire drive in Relevance using the ‘descendant folders’ inspector is extremely slow, and can lock up the client / make it stop responding to Actions or posting reports.
-
Never, ever execute the found files to retrieve the runtime details. If you scan for every java.exe on the system, it will include any java.exe that a user placed in their home directory or TEMP folder. That may be a real Java runtime, or it may be any other program masquerading as Java but really does something totally different. If you execute it in an Action, you’re running as LocalSystem so this gives an avenue to escalate privileges and compromise the system.
File Scan:
Instead, use an Action to run a probe on the machine. I have a pretty complex example we can reuse at https://bigfix.me/fixlet/details/26932 which scans for Spring Boot Framework, where several different filenames can be matched. In your Probe action it could be simplified to something like
action uses wow64 redirection false
parameter "output"="c:\temp\output.txt"
delete "{parameter "output"}"
delete __appendfile
appendfile {concatenation "%0d%0a" of ("for /F %22tokens=*%22 %25%25i in ('dir /s /b " & it & "\ ^| findstr /R /C:%22\\java\.exe$%22') do @echo %25%25~dpnxi>>%22" & (parameter "output") & "%22") of pathnames of root folders of drives whose (type of it = "DRIVE_FIXED")}
delete run_scan.cmd
move __appendfile run_scan.cmd
waithidden cmd.exe /c run_scan.cmd
This builds a batch file that should have content like
for /F "tokens=*" %%i in ('dir /s /b C:\ ^| findstr /R /C:"\\java\.exe$"') do @echo %%~dpnxi>>"output.txt"
After it executes the output file should have one line for each java.exe path, it’ll look like
C:\temp\OpenJDK11U-jre_x64_windows_hotspot_11.0.13_8\jdk-11.0.13+8-jre\bin\java.exe
C:\temp\OpenJDK8U-jre_x64_windows_hotspot_8u312b07\jdk8u312-b07-jre\bin\java.exe
Next up, for each Java instance you want to retrieve some properties. We can pull properties from those files by reading the lines of the output.txt file like
q: (pathname of it, size of it, sha1 of it) of files (lines of file "c:\temp\output.txt" as trimmed string)
A: C:\temp\OpenJDK11U-jre_x64_windows_hotspot_11.0.13_8\jdk-11.0.13+8-jre\bin\java.exe, 47824, bfa032a99dc13a7f01eae929beb35fd5b46dccc9
A: C:\temp\OpenJDK8U-jre_x64_windows_hotspot_8u312b07\jdk8u312-b07-jre\bin\java.exe, 224464, f1135ef9eeb7393222beb631ca2491485461055a
From the filesystem object it’s easy (on Windows) to retrieve things like “version” or size or sha1. For more details we can inspect the ‘version control blocks’ of the file. Those are what show up in the ‘Details’ view of the file:
But to retrieve values, we have to know the names. There’s a reference at VERSIONINFO resource - Win32 apps | Microsoft Learn that tells us we can retrieve
Name |
Description |
Comments |
Additional information that should be displayed for diagnostic purposes. |
CompanyName |
Company that produced the file—for example, Microsoft Corporation or Standard Microsystems Corporation, Inc. This string is required. |
FileDescription |
File description to be presented to users. This string may be displayed in a list box when the user is choosing files to install—for example, Keyboard Driver for AT-Style Keyboards. This string is required. |
FileVersion |
Version number of the file—for example, 3.10 or 5.00.RC2. This string is required. |
InternalName |
Internal name of the file, if one exists—for example, a module name if the file is a dynamic-link library. If the file has no internal name, this string should be the original filename, without extension. This string is required. |
LegalCopyright |
Copyright notices that apply to the file. This should include the full text of all notices, legal symbols, copyright dates, and so on. This string is optional. |
LegalTrademarks |
Trademarks and registered trademarks that apply to the file. This should include the full text of all notices, legal symbols, trademark numbers, and so on. This string is optional. |
OriginalFilename |
Original name of the file, not including a path. This information enables an application to determine whether a file has been renamed by a user. The format of the name depends on the file system for which the file was created. This string is required. |
PrivateBuild |
Information about a private version of the file—for example, Built by TESTER1 on \TESTBED. This string should be present only if VS_FF_PRIVATEBUILD is specified in the fileflags parameter of the root block. |
ProductName |
Name of the product with which the file is distributed. This string is required. |
ProductVersion |
Version of the product with which the file is distributed—for example, 3.10 or 5.00.RC2. This string is required. |
SpecialBuild |
Text that specifies how this version of the file differs from the standard version—for example, Private build for TESTER1 solving mouse problems on M250 and M250E computers. This string should be present only if VS_FF_SPECIALBUILD is specified in the fileflags parameter of the root block. |
Knowing this list we can do things like
q: (pathname of it, value "Comments" of version blocks of it | "No Comment", value "CompanyName" of version blocks of it | "No Company", value "FileDescription" of version blocks of it | "No FileDescription") of files (lines of file "c:\temp\output.txt" as trimmed string)
A: C:\temp\OpenJDK11U-jre_x64_windows_hotspot_11.0.13_8\jdk-11.0.13+8-jre\bin\java.exe, No Comment, Eclipse Adoptium, OpenJDK Platform binary
A: C:\temp\OpenJDK8U-jre_x64_windows_hotspot_8u312b07\jdk8u312-b07-jre\bin\java.exe, No Comment, Temurin, OpenJDK Platform binary
This doesn’t give all the details you’re looking for in exactly the format you’re asking, the format produced by executing ‘java --version’, but it’s much safer than executing every random .EXE you find on the machine. To find more details you may have to look in a lot more places - like parsing lines of file "RELEASE" of parent folder of it
, or registry entries, or other files in directories relative to the java.exe to find what kind of jvm it runs…
(or, you could deploy BigFix Inventory and get most of this out-of-the-box)