I’ve been tasked with finding the installed versions of Java throughout our environment. I already have a count of it through one of the reports but this analysis will be solely for Java. From the report that I generated I’ve seen that both 32 and 64 versions are present on some machines. I want my analysis to pick that up. Considering using regapps but it looks like they don’t show up there. Because the statement is pretty massive, I’ve pasted it here.
Currently the problem I run into is that it works on almost all Windows 7 systems but almost all Windows 2008R2 servers report “The operator “value” is not defined.” This was because I had the result displayed as a value then as a string so when I had my string values included there would be no errors. When I changed around the outputs to get it working on the broken servers, the error started happening on servers that were working.
The weird part is that the second “if” statement actually evaluates to false so it should skip the “then” statement and go right to the “else” but the error is an evaluation of the “then” statement as if it evaluated to “true”. I’m probably missing something easy here. Anyone want to take a look?
The error you are seeing is probably because “value” is being applied somewhere against the wrong type. A lot of these expressions I think can be shrunk into one. Just trying to figure out what your intent is?
My intent is to list the display name and the version of installed Java applications whether they be JRE, JDK, etc. When it works, the result looks like this:
The problem I was having was that I needed to look in both the x32 and x64 registries in order to be sure to grab all versions possible. I’ve updated the pastebin here.
I just split it into two statements that goes through x64 versions then goes to x32 versions.
So I did a QnA using your above method and it grabs both entries and causes a conflict with the relevance checking to see if the value exists.
Q:number of value "DisplayName" of keys whose (value "DisplayName" of it as string as lowercase contains "j2se runtime environment" OR value "DisplayName" of it as string as lowercase contains "runtimeenvironment" OR value "DisplayName" of it as string as lowercase starts with "java") of key "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall" of (x64 registry; x32 registry)
E: Singular expression refers to non-unique object.
I don’t know if, when installing Java 64-bit, it adds an entry for a 32-bit version as well but that seems to be what the registry is indicating. Either that or this PC I am using has both 32-bit and 64-bit versions of Java 7 Update 51.
(number of value “DisplayName” of keys whose (value “DisplayName” of it as string as lowercase contains “j2se runtime environment” OR value “DisplayName” of it as string as lowercase contains “runtimeenvironment” OR value “DisplayName” of it as string as lowercase starts with “java”) of key “HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall” of x32 registry) + (number of value “DisplayName” of keys whose (value “DisplayName” of it as string as lowercase contains “j2se runtime environment” OR value “DisplayName” of it as string as lowercase contains “runtimeenvironment” OR value “DisplayName” of it as string as lowercase starts with “java”) of key “HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall” of x64 registry)
That would work for the count. My QnA statement above was to try to determine why it wouldn’t display both. I believe it’s because the version number is the same in both registries thus it’s non-unique.
When I jump straight to the evaluation of the keys without checking they exist, I get the following result:
q:(values whose (name of it is "DisplayName") of keys whose (value "DisplayName" of it as string as lowercase contains "j2se runtime environment" OR value "DisplayName" of it as string as lowercase contains "runtimeenvironment" OR value "DisplayName" of it as string as lowercase starts with "java") of key "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall" of (x64 registry; x32 registry) , values whose (name of it is "DisplayVersion") of keys whose (value "DisplayName" of it as string as lowercase contains "j2se runtime environment" OR value "DisplayName" of it as string as lowercase contains "runtimeenvironment" OR value "DisplayName" of it as string as lowercase starts with "java") of key "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall" of (x64 registry; x32 registry))
A: Java 7 Update 51 (64-bit), 7.0.510
E: Singular expression refers to non-unique object.
So it found the 64-bit version but considers the other non-unique because they are the same version I think?
We don’t have many 32-bit systems but there are 32-bit versions of Java along side our 64-bit Java installs. I’m looking to make an analysis that grabs both in one go. I was hoping not to have to make it two separate analysis but it’s looking that way to get the desired results.
Here is what I got after swapping out the above relevance.
Q: (values whose (name of it is "DisplayName") of keys whose (value "DisplayName" of it as string as lowercase contains "j2se runtime environment" OR value "DisplayName" of it as string as lowercase contains "runtimeenvironment" OR value "DisplayName" of it as string as lowercase starts with "java") of (keys of key "HKLM\Software" of it) of (native registry; x32 registry) , values whose (name of it is "DisplayVersion") of keys whose (value "DisplayName" of it as string as lowercase contains "j2se runtime environment" OR value "DisplayName" of it as string as lowercase contains "runtimeenvironment" OR value "DisplayName" of it as string as lowercase starts with "java") of (keys of key "HKLM\Software" of it) of (native registry; x32 registry))
T: 121.603 ms
I think there are a couple of potential issues with the relevance above. One is that it appears to be a tuple of two identical relevance clauses. I’m guessing the intention was to leverage ; (instead of ,) in order to join to result sets (i.e. 64-bit registry and 32-bit registry). Also, the ‘keys of key’ isn’t going ‘deep enough’ into the registry for the Uninstalls.
I found this sample that I believe should meet your requirements:
unique values of ((concatenation of (If (exist value “DisplayName” of it) then (concatenation of substrings separated by “,” of (value “DisplayName” of it as string)) else “no-value”)) of keys whose (((it contains “java” OR it contains “j2se”) AND ((it contains “runtime environment” OR it contains “update”))) of (value “DisplayName” of it as string as lowercase)) of keys “HKLM\Software\Microsoft\Windows\CurrentVersion\Uninstall” of (if x64 of operating system then (x32 registry; x64 registry) else registry))
Sorry the code I posted does not go deep enough to get the uninstall keys as Aram points out. My code was an example of how to examine both registries with a single statement, but it did not properly get the uninstall keys.
This is a bit simpler. It does not check for “runtime” or “update” in the DisplayName, but that could be added:
unique values of ( value “DisplayName” of it as string as trimmed string & ", " & value “DisplayVersion” of it as string as trimmed string) of keys whose(exists (value “DisplayName” of it as string as trimmed string as lowercase) whose(it contains “j2se” OR it starts with “java”) AND exists (value “DisplayVersion” of it) ) of keys “HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall” of (native registry; x32 registry)
This will work on both 32bit systems & 64bit systems, and it will check both registries on 64bit systems. It will actually report each item twice on a 32bit system, but that will be eliminated by the “unique values” in the beginning of the statement.
Maybe this is what is desired:
unique values of ( value “DisplayName” of it as string as trimmed string & ", " & value “DisplayVersion” of it as string as trimmed string) of keys whose(exists (value “DisplayName” of it as string as trimmed string as lowercase) whose(it contains “j2se” OR it starts with “java” OR it contains “runtimeenvironment”) AND exists (value “DisplayVersion” of it) ) of keys “HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall” of (native registry; x32 registry)
The above relevance I provided is based upon the same relevance I use when creating a Fixlet/Task to install a piece of software.
So in many cases when creating a Fixlet/Task that installs a piece of software, I don’t actually need to care if it is a 32bit program or a 64bit program, only that it is not already installed. In that case I will add the following relevance:
not exists keys whose( exists (value “DisplayName” of it as string as trimmed string as lowercase) whose(it contains “name of software”) ) of keys “HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall” of (native registry; x32 registry)
This is not what I would do typically, because when I create Fixlets/Tasks to install software, I also want them to upgrade any older versions of the software that might be installed. In that case I also check the DisplayVersion, like this:
not exists keys whose( exists (value “DisplayName” of it as string as trimmed string as lowercase) whose(it contains “name of software”) AND value “DisplayVersion” of it as string as version >= “9.9.9.9” ) of keys “HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall” of (native registry; x32 registry)
What is nice about this relevance is that it it can be used on both 64bit and 32bit systems, and it can be used with slight variations to ensure the existence or nonexistence of the software, as well as to report which version is installed. This also wraps the logic up into a single statement, instead of having 2 separate statements, one checking if the software is installed, and another checking if the version is older than the version being installed.
Example: not exists keys whose(exists (value “DisplayName” of it as string as lowercase) whose(it contains “Command | Monitor” as lowercase OR it contains “OpenManage Client Instrumentation” as lowercase) AND exists (value “Publisher” of it as string as lowercase) whose(it contains “dell” as lowercase) AND exists (value “DisplayVersion” of it as string as version) whose(it >= “8.2.1.70”) ) of keys “HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall” of (native registry;x32 registry)
Java is actually one of the only exceptions to the above relevance when installing (though not for reporting both, like was desired). The reason is that it is common to install BOTH the 64bit version of Java AND the 32bit version of Java on a 64bit machine. This means the task that installs the 32bit version of Java should only check the 32bit registry to see if Java already exists. The task that installs the 64bit version of Java should exclude 32bit machines and should only check the 64bit registry for Java.