Remove all versions of LogMeIn software - vbscript

I'm creating a VBScript to remove all found instances of LogMeIn Software. It seems to work installing but it is leaving the registry key. If I run the string manually from the cmd prompt it completely uninstalls, including removing the registry key. What do I need to do to not just execute the MSI uninstall but to also clean up the registry? Thank You
On Error Resume Next
Const HKEY_LOCAL_MACHINE = &H80000002
strComputer = "."
Set WshShell = CreateObject("Wscript.Shell")
Set oReg=GetObject("winmgmts:{impersonationLevel=impersonate}!\\" &_
strComputer & "\root\default:StdRegProv")
strKeyPath =
"SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall"
oReg.EnumKey HKEY_LOCAL_MACHINE, strKeyPath, arrSubKeys
For Each subkey In arrSubKeys
strDisplayName = WshShell.RegRead ("HKLM\" & strKeyPath & "\" & subkey
& "\Contact")
If InStr(1, strDisplayName, "LogMeIn") > 0 Then
' msgbox "C:\Windows\system32\msiexec.exe /norestart /X " & SubKey & "
/qn" ' Just for debugging
WScript.Sleep 20000
WshShell.Run "cmd /c C:\Windows\System32\msiexec.exe /X" & SubKey & "
/qn /L*V msilog.txt", 1, True
End If
Next

How many instances? Are they using the same upgrade code? You can uninstall all instances by the single upgrade code if so. Here is an example: Powershell: Uninstall application by UpgradeCode.
UPDATE: C# / .NET version.
There is also the Windows Installer PowerShell module from Heath Stewart.
Here is a proposed script inlined - I haven't tested it for reboot scenarios. Just leave the product open and uninstall and see if it triggers a reboot. Invoke via cscript.exe for silent running:
Const msiUILevelNone = 2
Const msiInstallStateAbsent = 2
Set installer = CreateObject("WindowsInstaller.Installer")
'installer.UILevel = msiUILevelNone ' Disabled to prevent silent uninstall. Now the UAC prompt will show
' Uninstall Orca, replace upgrade code with yours
Set products = installer.RelatedProducts("{UPGRADE-GUID-GOES-HERE-000000000000}")
For Each product In products
' MsgBox "Product Code: " & product ' Show the product code found, if you want
' The following call when run silently with admin rights may reboot the system without warning!
' This is due to badly authored MSI packages - most packages will not trigger this problem.
installer.ConfigureProduct product, 0, msiInstallStateAbsent ' Uninstall product
' See text above for info on the newer ConfigureProductEx method.
Next
Set installer = Nothing
MsgBox "Finished" ' Just so we know the script ran if nothing found to uninstall

Related

Trying to script a silent uninstall with VBScript

