How are you uninstalling all versions of applications?
In our environment we often find ourselves challenged with application upgrades, due to a W-I-D-E variety of previous versions that we need to upgrade. Generally speaking, I'll handle uninstalls before the installs with something like this:
wmic product where "name like 'iTunes%%'" call uninstall /nointeractive
Which works......probably 98% of the time. Here is what I don't like, however.
1. It runs a repair on all appliations as it's searching for the referenced application. This is a problem when systems are monitored for changes, and these show up as (unnecessary) changes.
2. In some very minor cases, the WMI call fails which then causes the upgraded software to fail to install with an exit code of 1638 (previous version).
At the root of it, however, the approach is simple and future capable. Things were easier with only x86 Operating systems, as you could simply traverse HKLM\Software\Microsoft\Windows\CurrentVersion\Uninstall - but now the x64 code comes into play. I also read that you shouldn't hardcode the HKLM\Software\Wow6432Node... into scripts, as this path may change - rather you should use a value to redirect (escapes me at the moment).
In other environments that are faced by this (if not, lucky you) - how are you reliably uninstalling all versions of software, on x86 and x64 systems, while minimizing change?
If only vendors populated the upgrade table with any version previously released, we wouldn't have this problem ;)
-
I suppose a near perfect example would be something like this: http://community.spiceworks.com/scripts/show/250-uninstall-itunes Yet you have to know and plug in the uninstall parameters - which again would be the same in most cases. That script, as written at least, wouldn't account for x64 systems either. - drose23 11 years ago
Answers (1)
You could write a script that uses Function call to msi.dll.. for more info go here.. http://www.itninja.com/blog/view/searching-for-installed-msi-s-via-wisescript
What this allows you to do is verify the application is there before performing an Uninstall, and or Upgrade. Since you are using a call to a DLL it does not matter if its a 32 or 64 bit app, if its installed, it will find it.
For the scenaro you mentioned, I would create a script with a While Loop that reads all of the Productcodes from an INI file and then if found, write an entry to log and perform Uninstall, then go to the next item in the list.
Comments:
-
Thanks for the comment, and it's a great suggestion. If I'm understanding you correctly, I still see a minor flaw - the Product Code needs to be known. I've come up with a process that seems to work for error detection using WMI, basically this (some extra commenting for reference)
Document Type: WSE
item: Global
Version=9.02
Flags=00000100
Split=1420
Languages=65 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
Japanese Font Name=MS Gothic
Japanese Font Size=9
Progress Bar DLL=%_WISE_%\Progress\WIZ%_EXE_OS_TYPE_%.DLL
Start Gradient=0 0 255
End Gradient=0 0 0
Windows Flags=00000100000000010010110000001000
Message Font=MS Sans Serif
Font Size=8
Disk Label=Default
Disk Filename=SETUP
Patch Flags=0000000000000001
Patch Threshold=85
Patch Memory=4000
MIF PDF Version=1.0
MIF SMS Version=2.0
FTP Cluster Size=20
Dialogs Version=7
Crystal Format=10111100101100000010001001001001
Step View=All
Variable Name1=_SYS_
Variable Default1=C:\windows\system32
Variable Flags1=00001000
Variable Name2=_WIN_
Variable Default2=C:\windows
Variable Flags2=00001000
Variable Name3=_WISE_
Variable Default3=C:\Program Files (x86)\AdminStudio\11.5\WiseScript Package Editor
Variable Flags3=00001000
Requested Execution Level=asInvoker
end
item: Remark
Text=Establish variable with empty value in order to query contents of uninstall.txt
end
item: Set Variable
Variable=STATUS
end
item: Remark
Text=Path to uninstall.bat should vary based on application, rest doesn't need to be modified unless multiple uninstalls occur
end
item: Install File
Source=%PATH%\\uninstall.bat
Destination=%INST%\uninstall.bat
Flags=0000000010100010
end
item: Remark
Text=Execute WMI call to remove applications
end
item: Execute Program
Pathname=CMD
Command Line=/c "%INST%\uninstall.bat"
Default Directory=%SYS%
Flags=00001010
end
item: Remark
Text=This next section will read in uninstall.bat one line at a time and will loop until all lines are read and STATUS is fully populated
end
item: Read/Update Text File
Variable=UNINSTALL_STATUS
Pathname=%PATH%\uninstall.txt
end
item: Set Variable
Variable=STATUS
Value=%STATUS%%UNINSTALL_STATUS%%CRLF%
end
item: End Block
end
item: Remark
Text=Now that %STATUS% is fully populated, perform check to look for 1 of 2 successful scenarios, "Method execution successful" or "No Instance(s) Available". If neither is found, send e-mail about failure
end
item: If/While Statement
Variable=STATUS
Value=Method execution successful
Flags=00000011
end
item: If/While Statement
Variable=STATUS
Value=No Instance(s) Available
Flags=00000011
end
item: Install File
Source=%PATH%\send_uninstall_dot_txt.vbs
Destination=%INST%\send_uninstall_dot_txt.vbs
Flags=0000000010100010
end
item: Execute Program
Pathname=%INST%\send_uninstall_dot_txt.vbs
Flags=00001010
end
item: End Block
end
item: End Block
end
In a nutshell, it runs the wmic command from a batch file - and writes the output of that activity to a .txt file. That .txt file is then read by the WiseScript into a variable - and that variable is then searched for 1 of 2 strings of text. If neither string is found, it's assumed to be a failure - an e-mail is then sent to specific parties notifying of such, with the .txt file containing the failure information attached to that e-mail.
That at least gets me by the failure portion of WMI......without having to know anything except for the name of the application plus %% - drose23 11 years ago