0

I am attempting to create a batch script that will query the registry for uninstall packages. The goal is to create a batch script that will uninstall all VNC programs (UltraVNC, RealVNC, and TightVNC). This must be compatible with both Windows XP and Windows 7.

I started with the script from this StackOverflow solution Reg Query script for batch script . I am trying to alter the code to allow it to search for "VNC" in the DisplayName, strip the text between the {} in its corresponding UninstallPath, and then run msiexec.exe /qn /x {package-identifier} to silently uninstall the program.

When running the following code, it retrieves several programs that do not contain "VNC" in their DisplayName. The issue appears to lie in the following line of code:

if not "x!str1:VNC=!"=="x!str1!" (

Source of this line of code: How can I check if a variable contains another variable within a windows batch file?

I have tried the following code found at as an alternative, but it also listed way too many packages and did not properly pick only packages with "VNC" in their names.

set str1 = !product[%counter%]!
echo str1 > temp.dat
findstr /c:"VNC" "temp.dat" >nul 2>&1
if %errorlevel% == 0 (

Note: Many of the echo commands are there simply for testing purposes.

 @echo off
    setlocal
    set regVar=HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall
    set excluded=/c:" Microsoft" /c:"MDOP" /c:"Dell" 
    set count=1
    for /f "tokens=1,2,*" %%a in ('Reg Query %regVar% /S ^| findstr "DisplayName HKEY_ UninstallString"') do (
        setlocal EnableDelayedExpansion
        for %%n in (!count!) do (
            ENDLOCAL
            SET HKEY=Y
            IF "%%a"=="DisplayName" SET "HKEY="&set product[%%n]=%%c
            IF "%%a"=="UninstallString" SET "HKEY="&IF NOT DEFINED uninstall[%%n] set uninstall[%%n]=%%c
            IF "%%a"=="QuietUninstallString" SET "HKEY="&IF NOT DEFINED uninstall[%%n] set uninstall[%%n]=%%c
        IF DEFINED hkey IF DEFINED product[%%n] IF defined uninstall[%%n] SET /a count+=1&SET "hkey="
        IF DEFINED hkey set "product[%%n]="&SET "uninstall[%%n]="
        )
    )

    IF NOT DEFINED product[%count%] SET "uninstall[%count%]="&SET /a count-=1
    IF NOT DEFINED uninstall[%count%] SET "product[%count%]="&SET /a count-=1
    ECHO %count% entries found
    set counter=%count%
    pause
    @setlocal enableextensions enabledelayedexpansion
    :while
    if %counter% GTR 0 (
        set str1 = !product[%counter%]!
        echo str1
        if not "x!str1:VNC=!"=="x!str1!" (
            echo !product[%counter%]!
            echo !uninstall[%counter%]!
            set UninstallString=!uninstall[%counter%]!
            echo !UninstallString!
            set RunUninstall = ""
            for /f "tokens=2 delims={}" %%A in ("!uninstall[%counter%]!") do echo %%A REM set RunUninstall="msiExec.exe /qn /x{%%A}" (commented for testing purposes)
            call !RunUninstall!
            set /a counter-=1
            GOTO While
            ) Else (
            set /a counter-=1
            GOTO While
            )
        )

Output Snippet:

Intel(R) Network Connections 15.7.176.0
MsiExec.exe /X{26A24AE4-039D-4CA4-87B4-2F86418051F0}
MsiExec.exe /X{26A24AE4-039D-4CA4-87B4-2F86418051F0}
26A24AE4-039D-4CA4-87B4-2F86418051F0 REM set RunUninstall="msiExec.exe /qn /x{26
A24AE4-039D-4CA4-87B4-2F86418051F0}"
ECHO is off.
Microsoft .NET Framework 4.5.2
MsiExec.exe /X{26784146-6E05-3FF9-9335-786C7C0FB5BE}
MsiExec.exe /X{26784146-6E05-3FF9-9335-786C7C0FB5BE}
26784146-6E05-3FF9-9335-786C7C0FB5BE REM set RunUninstall="msiExec.exe /qn /x{26
784146-6E05-3FF9-9335-786C7C0FB5BE}"
ECHO is off.
Lenovo ThinkVantage Toolbox
MsiExec.exe /I{23170F69-40C1-2702-0920-000001000000}
MsiExec.exe /I{23170F69-40C1-2702-0920-000001000000}
23170F69-40C1-2702-0920-000001000000 REM set RunUninstall="msiExec.exe /qn /x{23
170F69-40C1-2702-0920-000001000000}"
ECHO is off.
OSFMount v1.5
MsiExec.exe /I{1B8ABA62-74F0-47ED-B18C-A43128E591B8}
MsiExec.exe /I{1B8ABA62-74F0-47ED-B18C-A43128E591B8}
1B8ABA62-74F0-47ED-B18C-A43128E591B8 REM set RunUninstall="msiExec.exe /qn /x{1B
8ABA62-74F0-47ED-B18C-A43128E591B8}"