I am attempting to write a script to an uninstall of some applications. I have the script working, but every program throws up a prompt when run.
I know that the applications support the “/S” parameter so a silent uninstall can be done. I can run the uninstall /s command from a command prompt and it works fine. No prompts, it just uninstalls.
My problem is invoking the /S parameter in a script. No matter how I try, I keep getting syntax errors. I know this is just me and my non-understanding of quotes and parenthesis, but I’m sort of tired of trying to get it to work. The problem is compounded by the fact that all the paths have spaces in them, which necessitates more of those dang quotes.
Hopefully someone can show me what I am doing wrong.
Also, I really don’t know what I’m doing with VBS stuff, so I’d appreciate it if you could all overlook how ugly the script is. :-)
I also have a question about the “true” parameter. My understanding is that this indicates that the current operation should be completed before moving on to the next operation. But the uninstalls seem to run all at the same time. Am I understanding the “true” parameter correctly?
The command for a silent uninstall is:
C:\Program Files\Juniper Networks\Network Connect 7.1.9\uninstall.exe /S
Here is my script without the "/S' parameter.
'Uninstall Juniper Networks Network Connect 7.1.9
Wscript.Echo "Uninstalling 'Juniper Networks Network Connect 7.1.9'"
Dim objShell
Set objShell = WScript.CreateObject( "WScript.Shell" )
objShell.Run ("""C:\Program Files\Juniper Networks\Network Connect 7.1.9\uninstall.exe"""), 1, True
Set objShell = nothing
Here's my self-explainig solution:
' VB Script Document
'http://stackoverflow.com/questions/23569022/trying-to-script-a-silent-uninstall-with-vbscript
option explicit
Dim strResult
strResult = Wscript.ScriptName _
& vbTab & "Uninstalling 'Juniper Networks Network Connect 7.1.9'"
Dim strCommand, intWindowStyle, bWaitOnReturn, intRetCode
' strCommand
' String value indicating the command line you want to run.
' You must include any parameters you want to pass to the executable file.
strCommand = """C:\Program Files\Juniper Networks\Network Connect 7.1.9\uninstall.exe"" /S"
'for test only strCommand = """C:\Program Files\Mozilla Firefox\firefox.exe"" -safe-mode"
' intWindowStyle
' Optional. Integer value indicating the appearance of the program's window.
' Note that not all programs make use of this information.
intWindowStyle = 1
' bWaitOnReturn
' Optional. Boolean value indicating whether the script should wait
' for the program to finish executing before continuing
' to the next statement in your script.
' If set to true, script execution halts until the program finishes,
' and Run returns any error code returned by the program.
' If set to false (the default), the Run method returns 0 immediately
' after starting the program (not to be interpreted as an error code).
bWaitOnReturn = True
strResult = strResult & vbNewLine & strCommand _
& vbNewLine & CStr( intWindowStyle) _
& vbNewLine & CStr( bWaitOnReturn)
Wscript.Echo strResult
Dim objShell
Set objShell = WScript.CreateObject( "WScript.Shell" )
' intRetCode
' The Run method returns an integer
intRetCode = objShell.Run( strCommand, intWindowStyle, bWaitOnReturn)
Set objShell = nothing
Wscript.Echo strResult & vbNewLine & "result=" & CStr( intRetCode)
Wscript.Quit

Would you fix this vbs to execute this bat file with admin priviledge

Under windows 7 with uac activated.
This is all around an issue. THIS ISSUE:
upnphost excessive cpu load
Especifically:
Mine has this problem frequently, and I hate to go restart the upnphost service all the time, so instead i just created a task in the
task scheduler to run a once a day, and repeat every 5 minutes. The
task runs a .bat file:
net stop upnphost
net start upnphost
if you want to make it run in the background without the cmd window
coming up, run this .vbs with the above .bat already created as
"C:\upnphost.bat":
Set WshShell = CreateObject("WScript.Shell")
WshShell.Run chr(34) & "C:\upnphost.bat" & Chr(34), 0 Set
WshShell = Nothing
this way the upnphost service will automatically restart every 5
minutes with no visible presentation, so if it decides to misbehave
and go high cpu, it will be for 5 minutes tops, you could change this
to any interval you want.
Everything works except for the fact that for the bat to actually work i need to right click directly on the bat and execute as admin.
For that reason if i click the vbs it will execute it but not as admin and it wont work.
So scheduling it as a task wont work either.
Can you fix the code in the vbs:
Set WshShell = CreateObject("WScript.Shell")
WshShell.Run chr(34) & "C:\upnphost.bat" & Chr(34), 0 Set
WshShell = Nothing
So it executes the bat with admin priviledge.
It that matters, my route to the bat has spaces.
Respectfully
You can launch an program as an administrator with UAC enabled, but you'll still get prompted whether you want to launch this program. For example,
Set objSA = CreateObject ("Shell.Application")
objSA.ShellExecute "cmd.exe","uac","","runas",1
However,
I was able to use this vbscript to stop and restart this service using a scheduled task, setting the task to run as "Hidden" and run with the highest privileges.
strService = "upnphost"
strComputer = "."
Set objWMIService = GetObject("winmgmts:{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2")
Set colService = objWMIService.ExecQuery("SELECT Name FROM Win32_Service " _
& "where Name='" & strService & "'")
For Each objService In colService
return = objService.StopService()
return = objService.StartService()
Next
The scheduled task must be run as a user who can start and stop the service (usually an admin account) and with the option "Run with highest privileges" enabled.

