31290

WMIC uninstaller

3 posts in this topic

Hello everyone, 

I'm working on a WMIC uninstaller. A quite simple one with a button to display product names in a editable list (for copy/paste purposes) but the main problem is that in order to achieve this, in my corporation, normal users cannot uninstall softs.

What I found/adapt so far:

#include <ButtonConstants.au3>
#include <ComboConstants.au3>
#include <EditConstants.au3>
#include <GUIConstantsEx.au3>
#include <StaticConstants.au3>
#include <WindowsConstants.au3>

$Form1 = GUICreate("wmic uninstaller", 300, 152, 337, 380)

$Label1 = GUICtrlCreateLabel("Computername", 0, 8, 75, 17)
$Input1 = GUICtrlCreateInput(@ComputerName, 0, 32, 125, 21)

$Label2 = GUICtrlCreateLabel("wmic command", 150, 8, 77, 17)
$Combo1 = GUICtrlCreateCombo("Model_Computer", 150, 32, 125, 25, BitOR($CBS_DROPDOWN,$CBS_AUTOHSCROLL))

GUICtrlSetData(-1, "Current_user|Installed_Apps|Serial_Number|Bios_Version")

$Button1 = GUICtrlCreateButton("List Apps", 150, 72, 91, 49)

While 1
    $nMsg = GUIGetMsg()
    Switch $nMsg
        Case $GUI_EVENT_CLOSE
            Exit
         case $button1
            $wmi = GUICtrlRead($combo1)
            $pc = GUICtrlRead($input1)
            call($wmi,$pc)

    EndSwitch
 WEnd
 
 Func Model_Computer($pc)
RunWait(@ComSpec & ' /c ' & 'wmic /node:' & $pc &' product get name > %temp%\apps.txt' ,"", @SW_HIDE)
$file=(@TempDir & "/apps.txt")
$fileread= FileRead($file)
MsgBox(0, $pc , $fileread)
FileDelete(@TempDir & "/apps.txt")
EndFunc

Here's the textual version I gave to my techs:

Create cmd shortcut on Desktop, run it as a different user (using their own admin accounts).
Once opened, type wmic
Once wmic loaded, type product get name
Wait for the list of installed soft to display
Type product where name="Exact App name" call uninstall
Type "Y" to confirm
Wait for task execution
Don't care about exit code
App is uninstalled (verified by getting the list again)!

In fact, I'd like to automatize this process.

Any ideas over here? :)

Thanks ^^


~~~ Doom Shall Never Die, Only The Players ~~~

Share this post


Link to post
Share on other sites



This is what I use, you could easily wrap a GUI around it:

#include <MsgBoxConstants.au3>

$sName = InputBox("Uninstall Wizard", "Please type the first few letters of the application name to search")
$oWMI = ObjGet("winmgmts:{impersonationLevel=impersonate}!\\" & @ComputerName & "\root\cimv2")
$aProducts = $oWMI.ExecQuery("Select * from Win32_Product Where Name LIKE '%" & $sName & "%'")

For $app in $aProducts
    $popup = MsgBox($MB_YESNOCANCEL, "Uninstall Wizard", "Would you like to uninstall " & $app.Name & "?")
        If $popup = $IDYES Then
            $app.Uninstall()
        ElseIf $popup = $IDCANCEL Then
            ExitLoop
        EndIf
Next

 

1 person likes this

When you're dead, you don't know you're dead - it's only difficult for those that know you. It's the same way when you're stupid...

My Scripts: SCCM UDFInclude Source with Compiled Script, Windows Firewall UDF

Share this post


Link to post
Share on other sites

Hell yeah! :) 

That's just awesome. No need to user admin credentials or so... Your core have done my script! Piece of cake now :) 

Thanks a lot for that :)

 


~~~ Doom Shall Never Die, Only The Players ~~~

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!


Register a new account

Sign in

Already have an account? Sign in here.


