Need uninstall .bat file to signal success when product does not exist
My situation is this. I am deploying Navisworks Freedom 2015 to PCs using SCCM 2012, some of which have 2014, others do not. The install signals reboot required and will reboot no matter what if its part of a Task Sequence, so I need to deploy it as a Package/Program which allows me to set the reboot behavior to never and avoid the automatic reboot, which I have to avoid in this deployment.
The problem is, I can't set conditions for the batch file that runs the uninstall for the previous version to only run if the previous version exists. So I need to force the batch file to run whether or not the app exists and send a error code of 0 to SCCM in order to continue the installation of the latest version.
Specifically, I get error codes 1605 and 255 when I try to run on a machine that does not have 2014 installed. Although it may not be best practice, I have attempted to script the errorlevel behavior in the batch file such that if either of those codes appear it still instructs the script to send a Success error code.
Example:
:funcUninstall
setlocal
set msi_ERROR_SUCCESS=0
set product_code=%~1
set product_name=%~2
msiexec /uninstall %product_code% %uninstallation_mode%
if %errorlevel%=1605 goto SUCCESS_
if %errorlevel%=255 goto SUCCESS_
if %errorlevel%==%msi_ERROR_SUCCESS% goto SUCCESS_
:ERROR_
::------------------------------------------
::print out Machine Name, product code, product name
::to the network log file for the product that failed to uninstall
set uninstallation_result=Failed, Result=%errorlevel%
goto DONE_
:SUCCESS_
set uninstallation_result=Succeeded
goto DONE_
:DONE_
echo %Date% %Time% %USERNAME% %COMPUTERNAME% Uninstall %product_name% (Product Code: %product_code%) %uninstallation_result% >> %network_log_file_path%
endlocal
GOTO:EOF
:END_FUNCTIONS_SECTION_
-
VBscript is easy to use and can manage error levels with much more precision than batch code. - EdT 9 years ago
Answers (6)
So here's what I ended up doing. I scrapped the batch file because it just wasn't making life easier than it would be to call individual msiexe /x commands for the previously installed components and run them with the 2015 install in a Task Sequence. After I discovered the Package/Program install would break if pending updates were there I bailed on preventing a reboot and just accepted it needed to happen. Not a big deal since this is an Available (optional) install for users. I was also able to include this at the start of the TS to remind users that go to install the app 2 months from now that they need to save everything because the machine will automatically reboot to complete the install.
It's not the perfect situation, but it should work. Thank you again for all the help. I appreciate all the input regardless of whether it gets directly used or not.
I use a reg query to check for that applications uninstall GUID. If missing it uses a goto to bypass the actual uninstall so the script reports a successful finish to SCCM.
echo. >>%logfile%
echo %date% %time% This is the Start >>%logfile%
REM check program is installed - avoids uninstall hanging at "action only valid for installed products" dialog.
reg query HKLM\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\{5A8D319F-84E0-4409-8402-A3F8F909854C}
if errorlevel 1 goto abort
REM UnInstall Application
start "Uninstall" /wait msiexec.exe /x {5A8D319F-84E0-4409-8402-A3F8F909854C} /qb /Norestart /lv %logfile%
goto eof
:abort
echo. >>%logfile%
echo program not installed - aborting. >>%logfile%
:eof
echo %date% %time% This is the end >>%logfile%
Comments:
-
using the /qn would allow it to silently carry on if it was not installed. you would still get an error logged in eventvwr, but atleast no hang. - Badger 9 years ago
You should be using SCCM for any logic involving the discovery, inventory, installation or removal of applications, not a CMD file. With what you're doing, you're actually bypassing the strength of SCCM's management & reporting abilities. Look into its ability to leverage 'dependencies' and marking things as 'superseded' and your life will be much easier.
If you must use batch files, first change your extension from .BAT to .CMD. Next, you can use the following syntax as the very last line in your script to set the errorlevel:
set errorlevel = 1605
Comments:
-
<< change your extension from .BAT to .CMD >> Ha, ha, ha! How on God's green Earth would that make any difference?!? - anonymous_9363 9 years ago
-
The OS interprets the .bat as a process for 8-bit operations. The .cmd extension is processed as 16-bit and works a little "better", OS-wise. It's one of those little pet peeves/quirks I've had for years. - vjaneczko 9 years ago
Here is where the script is at currently. Keep in mind, this has been dropped into the pre-existing batch file Autodesk supplies with their products, specifically intended for use with SCCM (according to them). So I am having to work with what I have but make some changes to get it to behave exactly how I want it to.
::Check if Navisworks Freedom 2014 x64 exists
SET PRODUCTKEY=HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall
REG QUERY %PRODUCTKEY%\{0D20419E-7BFA-0000-AFAF-A1181FCDFD27}
IF ERRORLEVEL 1 GOTO :NOTINSTALLED
The script will complete successfully and continue to the 2015 install from Software Center when deployed as a Program. The PC does not reboot. However, the issue I am noticing now is that it appears to always skip the rest of the script. Meaning if 2014 is installed, its not uninstalling it. Do I need an endif at the end of this script? Or do I need to instruct it to jump to the next section with another GOTO command? The intention was if the errorlevel code did not equal 1, it would continue with the rest of the scripts which would, in theory, uninstall the previous version.
Thanks for the comments thus far.
Comments:
-
Can you post a copy of this "...pre-existing batch file Autodesk supplies with their products, specifically intended for use with SCCM..." - anonymous_89149 9 years ago
-
::The following command lines allow un-installing products that were installed using this admin image
:: Notes on suggested usage:
:: + Copy the commands to a batch file to execute.
:: + The commands must be run with Administrative Privileges, e.g. right-click when opening Command Prompt and accept UAC
::========================================================================================
::Prepare uninstallation's command-line options
::========================================================================================
C:\Windows\System32\eventcreate.exe /T INFORMATION /ID 999 /L APPLICATION /D "Starting Script"
::Set the output file for uninstallation's log data
::DEFAULT: a log file with the same filename but with extension .log
:: is created in the Windows temporary folder (environment variable TEMP)
set msi_log_file_path="%TEMP%\%~n0.log"
::Delete the current log file
if exist %msi_log_file_path% del /Q %msi_log_file_path%
C:\Windows\System32\eventcreate.exe /T INFORMATION /ID 999 /L APPLICATION /D "Got Past log creation"
::Check if Navisworks Freedom 2014 x64 exists
SET PRODUCTKEY=HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall
C:\Windows\System32\eventcreate.exe /T INFORMATION /ID 999 /L APPLICATION /D "Got Past setting product key"
REG QUERY %PRODUCTKEY%\{0D20419E-7BFA-0000-AFAF-A1181FCDFD27}
C:\Windows\System32\eventcreate.exe /T INFORMATION /ID 999 /L APPLICATION /D "Got Past registry check"
IF ERRORLEVEL 1 GOTO :NOTINSTALLED
C:\Windows\System32\eventcreate.exe /T INFORMATION /ID 999 /L APPLICATION /D "Got Past Check Navisworks Freedom 2014 x64 exists"
::Set the path for the network log file
set network_log_folder=""
md %network_log_folder%
set network_log_file_path="%network_log_folder%%~n0_Admin.log"
echo ========================== %Date% %Time% =========================== >> %network_log_file_path%
echo Uninstallation Started on Computer Name: %COMPUTERNAME%, Username: %USERNAME%, Domain: %USERDNSDOMAIN% >> %network_log_file_path%
::DEFAULT: silent uninstallation
set non_silent_mode=/norestart /L*+ %msi_log_file_path% REMOVE=ALL REBOOT=ReallySuppress ADSK_SETUP_EXE=1
set silent_mode=/quiet %non_silent_mode%
set uninstallation_mode=%silent_mode%
::========================================================================================
::Helper Functions
::========================================================================================
goto END_FUNCTIONS_SECTION_
:BEGIN_FUNCTIONS_SECTION_
::---------------------------------
::Performs uninstallation and reports failure in the Network Log File
::---------------------------------
:funcUninstall
setlocal
set msi_ERROR_SUCCESS=0
set product_code=%~1
set product_name=%~2
msiexec /uninstall %product_code% %uninstallation_mode%
if %errorlevel%==%msi_ERROR_SUCCESS% goto SUCCESS_
:ERROR_
::------------------------------------------
::print out Machine Name, product code, product name
::to the network log file for the product that failed to uninstall
set uninstallation_result=Failed, Result=%errorlevel%
goto DONE_
:SUCCESS_
set uninstallation_result=Succeeded
goto DONE_
:DONE_
echo %Date% %Time% %USERNAME% %COMPUTERNAME% Uninstall %product_name% (Product Code: %product_code%) %uninstallation_result% >> %network_log_file_path%
endlocal
GOTO:EOF
:END_FUNCTIONS_SECTION_
C:\Windows\System32\eventcreate.exe /T INFORMATION /ID 999 /L APPLICATION /D "Got Past END_FUNCTIONS_SECTION_"
::========================================================================================
::Uncomment (by removing the ::) the command lines below to uninstall products
::========================================================================================
::::== MSXML 6.0 Parser
::::Manual uninstallation only
::::== Microsoft Visual C++ 2008 SP1 Redistributable (x86)
::::Manual uninstallation only
::::== Microsoft Visual C++ 2008 SP1 Redistributable (x64)
::::Manual uninstallation only
::::== Microsoft Visual C++ 2010 SP1 Redistributable (x86)
::::Manual uninstallation only
::::== Microsoft Visual C++ 2010 SP1 Redistributable (x64)
::::Manual uninstallation only
::::== .NET Framework Runtime 3.5 SP1
::::Manual uninstallation only
::::== DirectX® Runtime
::::Manual uninstallation only
::::== .NET Framework Runtime 4.5
::::Manual uninstallation only
::::== Autodesk Material Library 2014
call :funcUninstall {644F9B19-A462-499C-BF4D-300ABC2A28B1}, "Autodesk Material Library 2014"
::::== Autodesk Material Library Base Resolution Image Library 2014
call :funcUninstall {51BF3210-B825-4092-8E0D-66D689916E02}, "Autodesk Material Library Base Resolution Image Library 2014"
::::== Autodesk Navisworks Freedom 2014
call :funcUninstall {0D20419E-7BFA-0000-AFAF-A1181FCDFD27}, "Autodesk Navisworks Freedom 2014"
::::== Autodesk Navisworks Freedom 2014 English Language Pack
call :funcUninstall {0D20419E-7BFA-0409-AFAF-A1181FCDFD27}, "Autodesk Navisworks Freedom 2014 English Language Pack"
:NOTINSTALLED
Exit 0 - quattro004 9 years ago-
Sorry, can't see anything obviously wrong. I presume you are uncommenting call :funcUninstall {0D20419E-7BFA-0000-AFAF-A1181FCDFD27}, "Autodesk Navisworks Freedom 2014" and call :funcUninstall {0D20419E-7BFA-0409-AFAF-A1181FCDFD27}, "Autodesk Navisworks Freedom 2014 English Language Pack". If you are unsure whether system is in a clean state regarding the need to restart then perhaps call a restart package as a prerequisite to the Navisworks package. Remember with troubleshooting that echo is your friend. :) - anonymous_89149 9 years ago
-
the command to set %network_log_folder% is setting it to "". Try set network_log_folder="%windir%\temp\" or similar - anonymous_89149 9 years ago