VBScript Admin CMD Command Executed Remotely

Trying to execute a simple dns flush remotely from a machine, but for one reason or the other - I need to run the cmd as admin. The cmd runs fine under the account physically in person, but you need to do the whole right click -> run as admin bit.
Right now, remotePC is set to local or '.'
Set shl = WScript.CreateObject("WScript.Shell")
'Input remote PC
remotePC = "."
'Command which will be executed
strCommand = "cmd.exe /C cd C:\WINDOWS\system32 & ipconfig.exe /flushdns & pause"
'Connect to the remote PC
'Impersonate with the default level?
Set objWMIService = GetObject("winmgmts:" & "{impersonationLevel=impersonate}!\\" & remotePC & "\root\cimv2")
Set objProcess = objWMIService.Get("Win32_Process")
errReturn = objProcess.Create(strCommand, null, null, intProcessID)
Use PsExec for this purpose. Don't bother with VBScript.

cscript.exe opens a window

I have a vbs file that need to be run in 32-bit, even though I am running Windows 7 64-bit. I can launch this file with the command
C:\Windows\SysWOW64\cscript.exe my-file.vbs
and that works fine, but it leaves me with a redundant command prompt window that I have to close manually each time. It also makes it very cumbersome to run this vbs-file as a startup item.
Is there a way to start my 32-bit vbs-file in the background?
Try this for the 64bit problem, if it works you can combine it with the other answers
EDIT: here a question that goes more in depth on the 32/64 bit issue
How do I check if wscript/cscript runs on x64 host OS?
here the modified version, should make sure the script runs on 64bit platform
On Error Resume Next
Dim WshShell, OsType
Set WshShell = CreateObject("WScript.Shell")
OsType = WshShell.RegRead("HKLM\SYSTEM\CurrentControlSet\Control\Session Manager\Environment\PROCESSOR_ARCHITECTURE")
If OsType = "x86" then
wscript.echo "Windows 32bit system detected"
else
wscript.echo "Windows 64bit system detected"
If InStr(LCase(WScript.FullName),"system32") Then
CreateObject("WScript.Shell").Run """%systemroot%\SysWOW64\wscript.exe"" """ & WScript.ScriptFullName & """"
Wscript.Quit
End If
end if
Msgbox("I ran..")
If you need to use cscript this is IMHO a cool solution
Const HIDDEN_WINDOW = 0
strComputer = "."
Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\cimv2")
Set objStartup = objWMIService.Get("Win32_ProcessStartup")
Set objConfig = objStartup.SpawnInstance_
objConfig.ShowWindow = HIDDEN_WINDOW
Set objProcess = GetObject("winmgmts:\\" & strComputer & "\root\cimv2:Win32_Process")
objProcess.Create "Cscript.exe h:\Script\Test1.vbs", null, objConfig, intProcessID
If you can use wscript you could do the following, it's the simplest approach
Set objShell = CreateObject("Wscript.Shell")
objShell.Run "Wscript.exe h:\Script\Test1.vbs"
actually you can do it as a one-liner (i'm a Ruby guy 8>)
CreateObject("Wscript.Shell").Run("Wscript.exe h:\Script\Test1.vbs")

VBScript ending process started by .bat file

I have a scenario setup where I need to test to see if the results of a .bat file execution returned results. The .bat file calls up another .exe and the .bat file has a CMD DOS window that outputs critical error info to that DOS box from the .exe. If the .exe does not start correctly, I am able to check the results in our SQL DB. I need to close the current .bat file and re-launch it.
This seems fairly simple, I can get the ProcessID using the WMI call. I can terminate the process with a Terminate() command. This works for any .exe I use for testing: notepad, calc, iexplorer, etc. When I run the VBScript to kill the .bat file, it says it terminates the PID (which it does, since I cannot see the PID anymore), however, the DOS box is still open and the .exe called from the .bat file is still running. If I click on the "X" on the DOS box or right-click on the title bar and select "Close", the DOS box and the .exe are both killed. How do I get this script to work correctly. The server is running Windows Server 2003 (some are x32 and others are x64). Any ideas? Here is a version of my code, there have been several revs:
If colFiles.Count = 0 Then
Wscript.Echo "The file does not exist on the remote computer."
Else
Wscript.Echo "The file exists on the remote computer."
Set objWMIService = GetObject("winmgmts:" & "{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2")
Set colProcessList = objWMIService.ExecQuery("Select * from Win32_Process")
For Each objItem in colProcessList
If InStr(objItem.CommandLine, "r15_A.bat") Then
Wscript.Echo "Batch file: " & objItem.CommandLine & " Process ID: " & objItem.ProcessID & " Parent ID: " & objItem.ParentProcessID
Call TerminateProcess(objItem.ParentProcessID)
Call TerminateProcess(objItem.ProcessID)
End If
Next
dim shell
set shell=createobject("wscript.shell")
shell.run BATDIR & BATFILE
'set shell=nothing
End If
Function TerminateProcess(PID)
Set objWMIService = GetObject("winmgmts:\\.\root\CIMV2")
Set colProcesses = objWMIService.ExecQuery("SELECT * FROM Win32_Process WHERE Handle = '" & PID & "'")
For Each objProcess in colProcesses
On Error Resume Next
return = objProcess.Terminate()
Set colProcesses = objWMIService.ExecQuery("SELECT * FROM Win32_Process WHERE Handle = '" & PID & "'")
If Error Then
TerminateProcess = FALSE
Else
TerminateProcess = TRUE
msgBox colProcesses.Count
End If
Next
End Function
I have even tried to use the SendKeys to send ALt-F4, X, C, etc. AppActivate does bring the correct DOS box to the front.
Set WshShell = CreateObject("WScript.Shell")
WshShell.AppActivate "r15_A"
'WshShell.SendKeys("+{F10}")
WshShell.SendKeys("C")
Thanks in advance
EDIT--------------
Yes, I am going to have to kill the process that this .bat file calls. Only down side is this DOS box stays open. Annoying but I can live with it. In the end I wrote a script similar to my first one but only checks for the instance I want to kill by checking the CommandLine parameter: (The first bit of code with "-FAIL.txt" test to see if a FAIL file is present, if it is, then the rest of the scipts executes)
Set colFiles = objWMIService. _
ExecQuery("Select * From CIM_DataFile Where Name = 'S:\\servers\\Logs\\" & LOGFILE & "-FAIL.txt'")
If colFiles.Count = 0 Then
'Wscript.Echo "The file does not exist on the remote computer."
Else
'Wscript.Echo "The file exists on the remote computer."
strComputer = "."
Set objWMIService = GetObject("winmgmts:" _
& "{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2")
Set colProcessList = objWMIService.ExecQuery _
("Select * from Win32_Process Where Name = 'AppStart.exe'")
For Each objProcess in colProcessList
IF instr(objProcess.CommandLine, "robo05-A") > 0 THEN
'msgBox "Found text"
objProcess.Terminate()
'This part restarts the failed .bat file.
wscript.sleep (200)
dim shell
set shell=createobject("wscript.shell")
shell.run BATDIR & BATFILE
'set shell=nothing
ELSE
'msgBox "Not found"
END IF
Next
End If
The problem your having is the the executable that is being called from within your batch file is still running. I tried to recreated your setup with a bat the just did a ping -t %computername%, and sure enough the vbscript killed the cmd.exe but not the ping (Please note the Parent PID was explorer.exe, so you probably don't want to attempt killing that). Now I could easily kill ping.exe from task manager which then closed the window...but I only knew to do that because I knew what the bat was doing and what was left open. You could do a WMI search for the process that contains "ping.exe", grab the PID and then close that and that would basically be doing the same thing. Of course in your situation "ping.exe" is probably not the same executable as mine. If the exe changes every now and then then you could grab the commandline from your process find the parameter which contains the filepath to the r15_A.bat file, then use the filesystemobject to open this bat file, look for any executables which it calls which could possibly be still running and then kill those....but really that may be overkill for what your trying to accomplish.

Resources