It used outside of whose clause - installing software

Hi,

I’m trying to target relevance to an app version less than ‘x’ and am receiving the following error. This works in other places.

Q: (exists key whose (value "DisplayName" of it as string contains "Poll Everywhere" (it < "3.0.1") of (value "DisplayVersion" of it as string as version))) of keys "HKLM\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall" of (x64 registries; x32 registries)
E: "It" used outside of "whose" clause.

What am I doing wrong?

I’m absolutely no relevance expert but reading the developers page it states

To ensure that it points toward an object, you must include of < object > after any statement involving it (but without whose).

I thought I did, “of keys”

Thanks

1 Like

Hi Jason - you’re simply missing an AND between “Poll Everywhere” and (it < “3.0.1”)

Hey Wilson! Thanks for responding. “Keys” aren’t defined.

Q:(not exists keys whose (value "DisplayName" of it as string contains "Poll Everywhere")) OR (exists keys whose (value "DisplayName" of it as string contains "Poll Everywhere" and (it < "3.0.1") of (value "DisplayVersion" of it as string as version))) of keys "HKLM\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall" of (x64 registries; x32 registries)
E: The operator "keys" is not defined.

I got this part to run, but it is wrong. The key does exist on my PC. Answer should be true.

Q: exists keys whose (value "DisplayName" of it as string contains "Poll Everywhere" AND (it < "3.0.1") of (value "DisplayVersion" of it as string as version)) of keys "HKLM\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall" of (x64 registries; x32 registries)
A: False

Do this:

not exists keys whose (value "DisplayName" of it as string contains "Poll Everywhere" AND (it >= "3.0.1") of (it as string as version) of value "DisplayVersion" of it) of keys "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall" of (x64 registries; x32 registries)

Relevance should be written to flow from right to left as much as possible.

For example, use (it as string) of -whatever- instead of -whatever- as string

If you want to write relevance to install/update something, then write the relevance to get the desired state, then put not in front. The desired state is that the version of the software or newer is already installed, so you check for that condition, then you put not such that is only true if the desired state is not present. There is only 1 desired state, but there are infinite undesired states. Generally this is the best way to write relevance in general. You have many relevance clauses that are prereqs like windows of operating system but then you have a relevance clause that checks for the desired state but with a NOT in front so that the applicability relevance is TRUE only if the desired state does not exist, then the action “fixes” things to go from an undesired state to the desired state. Then the relevance is reevaluated after the action to check to see that the relevance went from TRUE to FALSE. Part of the beauty of this is that BigFix doesn’t care if the desired state was achieved outside of the use of a BigFix action, like by manual intervention by IT Support, it is then able to report that the desired state exists by marking the fixlet no longer applicable. As long as the relevance is written correctly, then you can be confident that machines that are not applicable have the desired state and those that are applicable do not have the desired state. Nearly all automated configuration management operates on principles like this, checking that the desired state does not exist, running something to make it so, then checking that things are now correct.

So why mention all of that? I find it is easiest to write the relevance in the first place by taking a test machine, putting it in the desired state, then write the relevance such that it is TRUE only in that desired state. Then put the not in front so that it is only FALSE in that desired state. Then I change the system so that is no longer in the desired state and check that the relevance becomes TRUE. For this example, I do this by either uninstalling the application, or by just directly editing the registry value to a lower version temporarily, then put it back. You technically don’t even need to install the real application on the test machine to write the correct relevance if you export the registry keys from a system that does have it then import it into a test system that does not. I also will sometimes manually edit the registry value version to be higher than the version I’m trying to install to ensure that the relevance stays FALSE because there will always be a new version in the future and I don’t want to install an older version if a newer version is already installed.

This is also how I often write relevance for Linux using the Windows Fixlet Debugger. I get a copy of the file I need to parse with relevance from a Linux system, put it on my windows system, then write the relevance to parse the file correctly on Windows, then update the paths to point to the correct location on Linux instead of Windows, then put the relevance into an Analysis property to test the results on real Linux systems. Once I validate the results, I can then use it elsewhere in fixlet applicability or anywhere else I need. I generally do this for all relevance, start in QnA command line or Fixlet Debugger to test on a single system, then put it in an analysis property to test on many systems, validate the results, then put it wherever. Then clean up the analysis properties I no longer need.

keys of keys "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall" of (x64 registries; x32 registries)

This is the relevance form you should use as the base for almost all windows software.

This relevance gives you all of the keys of all of the programs that are installed system wide (not per-user) that appear in add/remove programs for all windows including both 64bit and 32bit. It isn’t obvious, but this includes results from the registry location HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall due to how Windows on Windows redirection works.

This is technically incorrect:

This would only successfully check for the 32bit software on 64bit windows. It would not check for 64bit software on 64bit windows and it would also not check for 32bit software on 32bit windows. The reason why is a bit complicated, but this helps demonstrate part of the problem:

Q: number of keys of keys "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall" of (x32 registries)
A: 93
T: 0.991 ms
I: singular integer

Q: number of keys of keys "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall" of (x64 registries)
A: 145
T: 1.500 ms
I: singular integer

Q: number of keys of keys "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall" of (x64 registries; x32 registries)
A: 238
T: 3.012 ms
I: singular integer

Q: number of keys of keys "HKLM\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall" of (x64 registries)
A: 93
T: 1.139 ms
I: singular integer

Q: number of keys of keys "HKLM\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall" of (x32 registries)
A: 93
T: 1.028 ms
I: singular integer

I can’t explain why Microsoft thought this was the best solution for implementing 64bit windows side by side with 32bit windows, but I wish I could listen in on the meetings when this was decided. See more here: WoW64 - Wikipedia


This is more of a blog post than a simple answer to the question. I’m teaching a relevance class today, so I’m just thinking this way.

Examples:

6 Likes

@jgstew James, this is a fantastic write up - thanks for taking the time to do so!

2 Likes

Indeed. Many thanks for your detailed and thorough explanation. Fantastic

1 Like

Suggested relevance from above is working as expected. Many thanks again @jgstew Sage advice.

1 Like