UPDATE: I modified the code provided by wOxxOm in an attempt to make an exception for TightVNC and uninstall it quietly. Since there is not a QuietUninstallString in the registry for TightVNC, I am attempting to accomplish this by utilizing the msiexec.exe /qn /x options. However it keeps throwing the following error:

else was unexpected at this time.

My modified version of wOxxOm's code is listed below:

@echo off
setlocal enableDelayedExpansion
for %%a in ("" "\Wow6432Node") do (
    for /f "delims=" %%b in ('
        reg query HKLM\SOFTWARE%%~a\Microsoft\Windows\CurrentVersion\Uninstall ^
            /s /d /f "VNC" ^| findstr "HKEY_ DisplayName"
    ') do (
        set "line=%%b"
        if "!line:~0,4!"=="HKEY" (
            set "key=!line!"
        ) else (
            set Uninstall=
            rem Sort /r makes QuietUninstallString the last line
            for /f "tokens=2*" %%c in ('
                reg query "!key!" ^| find "UninstallString" ^| sort /r
            ') do if not "%%d"=="" set "Uninstall=%%d"

            if defined Uninstall (

                for /f "tokens=2*" %%c in ("!line!") do (
                    set product=%%d
                    if "x!product:TightVNC=!"=="x!product!" (
                        for /f "tokens=2 delims={}" %%A in ("!Uninstall!") do (
                        echo Found !product!
                        Running msiExec.exe /qn /x{%%A} REM (COMMENTED FOR TESTING)
                        REM CALL msiExec.exe /qn /x{%%A}
                        )
                    ) else (
                    echo Found %%d
                    echo Running !Uninstall! (COMMENTED FOR TESTING)
                    rem call !Uninstall!
                    echo.
                    )
                )
           )
        )
    )
Community
  • 1
  • 1
MattSec
  • 3
  • 5
  • Is it a requirement to use the registry and call msiexec? I mean, maybe a better approach could be to use WMIC commands: i.e. you can use a command like `wmic product where "Name like '%VNC%'" get Name, Version` to list installed software containing VNC in the name, and then use a command like `wmic product where "Name like '%VNC%'" call uninstall /nointeractive` to uninstall the application. – Wayfarer Oct 23 '15 at 09:52

2 Answers2

0
  1. Don't use spaces around = in set str1=!product[%counter%]!
  2. Instead of if %counter% GTR 0 ( which doesn't work and makes the loop infinite)
    use if %counter%==0 goto done and a :done label after the loop
  3. With quotes you don't need to add x to the comparison.
  4. Don't forget about 64-bit Windows and check Wow6432Node tree too (see the alternative code)

:while
if %counter%==0 goto done
set str1=!product[%counter%]!
if not "!str1:VNC=!"=="!str1!" (
    ..............................
    rem call !RunUninstall!
)
set /a counter-=1
GOTO While

:done

Alternatively you can make the batch file much faster (the "arrays" are slow in case of many strings) by listing only the products with VNC in DisplayName first and then fetch the UninstallString:

@echo off
setlocal enableDelayedExpansion
for %%a in ("" "\Wow6432Node") do (
    for /f "delims=" %%b in ('
        reg query HKLM\SOFTWARE%%~a\Microsoft\Windows\CurrentVersion\Uninstall ^
            /s /d /f "VNC" ^| findstr "HKEY_ DisplayName"
    ') do (
        set "line=%%b"
        if "!line:~0,4!"=="HKEY" (
            set "key=!line!"
        ) else (
            set Uninstall=
            rem Sort /r makes QuietUninstallString the last line
            for /f "tokens=2*" %%c in ('
                reg query "!key!" ^| find "UninstallString" ^| sort /r
            ') do if not "%%d"=="" set "Uninstall=%%d"

            if defined Uninstall (
                for /f "tokens=2*" %%c in ("!line!") do echo Found %%d
                echo Running !Uninstall! (COMMENTED FOR TESTING)
                rem call !Uninstall!
                echo.
            )
        )
    )
)
pause
wOxxOm
  • 65,848
  • 11
  • 132
  • 136
  • Thank you, wOxxOm! Your code is more efficient and compact. Its an impressive use of nesting, as well. Next I am going to try to modify the code to create an exception for TightVNC which does not have an entry for QuietUninstallString in the registry - utilizing the /qn /x msiexec.exe options. – MattSec Oct 22 '15 at 15:56
  • @MattSec, if you're talking about the alternative code, it *prefers* `QuietUninstallString` but will use `UninstallString` in the absence of the former. – wOxxOm Oct 22 '15 at 16:59
  • Yeah, it did that for me as well when I tested the code. I want TightVNC to run in quiet mode, which is supported using msiexec.exe options, but there is no QuietUninstallString defined in the registry. I edited the code to attempt to do this, but it keeps returning an error stating `else was unexpected at this time`. I am adding the modified code to my original question, if you are interested in helping me fix it again. – MattSec Oct 22 '15 at 20:39
  • @MattSec, 1) forgot `echo` before `Running` 2) Don't use unescaped parentheses in comments inside `()` blocks: either remove them of prepend each with `^` and 3) there's no closing `)` in your posted code, hopefully it's just a miss with selection while pasting. – wOxxOm Oct 22 '15 at 20:55
  • I think the missing parenthesis was a pasting error. The code ran as expected after prepending the parenthesis with ^ to escape them. Thanks again! – MattSec Oct 22 '15 at 21:22
0

Modifying wOxxOm's code, I was able to create the following code to quietly uninstall TightVNC, UltraVNC, and RealVNC. It will also start the uninstaller for any other software with "VNC" in the DisplayName in the Windows registry under HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall and HKLM\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall.

Hopefully this is handy to someone else out there as well.

@echo off
setlocal enableDelayedExpansion
for %%a in ("" "\Wow6432Node") do (
    for /f "delims=" %%b in ('
        reg query HKLM\SOFTWARE%%~a\Microsoft\Windows\CurrentVersion\Uninstall ^
            /s /d /f "VNC" ^| findstr "HKEY_ DisplayName"
    ') do (
        set "line=%%b"
        if "!line:~0,4!"=="HKEY" (
            set "key=!line!"
        ) else (
            set Uninstall=
            rem Sort /r makes QuietUninstallString the last line
            for /f "tokens=2*" %%c in ('
                reg query "!key!" ^| find "UninstallString" ^| sort /r
            ') do if not "%%d"=="" set "Uninstall=%%d"

            if defined Uninstall (

                for /f "tokens=2*" %%c in ("!line!") do (
                    set product=%%d
                    if NOT "x!product:TightVNC=!"=="x!product!" (
                        for /f "tokens=2 delims={}" %%A in ("!Uninstall!") do (
                        echo Found !product!
                        CALL msiExec.exe /qn /x{%%A}
                        echo.
                        )
                    ) else (
                        if NOT "x!product:UltraVNC=!"=="x!product!" (
                            for /f "tokens=1 delims=." %%A in ("!Uninstall!") do (
                                echo Found !product!
                                CALL %%A.exe" /VERYSILENT /NORESTART
                                echo.
                            )
                            ) else (
                                if NOT "x!Uninstall:RealVNC=!"=="x!Uninstall!" (
                                            for /f "tokens=1 delims=." %%A in ("!Uninstall!") do (
                                            echo Found !product!
                                            CALL %%A.exe" /VERYSILENT
                                            echo.
                                        )
                                    ) else (
                                        echo Found %%d
                                        CALL !Uninstall!
                                        echo.
                                )
                            )
                        )
                    )
                )
           )
        )
    )
MattSec
  • 3
  • 5