Hello Everyone!!!

Before I begin, let me tell you that I am not a programming expert. As with most of us, I am looking to work with my fellow professionals in learning what I need and giving to the ninjas what I have.

Not sure how many of you use vbscript for application packaging and deployment, but, I use it. Below is a template that can help in packaging software and setting up user scripts (active setup). I would be glad if someone can broaden this script and help me on areas that I marked in the script (which need to be improved)

Install template is located at - http://www.itninja.com/blog/view/application-packaging-vbscript-template

Here is what I enevisioned in the template

  1. Write log file before starting the install
  2. Unnstall msi/exe with appropriate command line
  3. if successful, write to log - else - exit with returning the code to SCCM
  4. Use active setup to run per user scripts/copy files etc

Here is what I think will make the script better

  1. A uninstall function which will search for application GUID in registry and uninstall the application using the uninstall string. This way, application will remove all previous versions

I need help with the uninstallĀ function in the script. When I have written this, the command window opens and does not close. The script needs to check both HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node and HKEY_LOCAL_MACHINE\SOFTWARE (i.e, 32-bit and 64-bit registry locations) and uninstall the application. The command we need to run needs to be in such a way that it can be modified for executables as well. If someone already has it, please add it here and some folk might be able to use it effectively.

If someone has a template in powershell, please also share it.

--

Cheers
Tech Surfer




'##==============================================================================
'##==============================================================================
'##  SCRIPT.........:  uninstall.vbs
'##  AUTHOR.........:  Tech Surfer
'##  VERSION........:  1.0.0.0
'##  REVISED DATE...........:  November 01, 2016
'##  DATE CREATED...........:  October 28, 2016
'##  LICENSE........:  Freeware
'##  REQUIREMENTS...:
'##
'##==============================================================================
'##==========******* USE SCRIPT AT YOUR OWN RISK *******=========================
'##==============================================================================
'##
'##  DESCRIPTION....:  This script will help uninstall applications. It is geared more towards msi'#s.
'##                    To run setup.exe files for silent uninstalls, please review the script and change accordingly.
'##                    Change the logfiles to whatever directories you want to write the log file to. Currently writing to C:\Temp\Application name
'##
'##  NOTES..........: ' Script does the following
      ' --- Gets current directory that is the script is running from
      ' --- Getting standard file locations that suits all windows operating systems using registry keys
      ' --- Gets information on who is running the script
      ' --- If needed, script bring a popup window to warn that the install will run in specific time
      ' --- Gets 64-bit or 32-bit operating system which can be used to copy files/use directory structure as required
      ' --- Uninstalls application using the product guids
      ' --- creates log files for uninstall
      ' --- Incase of error, quits the script by sending an error code (to SCCM/any other deployment tool)
'##
'##  CUSTOMIZE......: 'Customize the following to suit your needs
      ' DEPLOYNAME
      ' SETUPLOG
      ' POPUPTIMEOUT
      ' UNLOG
      ' MYFILE
      ' COMMANDLINE
      ' APPCLOSE
'## Functions that can be used (see bottom for reference)
      ' WriteLogFileLine(sLogFileName,sLogFileLine)
      ' LANGUAGE
      ' OsAchitecture
      ' FINDUNINSTALL
