Script bat Uninstalling the old version and installing the new version of the program - batch-file

I need to create a script to uninstall an older, existing, version of proCertum CardManager, before installing a newer version.
The program is available in our environment in both 32bit and 64bit versions, (eventually there will only be a 64bit version).
I need is:
-Check version of proCertum CardManager by Display Version
-if version 3.5.1.198 AND it is new version then GOTO :END
else GOTO :INSTALL
So far I have created a script but when I run it nothing happens. What am I missing?
Contents of the script:
#echo on
FOR /F "tokens=1,2,*" %%a IN ('reg query "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\proCertum CardManager" /V DisplayVersion') DO (
IF "%%a"=="DisplayVersion" SET "DisplayVersion=%%c"
if %DisplayVersion%=="3.5.1.198" ( goto :END
else (
goto :INSTALL
)
FOR /F "tokens=1,2,*" %%a IN ('reg query "HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstal\proCertum CardManager" /V DisplayVersion') DO (
IF "%%a"=="DisplayVersion" SET "DisplayVersion=%%c"
if %DisplayVersion%=="3.5.1.198" ( goto :END
else (
goto :INSTALL
)
:INSTALL
REM Uninstall Older version
start /wait msiexec.exe /x {B96A7F3B-AF29-489A-AE84-1DDF5942971C} /qn
REM Install latest version
start /wait msiexec.exe /i "%~dp0proCertumCardManager-3.5.1.198-64-bit-pl.msi" /qn /quiet
:END
I have created a script but when I run it nothing happens. Please indicate what is missing
My script now looks like this:
#echo off
for /f "usebackq tokens=* delims=" %%a in (`wmic product where name^='proCertumCardManager' 2^>^&1`) do (
for /f "tokens=* delims=" %%# in ("%%a") do set "result=%%~#"
)
if "%result%" equ "No Instance(s) Available." (
goto :END
if "%result%" neq "No Instance(s) Available."
goto :INSTALL_FULL
)
:INSTALL_FULL
reg query HKLM\Software\Microsoft\Windows\CurrentVersion\Uninstall\{B96A7F3B-AF29-489A-AE84-1DDF5942971C} /v DisplayVersion
reg query HKLM\Software\wow6432node\Microsoft\Windows\CurrentVersion\Uninstall\{B96A7F3B-AF29-489A-AE84-1DDF5942971C} /v DisplayVersion
for /f "tokens=3" %%i in ('reg query HKLM\Software\Microsoft\Windows\CurrentVersion\Uninstall\{B96A7F3B-AF29-489A-AE84-1DDF5942971C} /v DisplayVersion') do (
if %%i EQU 3.6.1.208 goto :END
if %%i NEQ 3.6.1.208 goto :INSTALL
)
:INSTALL
REM Uninstall Older version
start /wait msiexec.exe /x {B96A7F3B-AF29-489A-AE84-1DDF5942971C} /qn
REM Install latest version
start /wait msiexec.exe /i "%~dp0proCertumCardManager-3.6.1.208-64-bit-pl.msi" /qn /quiet
:END

Related

Batch script to check whether the required NPM package is installed or not doesn't work reliably

I have come up with a batch script, through some Googling and analysis on batch scripts, for checking if the package I mention in user prompt exists in system and get its version if it does. Here it is in its most possible final version:
#echo off && setlocal EnableDelayedExpansion
set "output_cnt=0"
set /p "pkg=Package? "
for /f "delims=" %%a in ('npm -v 2^>nul') do #set "npmV=%%a"
if defined npmV (echo NPM Version: %npmV%) else (echo NPM isn't installed)
for /f "delims=" %%b in ('node -v 2^>nul') do #set "nodeV=%%b"
if defined nodeV (echo Node Version: %nodeV%) else (echo Node isn't installed)
for /f "delims=" %%c in ('npm list -g %pkg% 2^>nul') do (
set /a output_cnt+=1
set "pkgV[!output_cnt!]=%%c"
)
if defined pkgV (for /l %%n in (1 1 !output_cnt!) do echo !pkg! Version: !pkgV[%%n]!) else (echo %pkg% isn't installed)
setlocal DisableDelayedExpansion && endlocal && pause
Now when I run this script, it does check properly whether Node and NPM are installed and gets their version accurately, but when I pass any package name to the user prompt (e.g. cowsay, and this package is installed, of that I am sure), it always says <package> isn't installed(as in cowsay isn't installed).
As you can see I am trying to capture full output of npm list -g <package> with multiple lines through array, but it clearly screws up.
Can anyone assist in figuring out what's wrong and get what I want?
Welcome to batch; arrays aren't real!*
Instead, you've got a collection of variables that all simply happen to start with pkgV[ that you're able to iterate over. So while %pkgV[1]%, %pkgV[2]%, etc. are all defined, %pkgV% by itself isn't because that particular variable was never set.
However, since you'll always have a %pkgV[1]% if any valid packages have been provided, you can check that pkgV[1] is defined and go from there. (Alternately, you can simply check that %output_cnt% is greater than 0.)
if defined pkgV[1] (for /l %%n in (1 1 !output_cnt!) do echo !pkg! Version: !pkgV[%%n]!) else (echo %pkg% isn't installed)
* - At least, not in the way that other languages do arrays.
Why do you use a (pseudo-)array after all? Why not simply doing all in a single loop?
I see two possible code portions to replace the for /f %%c loop and the subsequent if defined pkgV condition (which actually is the faulty code fragment as explained in SomethingDark's answer) with:
Use a flag-style variable that indicates whether npm list returned any items:
#echo off & setlocal EnableExtensions DisableDelayedExpansion
set "output_cnt=0"
set /p "pkg=Package? "
for /f "delims=" %%a in ('npm -v 2^>nul') do #set "npmV=%%a"
if defined npmV (echo NPM Version: %npmV%) else (echo NPM isn't installed)
for /f "delims=" %%b in ('node -v 2^>nul') do #set "nodeV=%%b"
if defined nodeV (echo Node Version: %nodeV%) else (echo Node isn't installed)
set "FLAG="
for /f "delims=" %%c in ('npm list -g %pkg% 2^>nul') do (
set "FLAG=#" & echo !pkg! Version: %%c
)
if not defined FLAG echo %pkg% isn't installed
pause
Detect the exit code of the for /f %%c loop by conditional execution, which is set to 1 when the loop doesn't iterate:
#echo off & setlocal EnableExtensions DisableDelayedExpansion
set "output_cnt=0"
set /p "pkg=Package? "
for /f "delims=" %%a in ('npm -v 2^>nul') do #set "npmV=%%a"
if defined npmV (echo NPM Version: %npmV%) else (echo NPM isn't installed)
for /f "delims=" %%b in ('node -v 2^>nul') do #set "nodeV=%%b"
if defined nodeV (echo Node Version: %nodeV%) else (echo Node isn't installed)
(
for /f "delims=" %%c in ('npm list -g %pkg% 2^>nul') do (
echo !pkg! Version: %%c
)
) || echo %pkg% isn't installed
pause
N. B.:
By the way, the command sequence setlocal DisableDelayedExpansion && endlocal at the end doesn't make any sense at all, since the state afterwards is just the same as without it.
If the intention was to surely have delayed expansion disabled at the pause command, you should have replaced your initial line with #echo off & setlocal EnableExtensions DisableDelayedExpansion and have inserted the line setlocal EnableDelayedExpansion before the for /f %%c loop in your original code.
If there will only be one installed version of any input package, then perhaps this would work for you:
#Echo Off
SetLocal EnableExtensions DisableDelayedExpansion
Set "nodeV="
For %%G In ("node.js") Do For /F %%H In (
'"%%~$PATH:%%G" -v') Do Set "nodeV=%%H"
If Defined nodeV (Echo Node Version: %nodeV%
) Else Echo node.js is not in your %%PATH%%
Set "npmV="
For %%G In ("npm.cmd") Do For /F %%H In (
'"%%~$PATH:%%G" -v') Do Set "npmV=%%H"
If Defined npmV (Echo NPM Version: %npmV%
) Else (Echo npm.cmd is not in your %%PATH%%
Echo Press any key to exit ...
Pause 1>NUL
Exit /B)
:GetPkg
Set "pkg="
Set /P "pkg=Package? "
If Not Defined pkg GoTo GetPkg
Set "pkgV="
For /F "Tokens=2 Delims=#" %%G In (
'npm.cmd list "%pkg%" -g 2^>NUL
^| %SystemRoot%\System32\find.exe "#"'
) Do Set "pkgV=%%G"
If Defined pkgV (Echo %pkg% Version: %pkgV%
) Else Echo %pkg% is not globally installed
Pause
EndLocal
GoTo :EOF
However, if there could be multiple installed versions of your input package, as implied by your code, then this modification may prove more useful:
#Echo Off
SetLocal EnableExtensions DisableDelayedExpansion
Set "nodeV="
For %%G In ("node.js") Do For /F %%H In (
'"%%~$PATH:%%G" -v') Do Set "nodeV=%%H"
If Defined nodeV (Echo Node Version: %nodeV%
) Else Echo node.js is not in your %%PATH%%
Set "npmV="
For %%G In ("npm.cmd") Do For /F %%H In (
'"%%~$PATH:%%G" -v') Do Set "npmV=%%H"
If Defined npmV (Echo NPM Version: %npmV%
) Else (Echo npm.cmd is not in your %%PATH%%
Echo Press any key to exit ...
Pause 1>NUL
Exit /B)
:GetPkg
Set "pkg="
Set /P "pkg=Package? "
If Not Defined pkg GoTo GetPkg
For /F "Delims==" %%G In ('"(Set pkgV[) 2>NUL"'
) Do Set "%%G="
Set "output_cnt=0"
For /F "Tokens=2 Delims=#" %%G In (
'npm.cmd list %pkg% -g 2^>NUL
^| %SystemRoot%\System32\find.exe "#"'
) Do (Set /A output_cnt += 1
SetLocal EnableDelayedExpansion
For %%H In (!output_cnt!) Do (EndLocal
Set "pkgV[%%H]=%%G"))
If %output_cnt GEq 1 (
For /F "Tokens=2,* Delims=[]=" %%G In (
'"(Set pkgV[) 2>NUL"'
) Do Echo %pkg% version %%G: %%H
) Else Echo %pkg% is not globally installed
Pause
EndLocal
GoTo :EOF
Please note, that none of the above code has been tested at all, if there are obvious typos, or errors, please let me know, and I'll take a look at it later.

Batch file for installed software

I am very new to batch just learnt a few. I agree to having shamelessly lifted this code from a website. This is the code I want for displaying list of installed software, however there is just one problem, the version and the softwares are being displayed in different lines. How can I have both in the same line?
Ex: If you run the batch you will see the versions at the beginning and then the softwares.
Any help would be greatly appreciated. Thanks in advance.
#echo off
If Exist C:\Final.txt Del C:\Final.txt
regedit /e C:\regexport.txt "HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Uninstall"
regedit /e C:\regexport2.txt "HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Uninstall"
regedit /e C:\regexport3.txt "HKEY_LOCAL_MACHINE\Software\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall"
find "DisplayName" C:\regexport.txt > C:\regprogs.txt
find "DisplayName" C:\regexport2.txt >> C:\regprogs.txt
find "DisplayName" C:\regexport3.txt >> C:\regprogs.txt
for /f "tokens=2 delims==" %%a in (C:\regprogs.txt) do echo %%~a >> C:\installedprogs.txt
find "DisplayVersion" C:\regexport.txt > C:\regprogs.txt
find "DisplayVersion" C:\regexport2.txt >> C:\regprogs.txt
find "DisplayVersion" C:\regexport3.txt >> C:\regprogs.txt
for /f "tokens=2 delims==" %%a in (C:\regprogs.txt) do echo %%~a >> C:\installedprogs.txt
del C:\regexport.txt
del C:\regexport2.txt
del C:\regexport3.txt
del C:\regprogs.txt
sort C:\installedprogs.txt > C:\alles.txt
del C:\installedprogs.txt
:: script om alle dubbele lijnen eruit te gooien
REM -- Prepare the Command Processor --
SETLOCAL ENABLEEXTENSIONS
SETLOCAL EnABLEDELAYEDEXPANSION
REM -- Prepare the Prompt for easy debugging -- restore with prompt=$p$g
prompt=$g
rem The finished program will remove duplicates lines
:START
set "_duplicates=TRUE"
set "_infile=C:\alles.txt"
set "_oldstr=the"
set "_newstr=and"
call :BATCHSUBSTITUTE %_infile% %_oldstr% %_newstr%
pause
goto :SHOWINTELL
goto :eof
:BATCHSUBSTITUTE
type nul> %TEMP%.\TEMP.DAT
if "%~2"=="" findstr "^::" "%~f0"&GOTO:EOF
for /f "tokens=1,* delims=]" %%A in ('"type %1|find /n /v """') do (
set "_line=%%B"
if defined _line (
if "%_duplicates%"=="TRUE" (
set "_unconverted=!_line!"
set "_converted=!_line:"=""!"
FIND "!_converted!" %TEMP%.\TEMP.DAT > nul
if errorlevel==1 (
>> %TEMP%.\TEMP.DAT echo !_unconverted!
)
)
) ELSE (
echo(>> %TEMP%.\TEMP.DAT
)
)
goto :eof
:SHOWINTELL
#echo A|move %TEMP%.\TEMP.DAT C:\allesnietdubbel.txt
del C:\alles.txt
::Alle lijnen weggooien waar 'KB' in voor komt
type C:\allesnietdubbel.txt | findstr /V KB > C:\drivers\Final.txt
goto :eof
exit
Try next approach. Edited - saves output to a csv file (rfc4180 compliant):
#ECHO OFF
SETLOCAL EnableExtensions DisableDelayedExpansion
set "_csvfile=%TEMP%\%COMPUTERNAME%_39082171.csv" change to match your needs
> "%_csvfile%" (
rem (facultative, optional) CSV header
echo "version","displayname","comment"
call :getsw "HKLM\Software\Microsoft\Windows\CurrentVersion\Uninstall"
call :getsw "HKCU\Software\Microsoft\Windows\CurrentVersion\Uninstall"
call :getsw "HKLM\Software\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall"
)
ENDLOCAL
goto :eof
:getsw
for /F "delims=" %%g in ('reg query "%~1" 2^>NUL') do (
set "_swRegKey=%%~g"
set "_swName="
set "_swVers="
for /F "tokens=1,2,*" %%G in ('
reg query "%%~g" /V DisplayName 2^>NUL ^| findstr /I "DisplayName"
') do set "_swName=%%~I"
for /F "tokens=1,2,*" %%G in ('
reg query "%%~g" /V DisplayVersion 2^>NUL ^| findstr /I "DisplayVersion"
') do set "_swVers=%%~I"
call :echosw
)
goto :eof
:echosw
SETLOCAL EnableDelayedExpansion
if "%_swName%%_swVers%"=="" (
rem comment up next ECHO command if you don't require such information
ECHO "","","unknown !_swRegKey:HKEY_LOCAL_MACHINE=HKLM!"
) else (
echo "!_swVers!","!_swName!",""
)
ENDLOCAL
goto :eof
Sample output (largely narrowed down for demonstration here):
==> D:\bat\SO\39082171.bat
==> type "%TEMP%\%COMPUTERNAME%_39082171.csv"|findstr /I "comment KB unknown"
"version","displayname","comment"
"","","unknown HKLM\Software\Microsoft\Windows\CurrentVersion\Uninstall\Connection Manager"
"12.0.31101","Visual Studio 2013 Update 4 (KB2829760)",""
"12.0.30112","Update for Microsoft Visual Studio 2013 (KB2932965)",""
"1","Update for (KB2504637)",""
==>
Resources (required reading):
(command reference) An A-Z Index of the Windows CMD command line
(helpful particularities) Windows CMD Shell Command Line Syntax
(%~G, %~1 etc. special page) Command Line arguments (Parameters)
(special page) EnableDelayedExpansion
(2>NUL, 2>&1, | etc. special page) Redirection
(2^>NUL, ^| etc.) Escape Characters, Delimiters and Quotes

Batch file conditions - Execute next statement only if FOR loop is true

I built/adapted a script to uninstall any previous version of Java before it install a new one. The script goes as follows;
1 - Uninstall any previous version of JAVA
SET regVar32=HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\WinDOws\CurrentVersion\Uninstall
SET regVar64=HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\WinDOws\CurrentVersion\Uninstall\
SET myCMD=REG QUERY %regVar32% /s /f *java*
FOR /f " usebackq delims={} tokens=2" %%i IN (`%myCMD%`) DO ( msiexec /x {%%i} /qn /norestart )
SET myCMD=REG QUERY %regVar64% /s /f *java*
FOR /f " usebackq delims={} tokens=2" %%i IN (`%myCMD%`) DO ( msiexec /x {%%i} /qn /norestart )
2 - Clean registry
3 - Clean files and folders
4 - install new version of JAVA
The problem is that the script doesn't have any condition and if the routine 1 doesn't find anything to uninstall it will continue to execute the others subroutines.
What I want to be able to do is that if routine number 1 above doesn't have anything to uninstall GOTO :INSTALL and install the new JAVA without running 2 and 3.
I hope I explained myself clear enough ;-) thank you in advance for any help.
(for /f .... do (msiexec .... )) || goto :install
If the for command does not find any line to process, it raises errorlevel. Using conditional execution you can detect it and directly jump to the required label.
In other words, you want to know if the two for commands in step 1-Uninstall processed any file. You may do that this way:
SET anyFileUninstalled=false
SET myCMD=REG QUERY %regVar32% /s /f *java*
FOR /f " usebackq delims={} tokens=2" %%i IN (`%myCMD%`) DO (
msiexec /x {%%i} /qn /norestart
SET anyFileUninstalled=true
)
SET myCMD=REG QUERY %regVar64% /s /f *java*
FOR /f " usebackq delims={} tokens=2" %%i IN (`%myCMD%`) DO (
msiexec /x {%%i} /qn /norestart
SET anyFileUninstalled=true
)
if %anyFileUninstalled% neq true goto install
So I finally was able to get it right with some help from you guys here. Here is how it ended up;
ECHO -------------------------------------------------------
ECHO UNISTALL ANY PREVIOUS VERSIONS OF JAVA 32 Bit
ECHO -------------------------------------------------------
SET uinstallState=false
SET jver="Java 7"
SET regVar32=HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall
SET myCMD=REG QUERY %regVar32% /s /f %jver%
FOR /f " usebackq delims={} tokens=2" %%i IN (`%myCMD%`) DO (
SET uinstallState=true
ECHO Uninstall Key: {%%i}
ECHO Condition: %uinstallState%
)
ECHO -------------------------------------------------------
ECHO UNISTALL ANY PREVIOUS VERSIONS OF JAVA 64 Bit
ECHO -------------------------------------------------------
SET uinstallState=false
SET jver="Java 7"
SET regVar64=HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\
SET myCMD=REG QUERY %regVar64% /s /f %jver%
FOR /f " usebackq delims={} tokens=2" %%i IN (`%myCMD%`) DO (
SET uinstallState=true
ECHO Uninstall Key: {%%i}
ECHO Condition: %uinstallState%
)
IF %uinstallState% NEQ true GOTO INSTALL
So now it will Skip the subroutine 2 and 3 and go straight to INSTALL if there is nothing to uninstall. :-)
Thank you all for the help.

Issues with batch file to search registry and edit

I'm not so new to batch scripting and have done a small amount of scripts for various other things but this script has stumped me.
I've actually pulled this idea from somewhere else as I'm not that deep into the for commands just yet.
What I'm trying to do with this script is search every subkey within the HKU rootkey for a specific subkey path. If that subkey path exists it'll modify a key value within that subkey path. But it seems to keep failing with no error.
This is what I have right now:
for /f %%a in ('reg query hku') do call :loop1 %%a
goto :end
:loop1
for /f %1 in (reg query %1\software\microsoft\dynamics) do call :loop2 %%b
goto :end
:loop2
if Errorlevel 1 goto :error
reg add %1\6.0\configuration /v configurationfile /t reg_sz /d \ /f
goto :end
:error
echo Error has occurrd.
goto :end
:end
Pause
When I run this batch I get the following.
c:\Users\-username-\Desktop\test>for /F %a in ('reg query hku') do call :loop1 %a
c:\Users\-username-\Desktop\test>call :loop1 HKEY_USERS\.DEFAULT
c:\Users\-username-\Desktop\test>for /f HKEY_USERS\.DEFAULT in (reg query HKEY_USER
S\.DEFAULT\software\microsoft\dynamics) do call :loop2 %b
c:\Users\-username-\Desktop\test>
It seems like it just stops running? when I check the errorlevel after it runs it returns "0" so I'd think I'd at least see the error message come up?
Am I missing something small I'm just looking over?
Run this to start with - see if what it returns is helpful to you:
This may need a later version of Windows - I'm not sure of the reg query options for earlier windows.
#echo off
for /f "delims=" %%a in ('reg query hku /s /f data /k ^| find /i "\software\microsoft\dynamics" ') do echo "%%a"
You need GOTO :eof to return from the subroutines.
for /f %%a in ('reg query hku') do call :loop1 "%%a"
pause
goto :eof
:loop1
for /f "%~1" in (reg query "%~1\software\microsoft\dynamics") do call :loop2 "%%b"
goto :eof
:loop2
if Errorlevel 1 echo Error has occurred. & pause & exit /B 1
reg add "%~1\6.0\configuration /v configurationfile" /t reg_sz /d \ /f
goto :eof
I found the bug(s). It was two places. RGuggiesberg, you are right. I needed the EOF in there. As foxidrive points out, the first line of "loop1" had some syntax issues. I was confusing myself.
Replaced:
for /f %1 in ('reg query %1\software\microsoft\dynamics') do call :loop2 %%b
with:
for /f %%b in ('reg query %1\software\microsoft\dynamics') do call :loop2 %%b
Now it's working fine. Thanks for the pointers!

Adding /? switch in batch?

Do someone knows how to add the action to be triggered when calling my batch file with the /? argument ? I've always used the -h to display usages, but for once I need my -h arg for something else.
EDIT : Actually I've tried by parsing attributes like this
for %%i in (%*) do ....
But the /? argument was skipped, I'll try yours solutions to see if it's different.
Btw, why when you parse %%i the /? args is skipped ?
The /? seems to be simply skipped by the for %%i in (%*) but it's the wildcard functionality of the for-loop, it tries to find a file that matches /? which will fail.
You can not use ? or * in a "normal" for-loop, without modifying the result.
You could use the SHIFT command to access all your parameters.
:parameterLoop
if "%~1"=="/?" call :help
if "%~1"=="-h" call :help
if "%~1"=="-o" call :other
shift
if not "%~1"=="" goto :parameterLoop
If you also want to display the selected option, you got a problem with the echo command, as this will normally show the help instead of /?.
You can avoid this by using echo(%1 instead of echo %1.
You check your command line arguments (%1, %2 etc) against the /? string and if true then print help using ECHO command. For example,
#ECHO OFF
IF "%1"=="/?" (
ECHO "Help Line 1"
ECHO "Help Line 2"
) ELSE (
ECHO "Do Your Action"
)
You could try this:
#echo off
if "%1"=="/?" goto print_help
goto normal_start
:print_help
echo Here is your help
goto end
:normal_start
echo I'm working
:end
Here's an actual use case for those visuals out there!
#ECHO OFF
:parameterLoop
IF /I "%1"=="/install" GOTO install
IF /I "%1"=="/uninstall" GOTO uninstall
IF /I "%1"=="/repair" GOTO repair
IF /I "%1"=="" (
ECHO.
ECHO Please use the following commands to proceed:
ECHO.
ECHO Use /INSTALL to setup the software
ECHO.
ECHO Use /UNINSTALL to remove the software
ECHO.
ECHO Use /REPAIR to repair the software
ECHO.
GOTO end
)
:install
TASKKILL /F /IM vpnui* /T
TASKKILL /F /IM DartOffline* /T
MSIEXEC /I "anyconnect-win-XXX-core-vpn-predeploy-k9.msi" /QN /NORESTART
MSIEXEC /I "anyconnect-win-XXX-dart-predeploy-k9.msi" /QN /NORESTART
MSIEXEC /I "anyconnect-win-XXX-posture-predeploy-k9.msi" /QN /NORESTART
COPY /Y "production.xml" "%ProgramData%\Cisco\Cisco AnyConnect Secure Mobility Client\Profile\production.xml"
GOTO end
:uninstall
TASKKILL /F /IM vpnui* /T
TASKKILL /F /IM DartOffline* /T
DEL /F /S /Q "%ProgramData%\Cisco\Cisco AnyConnect Secure Mobility Client\Profile\production.xml"
MSIEXEC /X "anyconnect-win-XXX-core-vpn-predeploy-k9.msi" /QN /NORESTART
MSIEXEC /X "anyconnect-win-XXX-dart-predeploy-k9.msi" /QN /NORESTART
MSIEXEC /X "anyconnect-win-XXX-posture-predeploy-k9.msi" /QN /NORESTART
RMDIR /S /Q "%ProgramData%\Cisco\Cisco AnyConnect Secure Mobility Client"
GOTO end
:repair
TASKKILL /F /IM vpnui* /T
TASKKILL /F /IM DartOffline* /T
DEL /F /S /Q "%ProgramData%\Cisco\Cisco AnyConnect Secure Mobility Client\Profile\production.xml"
MSIEXEC /X "anyconnect-win-XXX-core-vpn-predeploy-k9.msi" /QN /NORESTART
MSIEXEC /X "anyconnect-win-XXX-dart-predeploy-k9.msi" /QN /NORESTART
MSIEXEC /X "anyconnect-win-XXX-posture-predeploy-k9.msi" /QN /NORESTART
RMDIR /S /Q "%ProgramData%\Cisco\Cisco AnyConnect Secure Mobility Client"
MSIEXEC /I "anyconnect-win-XXX-core-vpn-predeploy-k9.msi" /QN /NORESTART
MSIEXEC /I "anyconnect-win-XXX-dart-predeploy-k9.msi" /QN /NORESTART
MSIEXEC /I "anyconnect-win-XXX-posture-predeploy-k9.msi" /QN /NORESTART
COPY /Y "production.xml" "%ProgramData%\Cisco\Cisco AnyConnect Secure Mobility Client\Profile\production.xml"
GOTO end
:end
EXIT /B
REM Src https://stackoverflow.com/questions/8179425/adding-switch-in-batch
Essentially with that command I can install my software using the /install or /uninstall or /repair switches... way useful in intune and making custom MSI's with AdvancedInstaller!
Also if you type nothing a little help menu appears instructing the user which commands are available :)

Resources