Sign In Now

  • Similar Content

    • FMS
      By FMS
      Hello,
      I've some troubles whit the run command.
      Below u see 2 command's , 1 is working and the other not. (the first isn't working)
      I think the problem is in te space between program and files.Also I've treid every thing i could think of or the helpfiles handed to me.
      (or maybe I din't find the correct answer:))
      I tried so mush that i don't know anymore if it's the space between program files or not.
      Could somebody point me in the right direction?
      Not working:
      Run(@ComSpec & " /c psexec -i \\127.0.0.1 -u username -p pass -h -d /accepteula C:\Program Files\some_prog\Shell.exe" ,"C:\tools", @SW_HIDE) Working :
      Run(@ComSpec & " /c psexec -i \\127.0.0.1 -u username -p pass /accepteula cmd" , "C:\tools" , @SW_HIDE)  
       
       
       
       
       
       
    • FMS
      By FMS
      hello,
      I'm trying to make a check if a process is running on a remote PC.
      This is what i got this far when I edit a found snippet on this forum.
       
      The function _CMDreturn returns the output of the command line command.
      In this output I want to scan if there is a line whit "process mspaint was not found".
      This I'm trying to do whit StringLeft.
      The problem is that I don't get any error's and also don't get a message if it doesn't exist.
      Could somebody say to me what I'm doing wrong here?
      Or iff there is a better way to do this?
      Thanks in advanced.
       
      #include <Constants.au3> $result= _CMDreturn('C:\Tools\Ps\pslist.exe mspaint') msgbox(0,"Version",$result) Func _CMDreturn($sCommand) $cmdreturn = "" $stream = Run(@ComSpec & " /c " & $sCommand, @SystemDir, @SW_HIDE, $STDOUT_CHILD + $STDIN_CHILD) While 1 $line = StdoutRead($stream) If @error Then ExitLoop If StringLeft($line, 32) = "process mspaint was not found on" Then msgbox(0,"not found",$line) EndIf $cmdreturn &= $line WEnd Return $cmdreturn EndFunc  
    • Eggsplorer
      By Eggsplorer
      Hi,
      I want to install chocolatey (https://chocolatey.org/) with AutoIt.
      I just need to send the following command to cmd:
      @powershell -NoProfile -ExecutionPolicy unrestricted -Command "(iex ((new-object net.webclient).DownloadString('https://chocolatey.org/install.ps1'))) >$null 2>&1" && SET PATH=%PATH%;%ALLUSERSPROFILE%\chocolatey\bin This is what I tried:
      RunWait(@ComSpec & " /C " "@powershell -NoProfile -ExecutionPolicy unrestricted -Command "(iex ((new-object net.webclient).DownloadString('https://chocolatey.org/install.ps1'))) >$null 2>&1" && SET PATH=%PATH%;%ALLUSERSPROFILE%\chocolatey\bin", ""); It didn't work propably because of the quotes.
      So I tried this:
      $code1 = "@powershell -NoProfile -ExecutionPolicy unrestricted -Command" $code2 = " (iex ((new-object net.webclient).DownloadString('https://chocolatey.org/install.ps1'))) >$null 2>&1" $code3 = " && SET PATH=%PATH%;%ALLUSERSPROFILE%\chocolatey\bin" RunWait(@ComSpec & " /C " & $code1 & $code2 & $code3, ""); Didn't work either.
      Any help?
      Thanks in advance =)
    • theak
      By theak
      Trying to make a script where it will run a command to show me the model name AND serial tag info on a laptop remotely and copy it to keyboard step by step. I know how to do this via WMIC but I'm curious how to create a CMD script out of it so I can just one click. So it would look something like....
      wmic csproduct get name *copy to clipboard* "Press enter to advance" [Enter] wmic csproduct get identifyingnumber *copy to clipboard* "Finished" Any ideas?
    • jguinch
      By jguinch
      Here is a small function that lists installed applications from the registry (uninstall keys). _UninstallList() allows to search on specific string in registry values.
      The feature supports x86 and x64, even if the program is compiled in 32 or 64 bits.
      Thanks for you comments and suggestions.
      ! NEW VERSION !
      Changes :
       - The function returns the installation date of each application (see remark)
       - $sCol parameter added : allows you to add columns in the returned array
      Remark : the installation date is retrieved from the InstallDate value in the registry. If this value does not exist, the InstallDate takes the last time at which the subkey was last written (great idea from JFX, thanks to him !)
      #include <Date.au3> ; needed for _UninstallList function ; Examples ########################################################################################################## #Include <Array.au3> ; Just for _ArrayDisplay Local $aList ; Lists all uninstall keys $aList = _UninstallList() _ArrayDisplay($aList, "All uninstall keys", Default, Default, Default, "RegistryPath|RegistrySubKey|DisplayName|Date") ; Lists all keys, where the publisher name (Publisher value) starts with "adobe" $aList = _UninstallList("Publisher", "Adobe") _ArrayDisplay($aList, "Adobe Publisher", Default, Default, Default, "RegistryPath|RegistrySubKey|DisplayName|Date") ; Lists all x86 keys only, where the name (DisplayName value) contains "flash" $aList = _UninstallList("DisplayName", "Flash", "", 1, 1) _ArrayDisplay($aList, "Flash (x86)", Default, Default, Default, "RegistryPath|RegistrySubKey|DisplayName|Date") ; Lists all keys matching a Java version (using a regular expression) $aList = _UninstallList("DisplayName", "(?i)Java \d+ Update \d+", "", 3) _ArrayDisplay($aList, "Java", Default, Default, Default, "RegistryPath|RegistrySubKey|DisplayName|Date") ; Lists all x64 keys only, where the quiet uninstall string (QuietUninstallString value) is set $aList = _UninstallList("QuietUninstallString", ".+", "QuietUninstallString", 3, 2) _ArrayDisplay($aList, "QuietUninstallString (x64)", Default, Default, Default, "RegistryPath|RegistrySubKey|DisplayName|Date|QuietUninstallString") ; List all x86 keys only, where the name (DisplayName value) start with "Autoit"  and retrieve the ; UninstallString, DisplayVersion values $aList = _UninstallList("DisplayName", "Autoit", "UninstallString|DisplayVersion", 0, 1) _ArrayDisplay($aList, "Autoit (x86)", Default, Default, Default, "RegistryPath|RegistrySubKey|DisplayName|Date|UninstallString|DisplayVersion") ; ################################################################################################################### ; #FUNCTION# ==================================================================================================================== ; Name ..........: _UninstallList ; Description ...: Returns an array of matching uninstall keys from registry, with an optional filter ; Syntax ........: _UninstallList([$sValueName = ""[, $sFilter = ""[, $sCols = ""[, $iSearchMode = 0[,$ iArch = 3]]]]]]) ; Parameters ....: $sValueName       - [optional] Registry value used for the filter. ;                                          Default is all keys ($sFilter do not operates). ;                  $sFilter          - [optional] String to search in $sValueName. Filter is not case sensitive. ;                  $sCols            - [optional] Additional values to retrieve. Use "|" to separate each value. ;                                          Each value adds a column in the returned array ;                  $iSearchMode      - [optional] Search mode. Default is 0. ;                                          0 : Match string from the start. ;                                          1 : Match any substring. ;                                          2 : Exact string match. ;                                          3 : $sFilter is a regular expression ;                  $iArch            - [optional] Registry keys to search in. Default is 3. ;                                          1 : x86 registry keys only ;                                          2 : x64 registry keys only ;                                          3 : both x86 and x64 registry keys ; Return values .: Returns a 2D array of registry keys and values : ;                      $array[0][0] : Number of keys ;                      $array[n][0] : Registry key path ;                      $array[n][1] : Registry subkey ;                      $array[n][2] : Display name ;                      $array[n][3] : Installation date (YYYYMMDD format) ;                      $array[n][4] : 1st additional value specified in $sCols (only if $sCols is set) ;                      $array[n][5] : 2nd additional value specified in $sCols (only if $sCols contains at least 2 entries) ;                      $array[n][x] : Nth additional value ... ; Author ........: jguinch ; =============================================================================================================================== Func _UninstallList($sValueName = "", $sFilter = "", $sCols = "", $iSearchMode = 0, $iArch = 3)     Local $sHKLMx86, $sHKLM64, $sHKCU = "HKCU\Software\Microsoft\Windows\CurrentVersion\Uninstall"     Local $aKeys[1] = [ $sHKCU ]     Local $sDisplayName, $sSubKey, $sKeyDate, $sDate, $sValue, $iFound, $n, $aResult[1][4], $iCol     Local $aCols[1] = [0]     If NOT IsInt($iArch) OR $iArch < 0 OR $iArch > 3 Then Return SetError(1, 0, 0)     If NOT IsInt($iSearchMode) OR $iSearchMode < 0 OR $iSearchMode > 3 Then Return SetError(1, 0, 0)     $sCols = StringRegExpReplace( StringRegExpReplace($sCols, "(?i)(DisplayName|InstallDate)\|?", ""), "\|$", "")     If $sCols <> "" Then $aCols = StringSplit($sCols, "|")     If @OSArch = "X86" Then         $iArch = 1         $sHKLMx86 = "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall"     Else         If @AutoitX64 Then             $sHKLMx86 = "HKLM\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall"             $sHKLM64 = "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall"         Else             $sHKLMx86 = "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall"             $sHKLM64 = "HKLM64\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall"         EndIf     EndIf     If BitAND($iArch, 1) Then         Redim $aKeys[ UBound($aKeys) + 1]         $aKeys [ UBound($aKeys) - 1] = $sHKLMx86     EndIf     If BitAND($iArch, 2) Then         Redim $aKeys[ UBound($aKeys) + 1]         $aKeys [ UBound($aKeys) - 1] = $sHKLM64     EndIf     For $i = 0 To UBound($aKeys) - 1         $n = 1         While 1             $iFound = 1             $aSubKey = _RegEnumKeyEx($aKeys[$i], $n)             If @error Then ExitLoop             $sSubKey = $aSubKey[0]             $sKeyDate = StringRegExpReplace($aSubKey[1], "^(\d{4})/(\d{2})/(\d{2}).+", "$1$2$3")             $sDisplayName = RegRead($aKeys[$i] & "\" & $sSubKey, "DisplayName")             $sDate = RegRead($aKeys[$i] & "\" & $sSubKey, "InstallDate")             If $sDate = "" Then $sDate = $sKeyDate             If $sDisplayName <> "" Then                  If $sValueName <> "" Then                     $iFound = 0                     $sValue = RegRead( $aKeys[$i] & "\" & $sSubKey, $sValueName)                     If ( $iSearchMode = 0 AND StringInStr($sValue, $sFilter) = 1 ) OR _                        ( $iSearchMode = 1 AND StringInStr($sValue, $sFilter) ) OR _                        ( $iSearchMode = 2 AND $sValue = $sFilter ) OR _                        ( $iSearchMode = 3 AND StringRegExp($sValue, $sFilter) ) Then                             $iFound = 1                     EndIf                 EndIf                 If $iFound Then                     Redim $aResult[ UBound($aResult) + 1][ 4 + $aCols[0] ]                     $aResult[ UBound($aResult) - 1][0] = $aKeys[$i]                     $aResult[ UBound($aResult) - 1][1] = $sSubKey                     $aResult[ UBound($aResult) - 1][2] = $sDisplayName                     $aResult[ UBound($aResult) - 1][3] = $sDate                     For $iCol = 1 To $aCols[0]                         $aResult[ UBound($aResult) - 1][3 + $iCol] = RegRead( $aKeys[$i] & "\" & $sSubKey, $aCols[$iCol])                     Next                 EndIf             EndIf             $n += 1         WEnd     Next     $aResult[0][0] = UBound($aResult) - 1     Return $aResult EndFunc ; #FUNCTION# ==================================================================================================================== ; Name ..........: _RegEnumKeyEx ; Description ...: Enumerates the subkeys of the specified open registry key. The function retrieves information about one subkey ;                  each time it is called. ; Syntax ........: _RegEnumKeyEx($sKey, $iInstance) ; Parameters ....: $sKey                - The registry key to read. ;                  $iInstance           - The 1-based key instance to retrieve. ; Return values .: Success              - A 1D array : ;                                          $aArray[0] = subkey name ;                                          $aArray[1] = time at which the enumerated subkey was last written ;                  Failure               - Returns 0 and set @eror to non-zero value ; Author ........: jguinch ; =============================================================================================================================== Func _RegEnumKeyEx($sKey, $iInstance)     If NOT IsDeclared("KEY_WOW64_32KEY") Then Local Const $KEY_WOW64_32KEY = 0x0200     If NOT IsDeclared("KEY_WOW64_64KEY") Then Local Const $KEY_WOW64_64KEY = 0x0100     If NOT IsDeclared("KEY_ENUMERATE_SUB_KEYS") Then Local Const $KEY_ENUMERATE_SUB_KEYS = 0x0008     If NOT IsDeclared("tagFILETIME") Then Local Const $tagFILETIME = "struct;dword Lo;dword Hi;endstruct"     Local $iSamDesired = $KEY_ENUMERATE_SUB_KEYS     Local $iX64Key = 0, $sRootKey, $aResult[2]     Local $sRoot = StringRegExpReplace($sKey, "\\.+", "")     Local $sSubkey = StringRegExpReplace($sKey, "^[^\\]+\\", "")     $sRoot = StringReplace($sRoot, "64", "")     If @extended Then $iX64Key = 1     If NOT IsInt($iInstance) OR $iInstance < 1 Then Return SetError(2, 0, 0)     Switch $sRoot         Case "HKCR", "HKEY_CLASSES_ROOT"             $sRootKey = 0x80000000         Case "HKLM", "HKEY_LOCAL_MACHINE"             $sRootKey = 0x80000002         Case "HKCU", "HKEY_CURRENT_USER"             $sRootKey = 0x80000001         Case "HKU", "HKEY_USERS"             $sRootKey = 0x80000003         Case  "HKCC", "HKEY_CURRENT_CONFIG"             $sRootKey = 0x80000005         Case Else             Return SetError(1, 0, 0)     EndSwitch     If StringRegExp(@OSArch, "64$") Then         If @AutoItX64 OR $iX64Key Then             $iSamDesired = BitOR($iSamDesired, $KEY_WOW64_64KEY)         Else             $iSamDesired = BitOR($iSamDesired, $KEY_WOW64_32KEY)         EndIf     EndIf     Local $aRetOPen = DllCall('advapi32.dll', 'long', 'RegOpenKeyExW', 'handle', $sRootKey, 'wstr', $sSubKey, 'dword', 0, 'dword', $iSamDesired, 'ulong_ptr*', 0)     If @error Then Return SetError(@error, @extended, 0)     If $aRetOPen[0] Then Return SetError(10, $aRetOPen[0], 0)     Local $hKey = $aRetOPen[5]     Local $tFILETIME = DllStructCreate($tagFILETIME)     Local $lpftLastWriteTime = DllStructGetPtr($tFILETIME)     Local $aRetEnum = DllCall('Advapi32.dll', 'long', 'RegEnumKeyExW', 'long', $hKey, 'dword', $iInstance - 1, 'wstr', "", 'dword*', 255, 'dword', "", 'ptr', "", 'dword', "", 'ptr', $lpftLastWriteTime)     If Not IsArray($aRetEnum) OR $aRetEnum[0] <> 0 Then Return SetError( 3, 0, 1)     Local $tFILETIME2 = _Date_Time_FileTimeToLocalFileTime($lpftLastWriteTime)     Local $localtime = _Date_Time_FileTimeToStr($tFILETIME2, 1)     $aResult[0] = $aRetEnum[3]     $aResult[1] = $localtime     Return $aResult EndFunc