-2

I'm attempting to write a batch script that will search the registry and add the value of the UninstallString within a key into a variable.
There are a few caveats:

  1. The keys may be different on different workstations (depends on installer used, multiple modified MSI versions exist for samesoftware version)
  2. There is the main product with patches installed
  3. The patches must be uninstalled first before the main product

For example, the Cisco Supervisor Desktop software may have the following keys:

Patch 3
KEY: HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall{981E3887-9D55-4B91-B643-7155AA98C906}
DisplayName value: Cisco Desktop Services 8.5(4) Maintenance Release 4 Engineering Special 6
UninstallString value: MsiExec.exe /X{981E3887-9D55-4B91-B643-7155AA98C906}

Patch 2
KEY: HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall{4FA5AFA8-FDEB-43C9-83B7-43092593ACDF}
DisplayName value: Cisco Desktop Services 8.5(4) Maintenance Release 4 Engineering Special 4
UninstallString value: MsiExec.exe /X{4FA5AFA8-FDEB-43C9-83B7-43092593ACDF}

Patch 1:
KEY: HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall{CA941834-837E-44C2-BF83-E7E7558FDD61}
DisplayName value: Cisco Desktop Services 8.5(4) Maintenance Release 4
UninstallString value: MsiExec.exe /X{CA941834-837E-44C2-BF83-E7E7558FDD61}

Main product:
KEY: HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall
DisplayName value: Cisco Supervisor Desktop
UninstallString value: MsiExec.exe /X{AB60EBDC-45A9-4764-96CB-EFCE4AD0C10B}

They must be uninstalled in that order. There is also the potential for other keys to be in the registry when multiple versions are installed.

I would think a search function could be created for the patches using DisplayName value Cisco Desktop Services since it's common for all the patches then a separate search for the Cisco Supervisor Agent.

I currently have WMIC commands but sometimes they can be extremely slow to run while if I manually run the UninstallString value it completes quickly. I have also had instances where the WMIC command will not uninstall the product when the UninstallString value will.

Nimantha
  • 6,405
  • 6
  • 28
  • 69
Brian S
  • 21
  • 3
  • 1
    `reg` utility based method is the fastest indeed, take a look at [How can I automatically uninstall all programs containing "VNC" in their displayname using a batch file?](http://stackoverflow.com/a/33279973) if you can tweak it it yourself, – wOxxOm Nov 20 '15 at 17:51
  • Thank you. That appears to work great for finding the uninstall strings. Do you know of a way to arrange the uninstalls so they will uninstall in a particular order? – Brian S Nov 20 '15 at 19:16
  • I guess there could be many ways. For example you can make an "array" with all the uninstall strings – wOxxOm Nov 20 '15 at 19:42

1 Answers1

0

Based on the suggestion by @wOxxOm in the comments (looking through How can I automatically uninstall all programs containing "VNC" in their displayname using a batch file? and using an array), I have taken the code, modified it, and was able to export the DisplayName and UninstallString lists into text files. I have also been able to sort the DisplayName list correctly but I have not been able to get the corresponding UninstallString to sort in the same order. For example, the unsorted DisplayName list is listed as 2, 3, 1. I can get it sorted as 3, 2, 1 using sort /r. But if I sort the UninstallString list with sort /r I get a sorted list of 1, 3, 2.

app.txt    
2 Cisco Desktop Services 8.5(4) Maintenance Release 4 Engineering Special 4 
3 Cisco Desktop Services 8.5(4) Maintenance Release 4 Engineering Special 6 
1 Cisco Desktop Services 8.5(4) Maintenance Release 4 

app_sorted.txt
3 Cisco Desktop Services 8.5(4) Maintenance Release 4 Engineering Special 6 
2 Cisco Desktop Services 8.5(4) Maintenance Release 4 Engineering Special 4 
1 Cisco Desktop Services 8.5(4) Maintenance Release 4 

un.txt    
2 MsiExec.exe /X{4FA5AFA8-FDEB-43C9-83B7-43092593ACDF}
3 MsiExec.exe /X{981E3887-9D55-4B91-B643-7155AA98C906}
1 MsiExec.exe /X{CA941834-837E-44C2-BF83-E7E7558FDD61}

un_sorted.txt    
1 MsiExec.exe /X{CA941834-837E-44C2-BF83-E7E7558FDD61}
3 MsiExec.exe /X{981E3887-9D55-4B91-B643-7155AA98C906}
2 MsiExec.exe /X{4FA5AFA8-FDEB-43C9-83B7-43092593ACDF}

The un_sorted.txt needs to be:    
3 MsiExec.exe /X{981E3887-9D55-4B91-B643-7155AA98C906}
2 MsiExec.exe /X{4FA5AFA8-FDEB-43C9-83B7-43092593ACDF}
1 MsiExec.exe /X{CA941834-837E-44C2-BF83-E7E7558FDD61}

The #'s at the beginning of each line is the order of original installation as they MUST be uninstalled in reverse order. The #'s are for reference.

I would like to be able to do this without the txt files if possible.

Here is the modified code:

@echo off
setlocal enableDelayedExpansion
::Build array
for %%a in ("" "\Wow6432Node") do (
    for /f "delims=" %%b in ('
        reg query HKLM\SOFTWARE%%~a\Microsoft\Windows\CurrentVersion\Uninstall ^
            /s /d /f "Cisco Desktop" ^| findstr "HKEY_ DisplayName" ^| sort /r
    ') 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 app=%%d
                echo !app! >> C:\Test\app1.txt
                echo !app!,!Uninstall! >> C:\Test\un1.txt
                )
            )
        )
    )
)
sort /r < C:\Test\app.txt > C:\Test\app_sorted.txt

EDIT: If I do ^| sort /r to the DisplayName find line, I will get the DisplayName results I am looking for but it repeats the same UninstallString for each DisplayName listed:

un.txt
3 Cisco Desktop Services 8.5(4) Maintenance Release 4 Engineering Special 6,MsiExec.exe /X{4FA5AFA8-FDEB-43C9-83B7-43092593ACDF}    
2 Cisco Desktop Services 8.5(4) Maintenance Release 4 Engineering Special 4,MsiExec.exe /X{4FA5AFA8-FDEB-43C9-83B7-43092593ACDF}    
1 Cisco Desktop Services 8.5(4) Maintenance Release 4,MsiExec.exe /X{4FA5AFA8-FDEB-43C9-83B7-43092593ACDF} 
Nimantha
  • 6,405
  • 6
  • 28
  • 69
Brian S
  • 21
  • 3
  • I know that I could add the DisplayName as a list right in the script and would work great, but it wouldn't help for those workstations that have an older version installed and I may not know the list without looking at it. Then I'd have to modify the script for the different list. Not what I want to do. – Brian S Nov 27 '15 at 13:20