We have a software package, lets call it “Nachos” and installing new versions of the software does not uninstall the previous versions.
I can manually create a fixlet or fixlets that will uninstall old versions; but what I want to accomplish is to look at the version numbers in the registry (or on the files themselves) and identify the largest version number and uninstall all of the other versions.
I created an analysis that shows me all of the currently installed versions:
concatenation ", " of ((it as string) of values "DisplayVersion" of keys whose (value "DisplayName" of it as string contains "Nachos") of key "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall" of native registry)
The install folders contain part of the version number. As an example:
C:\Program Files\Nachos\Nachos Application 9.2\Folder\nachos.exe
C:\Program Files\Nachos\Nachos Application 9.8\Folder\nachos.exe
C:\Program Files\Nachos\Nachos Application 10.1\Folder\nachos.exe
Might exist on a machine together.
I’d like to create a fixlet that will look at all of the versions and uninstall any thing that is not the maximum version currently installed.
I can also get the version of file by running the relevance:
versions of files "bin\nachos.exe" of folders of folders "c:\Program Files\Nachos"
I cannot figure out the relevance to show me the maximum of those though. Once I have that, I believe I can do a for each and accomplish the uninstall routines.
There are already examples of this with the uninstall multiple versions of Java Fixlets in the IBM patch sites. (though I’m sure the relevance could be better in those examples) This is exactly what they do.
Good call on that (I knew a little crowd sourcing would kick my brain into gear! The Java fixlet was exactly what I needed.
delete __appendfile
appendfile @ECHO OFF
appendfile {concatenation "%0d%0a" of ("start /w msiexec /x" & name of it & " /qn REBOOT=ReallySuppress") of keys whose ((value "DisplayName" of it as string as lowercase contains "nachos" as lowercase) AND (numeric value of concatenation of (if length of it = 1 then "000" & it else if length of it = 2 then "00" & it else if length of it = 3 then "0" & it else it) of substrings separated by "_" of substrings separated by "." of ((pad of (value "DisplayVersion" of it as string as version)) as string)) < (maximum of (numeric values of concatenation of (if length of it = 1 then "000" & it else if length of it = 2 then "00" & it else if length of it = 3 then "0" & it else it) of substrings separated by "_" of substrings separated by "." of ((pad of (value "DisplayVersion" of it as string as version)) as string)) of keys whose ((it contains "nachos") of (value "DisplayName" of it as string as lowercase)) of key "HKLM\Software\Microsoft\Windows\CurrentVersion\Uninstall" of native registry)) of key "HKLM\Software\Microsoft\Windows\CurrentVersion\Uninstall" of native registry}
delete uninstallJRE.bat
copy __appendfile uninstallNachos.bat
wait "{pathname of client folder of site "BESSupport"}\RunQuiet.exe" uninstallNachos.bat
action may require restart
and relevance:
(it > 1) of number of keys whose (value "DisplayName" of it as string as lowercase contains "nachos") of key "HKLM\Software\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall" of native registry
This relevance is technically incorrect. It should be more like:
(it > 1) of number of keys whose (value "DisplayName" of it as string as lowercase contains "nachos") of keys "HKLM\Software\Microsoft\Windows\CurrentVersion\Uninstall" of (x64 registries; x32 registries)
The way you have it written, it would never work on a 32bit system, but would work on a 64bit system in most cases.
I’m sure you got this directly from the Java fixlet, but I think this relevance could be so much better.
Interestingly enough, changing from native reigistry to the x64/x32 registries command results in the relevance not working. The app actually stores addtional keys in the WOW6432Node under the uninstall section that the relevance picks up; but are part of the current version of the software.
It wouldn’t work the way you have it written, but it SHOULD work the way I have it written. If you use (x64 registries; x32 registries) then you must also use keys instead of key… it has to be pluralized.
…and not include Wow6432Node in the pathname of the key. The inspector checking x32 registries will be redirected there automatically. Observe that jgstew omitted Wow6432Node in his example
This is actually the whole reason behind 32-bit redirection. The 32-bit program doesn’t know that its keys are written beneath Wow6432Node, this is just automatically redirected by windows.
By checking the key (without Wow6432Node), the ‘x64 registries’ would find a 64-bit program in the (native) 64-bit path, while the ‘x32 registries’ would find a 32-bit program installed on a 64-bit machine (being redirected beneath Wow6432Node), OR find the same 32-bit program on a 32-bit machine (where the program would have written to the ‘native’ registry path)
Don’t worry if this doesn’t make sense. It is very confusing, it is a Microsoft / windows thing, not actually a bigfix complication, just one bigfix has to deal with the fallout of. It took me years to wrap my head around what is actually going on.
Oh no, I get the idea; but the problem is using native registry works as expected, using “…keys “HKLM\Software\Microsoft\Windows\CurrentVersion\Uninstall” of (x64 registries; x32 registries)” returns incorrect values due to there being additional uninstall lines that invalidate the information due to how the app is installed.
Using the 64/32 option pulls in additional entries, that give me false positives. Otherwise the 64/32 would be the better way to go.
(it > 1) of number of keys whose (value "DisplayName" of it as string as lowercase contains "nachos") of keys "HKLM\Software\Microsoft\Windows\CurrentVersion\Uninstall" of (registries)
Does this return what you expect on x64 systems? This should read the correct locations on both x64 and x32 systems.
WOW6432Node is always incorrect on 32bit systems. but registries and x32 registries automatically read from the WOW6432Node on x64 systems, but the regular location on 32bit ones… it actually handles this difference transparently, which is also confusing.
Nope, only the “native registry” appears to return the correct results. Using the 64/32 or registries in the action script caused it to find and try to uninstall the wrong thing (fortunately not uninstalling anything). Using the 64/32 or registries in the relevance causes it to identify every PC that has the application installed on it once or more because one install creates an uninstall record under the native registry and two entries under the WOW6432Node uninstall.
(it > 1) of number of keys whose (value "DisplayName" of it as string as lowercase contains "nachos") of keys "HKLM\Software\Microsoft\Windows\CurrentVersion\Uninstall" of (registries)
Or the 64/32 version.
I could also include a section to ignore any uninstall keys that contain c:\ProgramData\Package Cache in them. That would allow that to work.
This will not work on a 32bit system, only a 64bit system:
keys "HKLM\Software\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall" of native registries
This is equivalent on 64bit Windows, but also works on 32bit Windows:
keys "HKLM\Software\Microsoft\Windows\CurrentVersion\Uninstall" of registries
The reason this works is it checks the location listed on 32bit systems, but checks the HKLM\Software\WOW6432Node on 64bit systems. This is the “better” way to use the registry for 32bit software keys.
Either one may work depending on the circumstance, but one is more broadly applicable.