'##==============================================================================
'##  Starting the Script
'##==============================================================================
On Error Resume Next
set fs = CreateObject("Scripting.FileSystemObject")
Set Sh = WScript.CreateObject("WScript.Shell")
'## Change the name of the application below accordingly
DEPLOYNAME = "ApplicationName"
'#Define current folder from where the script is running
CURRENTDIR = fs.GetParentFolderName(Wscript.ScriptFullName)
QUOTE = chr(34)
'# Getting standard file locations that suits all windows operating systems
cdesktop = sh.expandenvironmentstrings(sh.regread("HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\User Shell Folders\Common Desktop"))
cprograms = sh.expandenvironmentstrings(sh.regread("HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\User Shell Folders\Common Programs"))
cstart = sh.expandenvironmentstrings(sh.regread("HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\User Shell Folders\Common Start Menu"))
cappdata = sh.expandenvironmentstrings(sh.regread("HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\User Shell Folders\Common AppData"))
udesktop = sh.expandenvironmentstrings(sh.regread("HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\User Shell Folders\Desktop"))
'# Checking to see who is running the script. This will help investigate installation failure
Set objNetwork = CreateObject("Wscript.Network")
RUNNINGAS = objNetwork.UserName
'# Write a log file for my program and change the path here accordingly
SETUPLOG = "C:\Temp\" & DEPLOYNAME & "Uninstall.log"
mylog =  WriteLogFileLine(SETUPLOG,"Installation is initiated by :: " & RUNNINGAS)
mylog =  WriteLogFileLine(SETUPLOG,"Script is run by ---- " & RUNNINGAS & " ---- from location :: " & CURRENTDIR)
mylog =  WriteLogFileLine(SETUPLOG,"Started installing application")
'# ====================================== BEGIN : Message while terminating any applications =========================================
'# Change number of seconds to wait as required
POPUPTIMEOUT = 0
APPCLOSE = "Enter name of applications that will be closed"
'# Change the below message as required to suit your application
POPUPMESSAGE = "This installation will close " & APPCLOSE & ". Please save all your work and close " & APPCLOSE & " applications. Application will install in " & POPUPTIMEOUT & " seconds!"
'# Change the below title as required to suit your application
POPUPTITLE = "WARNING!! " & APPCLOSE & " will close as part of the installation!"
If POPUPTIMEOUT <> 0 then MYPOPUP = sh.Popup(POPUPMESSAGE, POPUPTIMEOUT, POPUPTITLE)
'# ================================ END of Message : Message while terminating any applications =============================
'# ==================================== Begin cleanup of previous versions of the applications ========================
'# Make sure the application name is exactly what you want changed
'# DANGER!!! Don't give a name like "Microsoft" or "Adobe" as this will uninstall every product that has similar display name
'uncomment and use this section
'myret = FINDUNINSTALL("ApplicationName")
'Change the product code here. If this is a seup.exe, provide the file name and change the command line below accordingly.
PRODUCTCODE = "{MSIPRODUCTCODE}"
'#change the name of the application you want to terminate
TASKKILL = sh.expandenvironmentstrings("%WINDIR%\system32\taskkill.exe")
'myret = sh.run("cmd.exe /c " & quote & TASKKILL & quote & " /f /im name*",1,False)
'# ===================================== Begin cleanup of previous versions of the applications ==============
'Writes a seperate uninstall log if it finds previous version of the package installed
UNLOG = "C:\Temp\" & DEPLOYNAME & "uninst.log"
'# This section is looking for 64-bit or 32-bit of the Operating System
'# This can be checked in various ways. FOr example, you can look for SYSWOW64 folder (C:\Windows\SYSWOW64)
'# Some organizations have folder redirection issues and make sure your script does not redirect to wrong application
'Use Function OsAchitecture at the bottom if you need to find whether the system is 32-bit or 64-bit
'# Use MYFILE incase this is setup.exe. Change command line below as necessary
'MYFILE = CURRENTDIR & "\setupfile.exe"
 '#Installing Application. If the install fails here, the script will quit with appropriate error code
 mylog =  WriteLogFileLine(SETUPLOG,"Running uninstallation. Product code for the application is :: " & PRODUCTCODE)
 MSILOG = "C:\Temp\" & DEPLOYNAME & "msiuninst.log"
 COMMANDLINE = "msiexec.exe /X " & PRODUCTCODE & " /qb! REBOOT=ReallySuppress /l*v "& MSILOG
 myret = sh.run("cmd.exe /c " & COMMANDLINE,1,True)
 
 '# General successful exit code for application install are 0 and 30. If a specific application exits a different code, change that here.
 If myret = 0 or myret = 3010 Then
  mylog =  WriteLogFileLine(SETUPLOG,"Application successfully uninstalled. Exit code for uninstall is :: " & myret)
 '# Writing a specific registry key if the application install is successful. This will help in detection method in SCCM and also for inventory purposes.
 '# This is mandatory and can be changed per suitability
 '# Removing application installation/active setup registry keys after successful uninstalls
  myret = sh.regdelete("HKEY_LOCAL_MACHINE\SOFTWARE\BBH_Custom\" & DEPLOYNAME & "\")
  myret = sh.regdelete("HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Active Setup\Installed Components\" & DEPLOYNAME & "\")
 '# ========================= BEGIN CUSTOM ACTIONS HERE =================================================================================
 '# Add any custom action that you want to perform after successful here. This will ensure that these will only be created after a successful install and not everytime
 '# Example of custom actions :: Deleting/Creating shortcts, Appending specific files, creating/deleting directories etc
  myret = sh.run("cmd.exe /c RD /S /Q " & quote & "C:\TEMP\" & DEPLOYNAME & quote,1,True) 
 '# ========================= END CUSTOM ACTIONS HERE ================================================================================= 
 Else
  '# If the install failes with error code other than 0 or 3010, script will quit with appropriate exit code. Script will stop running here
  mylog =  WriteLogFileLine(SETUPLOG,"unnstallation Failed and Resullt is:: " & myret)
  mylog =  WriteLogFileLine(SETUPLOG,"Please Verify MSILOG for additional details which is located at:: " & MSILOG )
  wscript.quit(myret)
 End If
'# ===================================== Begin Functions and other Criteria =======================================================
'# ===================================== BEGIN Start Log Function =======================================
Function WriteLogFileLine(sLogFileName,sLogFileLine)
    dateStamp = Now()
 Set OFS = CreateObject("Scripting.FileSystemObject")
 Set logfile = OFS.OpenTextFile(sLogFileName, 8, True)
    logfile.WriteLine(cstr(dateStamp) + " - " + sLogFileLine)
    logfile.Close
    Set logfile = Nothing
    Set OFS = Nothing
End Function
'# ===================================== END Start Log Function =======================================
'# =========================== Function to get OS Language for the application to install ========================================
FUNCTION LANGUAGE()
strComputer = "."
Set objWMIService = GetObject("winmgmts:{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2")
Set colOperatingSystems = objWMIService.ExecQuery ("Select * from Win32_OperatingSystem")
For Each objOperatingSystem in colOperatingSystems
LANGUAGE = objOperatingSystem.OSLanguage
Next
End Function
'# =========================== End Function to get OS Language for the application to install ========================================
'# =========================== Function to get OS Architecture ========================================
Function OsAchitecture ()
    On Error Resume Next
    Dim WshShell
    Set WshShell = CreateObject("WScript.Shell")
    OsAchitecture = WshShell.RegRead("HKLM\SYSTEM\CurrentControlSet\Control\Session Manager\Environment\PROCESSOR_OsAchitectureITECTURE")
    On Error Goto 0
End Function
'# =========================== End Function to get OS Architecture ========================================
'# =========================== BEGIN FINDUNINSTALL Function to get previous versions of the software ========================================
Function FINDUNINSTALL(strsoft)
const HKEY_LOCAL_MACHINE = &H80000002
strComputer = "."
Set oReg = GetObject("winmgmts:{impersonationLevel=impersonate}!\\" & strComputer & "\root\default:StdRegProv")
strKeyPath = "software\wow6432node\microsoft\windows\currentversion\uninstall" 'OR strKeyPath = "software\microsoft\windows\currentversion\uninstall"' Root level
oReg.EnumKey HKEY_LOCAL_MACHINE, strKeyPath, arrSubKeys
For Each subkey In arrSubKeys
On Error Resume Next
sDisplayName = Sh.Regread("HKLM\" & strKeyPath & "\" & subkey & "\Displayname")
If instr(lcase(sDisplayName), lcase(strsoft)) > 0 then
 sUninstallString = Sh.Regread("HKLM\" & strKeyPath & "\" & subkey & "\uninstallstring")
 If instr(lcase(sUninstallString), "msiexec") Then
 mylog =  WriteLogFileLine(SETUPLOG,"Found previous version of the package:: " & subkey)
 mylog =  WriteLogFileLine(SETUPLOG,"Beginning uninstalling previous version:: " & subkey)
 myret = sh.run("cmd.exe /c msiexec /X " & subkey & " /qn REBOOT=ReallySuppress /l*v " & quote & UNLOG & quote,1,True)
 If myret = 0 OR myret = 3010 Then
  mylog =  WriteLogFileLine(SETUPLOG,"Successfully uninstalled previous version!!!  Exit Code returned is :: " & myret)
 Else
  mylog =  WriteLogFileLine(SETUPLOG,"Uninstalling previous version failed!! Exit code for uninstall is :: " & myret)
  wscript.quit(myret)
 End If
 End If
end if
Next
Set oReg = GetObject("winmgmts:{impersonationLevel=impersonate}!\\" & strComputer & "\root\default:StdRegProv")
strKeyPath = "software\microsoft\windows\currentversion\uninstall" ' Root level
oReg.EnumKey HKEY_LOCAL_MACHINE, strKeyPath, arrSubKeys
For Each subkey In arrSubKeys
On Error Resume Next
sDisplayName = Sh.Regread("HKLM\" & strKeyPath & "\" & subkey & "\Displayname")
if instr(lcase(sDisplayName), lcase(strsoft)) > 0 then
 sUninstallString = Sh.Regread("HKLM\" & strKeyPath & "\" & subkey & "\uninstallstring")
 If instr(lcase(sUninstallString), "msiexec") Then
 mylog =  WriteLogFileLine(SETUPLOG,"Found previous version of the package:: " & subkey)
 mylog =  WriteLogFileLine(SETUPLOG,"Beginning uninstalling previous version:: " & subkey)
 myret = sh.run("cmd.exe /c msiexec /X " & subkey & " /qn REBOOT=ReallySuppress /l*v " & quote & UNLOG & quote,1,True)
 If myret = 0 OR myret = 3010 Then
  mylog =  WriteLogFileLine(SETUPLOG,"Successfully uninstalled previous version!!!  Exit Code returned is :: " & myret)
 Else
  mylog =  WriteLogFileLine(SETUPLOG,"Uninstalling previous version failed!! Exit code for uninstall is :: " & myret)
  wscript.quit(myret)
 End If
 End If
end if
Next
End Function
'# =========================== END FINDUNINSTALL Function to get previous versions of the software ========================================
'# ===================================== End Functions =======================================================
'##==============================================================================
'##  END OF FILE
'##==============================================================================