AppDeploy/ITNinja has helped me enormously over the years thanks to posts of other folks not unlike me. So, in the spirit of open source & knowledge transfer, I hope others find this helpful!
Our environment isn't the best at keeping our applications up to date. We're usually a handful of versions behind for a variety of reasons. Our environment also isn't locked down, leaving users as local admins with full reign over the machine to install/uninstall whatever they want. Ignoring the potential security threats this opens up, its usually not a problem, except when a user installs a newer version of something that our support team isn't familiar with.
Applications like Java, Flash and Reader are usually updated 'regularly' by our users. While it doesn't necessarily create instability or technical problems in general day to day use, its often a problem when we need to deploy specific versions of one of those applications. For instance up until recently the USPTO only supported Java 6 requring us to say a few versions behind; some other apps like Stonegate and NetApp also required earlier versions of Java and so on.
I used to keep a running list of the uninstall strings for the versions of Java we not only deployed, but also the ones we ran across when we found that a user had Java Y not Java X. (It was not unlike the Ultimate Java Uninstaller and others like it) Needless to say this list became rather lengthy, and the general concensus was that the installs were taking longer & longer. (Even though Java Z.Y.X wasn't installed, the msi would run and fail silently then move on - wash, rinse, repeat) I didn't like the solution, but it was all that made sense at the time, and all I had time to create.
After getting several projects & deliverables off my plate I decided to do what I could to combat this problem & improve the process. I decided to take a slightly different approach to determine whether or not a specific application was installed then remove it. Its not too difficult so I'll try to explain: I query the Uninstall key in the registry looking for the application in question, then call the uninstall string with a quick substitution. This allows me to handle any version of Java, Reader or even Flash (although they have their own uninstaller).
This is for Java
@echo off
setlocal enabledelayedexpansion echo. & echo Checking for Obsolete Versions of Java... rem this is the old code that would run the uninstall for specific versions of Java
rem I didn't like this solution - required adding more cmd files every time we found a new version
rem for /f "usebackq tokens=*" %%i in (`dir /b /a:D "%~dp0"`) do (
rem echo i is %%i
rem if exist "%~dp0%%i\uninstall_java.cmd" (
rem echo. Removing %%i
rem call "%~dp0%%i\uninstall_java.cmd"
rem )
rem if exist "%~dp0%%i\uninstall.cmd" (
rem echo. Removing %%i
rem call "%~dp0%%i\uninstall.cmd"
rem )
rem ) rem this is my new process for removing Java
for /f "usebackq tokens=*" %%a in (`reg query HKLM\software\microsoft\windows\currentversion\uninstall`) do (
rem echo a is %%a
for /f "usebackq tokens=2*" %%b in (`reg query "%%a" /v DisplayName 2^>nul ^| find /i "java"`) do (
rem echo b is %%b
rem echo c is %%c
for /f "usebackq tokens=3,4" %%d in (`reg query "%%a" /v UninstallString 2^>nul`) do (
echo. Removing %%c
rem echo d is %%d
rem echo e is %%e set uninstallcmd=%%e
set uninstallcmd=!uninstallcmd:^/I=^/X! rem %%d %%e /qb-
%%d !uninstallcmd! /qb-
)
)
) :end
endlocal
#EOF
I use the same technique for Adobe Reader...
echo. & echo Checking Registry for Other Versions ...
rem check registry
for /f "usebackq tokens=*" %%a in (`reg query HKLM\software\microsoft\windows\currentversion\uninstall`) do (
rem echo a is %%a
for /f "usebackq tokens=2*" %%b in (`reg query "%%a" /v DisplayName 2^>nul ^| find /i "adobe reader"`) do (
rem echo b is %%b
rem echo c is %%c
for /f "usebackq tokens=3,4" %%d in (`reg query "%%a" /v UninstallString 2^>nul`) do (
echo. Removing %%c (via Registry^)
rem echo d is %%d
rem echo e is %%e
set uninstallcmd=%%e
set uninstallcmd=!uninstallcmd:^/I=^/X! rem %%d %%e /qb-
rem %%d !uninstallcmd! /qb- REBOOT=REALLYSUPPRESS
%%d !uninstallcmd! /qb- REBOOT=REALLYSUPPRESS /norestart
)
)
)
And this one is for Adobe Flash both ActiveX and Plug-in .....
for /f "usebackq tokens=*" %%a in (`reg query HKLM\software\microsoft\windows\currentversion\uninstall`) do (
rem echo a is %%a
rem @echo %date% %time% - percent a is %%a>> !flashlog!rem for /f "usebackq tokens=2*" %%b in (`reg query "%%a" /v DisplayName 2^>nul ^| find /i "adobe flash player"`) do (
for /f "usebackq tokens=2*" %%b in (`reg query "%%a" /v DisplayName 2^>nul ^| find /i "DisplayName" ^| find /i "adobe flash player"`) do (
@echo %date% %time% - percent a is %%a>> !flashlog!
@echo %date% %time% - percent b is %%b>> !flashlog!
@echo %date% %time% - percent c is %%c>> !flashlog!rem echo a is %%a
rem echo b is %%b
rem echo c is %%cset appname="%%c"
@echo %date% %time% - appname is "!appname!">> !flashlog!rem set appname=!appname:&=and!
rem @echo %date% %time% - appname with ^& removed "!appname!">> !flashlog!set appname=!appname:"=!
@echo %date% %time% - appname with ^" removed "!appname!">> !flashlog!
rem for /f "usebackq tokens=3,4" %%d in (`reg query "%%a" /v UninstallString 2^>nul`) do (
for /f "usebackq tokens=3,4" %%d in (`reg query "%%a" /v UninstallString 2^>nul ^| find /v /i "%%a"`) do (
@echo %date% %time% - percent d is %%d>> !flashlog!
@echo %date% %time% - precent e is %%e>> !flashlog!rem check for msi
set uninstallstring=%%d
@echo %date% %time% - Uninstallstring is !uninstallstring!>> !flashlog!for /f "usebackq tokens=*" %%f in (`echo !uninstallstring! ^| find /c /i "msiexec"`) do (
@echo %date% %time% - precent f is %%f>> !flashlog!set count=%%f
@echo %date% %time% - count is !count!>> !flashlog!echo. Removing !appname!
@echo %date% %time% - Removing !appname!>> !flashlog!if [!count!]==[1] (
@echo %date% %time% - msiexec detected as count is 1: !count!>> !flashlog!set uninstallcmd=%%e
set uninstallcmd=!uninstallcmd:^/I=^/X!@echo %date% %time% - executing: %%d !uninstallcmd! /qb->> !flashlog!
%%d !uninstallcmd! /qb-
) else (
if [!count!]==[0] (
@echo %date% %time% - non-msi detected as count is 0: !count!>> !flashlog!
@echo %date% %time% - executing: start /q "uninstalling %%c" %%d %%f /qb->> !flashlog!
start /w "uninstalling %%c" %%d %%e
) else (
@echo %date% %time% - not sure what was detected as count is not 0 or 1: !count!>> !flashlog!
@echo %date% %time% - executing: start /q "uninstalling %%c" %%d %%f /qb->> !flashlog!
start /w "uninstalling %%c" %%d %%e
)
)set count=
)
)set appname=
)
)rem this shouldn't be necessary anymore but I leave it here for historical purposes.
rem uninstall flash with remaining .exe(s)
for /f "usebackq tokens=*" %%h in (`dir /b /a:-d "C:\Windows\System32\Macromed\Flash\*.exe" 2^>nul`) do (
rem echo. Running %%h
rem start /w "Uninstalling Flash %%h" "C:\Windows\System32\Macromed\Flash\%%h" -uninstall
rem del /q "C:\Windows\System32\Macromed\Flash\%%h"
)
But that was before I discovered the Flash Uninstaller :) which I now call via:
'start /w "Adobe Flash Uninstaller" "%~dp0uninstall_flash_player.exe" -uninstall'
You can take it a step further by looking for specific versions of applications. We haven't had a need for that so I haven't taken the time to add something like that in but its not too difficult.
I think the script is pretty quick, especially in comparison to what we were seeing with the older process of running 32 msiexec /X's.
Enjoy!
Comments