MSI

  • Delete Folder on Uninstall of MSI

    Problem: Application remnants remain after uninstall.

    After uninstalling a particular MSI some remnants remain of the application files in the ProgramFiles folder.

    Reason: Application is updated in situe.

    The application is a standard client/server setup with application updates being applied to the server which then disseminate to all clients which means files are present on the client that weren't put there by the MSI itself. Natively an MSI will only remove files that were installed by itself...............or if they've been added to the removefiles table, however we have no idea of the name of the files that will need to be removed so we need a catch all solution.

    Fix: Script the removal of the folder during uninstall.

    I decided on a vbscript in a custom action to the remove the folder and all it's contents, triggered when the application is uninstalled.


    Create a VBScript Custom Action that is stored within the CA and complete as per below, you can find the VBScript here.

    *Action*  
    Return Processing
    Synchronous (Check exit code)
    In-Script Execution Deferred Execution in System Context
    Key Installer\Products\<GUID>
    Name Transforms
    Component ISRegistryValue
    *Sequence* - Install Exec After RemoveFolders
    Install Exec Condition
    REMOVE="ALL"
  • Install MSI (Simple) .vbs

    install-MSInospaces.vbs

    Option Explicit
     
    Dim wshShell, strCmd, oEnv
     
    Set wshShell = CreateObject("WScript.Shell")
     
    Set oEnv = wshShell.Environment("PROCESS")
    oEnv("SEE_MASK_NOZONECHECKS") = 1
     
    wshShell.Run "msiexec /i \\SERVERNAME\pathwithnospaces\yourmsi.msi /qn /norestart", 0, True
     
    oEnv.Remove("SEE_MASK_NOZONECHECKS")
    Set oEnv = Nothing
    Set wshShell = Nothing
  • Remove Registry VALUE on Install in Basic MSI

     

    Problem: Existing install of an MSI application will not un-install.

    On 30+ servers a vendor supplied MSI needed to be updated to the next version however the application would not un-install using any standard removal methods with various switches and will not upgrade to the next version. Using MSIZap seems to work but the subsequent install of the next version results in mis-match errors.

    Reason: Rogue property set via an MST transform on install.

    A PROPERTY was found that was set via a transform when the original application was installed ADDDEFAULT=ALL. Whichever setting this property is affecting it allowed the install but not the un-install.

    Fix: Break the link between the transform and the MSI.

    Within the HKEY_CLASSES_ROOT\Installer\Products\<GUID> registry key a VALUE exists that connects the MSI to it's transform MST file so removing this VALUE will allow the normal un-install process to complete. Creating a basic MSI to remove the VALUE was decided as the easiest option to rollout using existing deployment tools.


    Create a basic MSI with an entry in the RemoveRegistry table replacing the values with your own settings, I used '0' for the root as I needed to work with HKEY_CLASSES_ROOT but check the details below for your own values.

    *Column Name* *Row Contents*
    RemoveRegistry RemoveRegistry01
    Root 0
    Key Installer\Products\<GUID>
    Name Transforms
    Component ISRegistryValue
     
    RemoveRegistry (s72)

    Unique name to define the entry (you can choose this)

    Root (i2)

    numeric value defining the registry hive you'll be deleting from
    0 = HKCR
    1 = HKCU
    2 = HKLM
    3 = HKU

    Key (l255)

    The rest of the key name, such as SOFTWARE\MyProduct\

    Name (L255)

    Name of the Registry VALUE, such as UninstallString

    Component_ (s72)

    Name of a component from the component table to link the removal too, this has to be a component selected for install. If you don't have an existing component to use just create a new component.

  • Silent Driver Install for MSI - "Would you like to install this device software?"

    Problem: Driver will not install silently.

    When trying to complete a silent install of a vendor supplied MSI that comes bundled with drivers, a window is shown during install prompting for input to continue with the install. The window shown also gives you the option to trust that publisher for future installs.

     

    Reason: The certificate has gone past it's expiration date.

    The reason why the Windows Security prompt is displayed is because the certifcate that was used to sign the .cat catalog file has gone past it's expiration date.

    Fix: Add the certificate as a Trusted Publisher.

    Adding the certificate into the certificate store within the Trusted Publisher folder will then allow any drivers from that publisher/vendor to install without any security prompts. Ticking the box on the "Would you like to install this device software" window has the same outcome.

    Instructions:

    Firstly we need to run through an install of the application so we can obtain a copy of the certifcate to use as a trusted publisher section of the certificate store. I completed this task in a VM on my test environment.

    1. In your test environment complete an install of the application making sure to tick the 'Always trust software from......' box and choose 'Install' on the Windows Security prompt.

    2. Run certmgr.msc or open the certifcate manager however you like, navigate and expand the trusted publisher section on the left then click certificates underneath it.

    3. You should see the certificate with the same name as from the Windows Security prompt (if you don't and you had the certificate store open while doing the install you just need to refresh the store, otherwise you will need to troubleshoot as to why).

    4. Right click the certificate and choose 'All Tasks - Export' leaving everything as default save to a known location with a relevant filename, I'll use mycert.cer as the example for this.

    Now that we have a copy of the certificate we just need to get the MSI to install the certificate in the trusted publisher section prior to the driver being installed. If like myself you are doing this with a vendor supplied MSI you will need to create a .mst transform file to make the changes to the MSI, I'm using Installshield but the process can be tailored for whatever tool you're using.

    5. Add the certifcate you exported above to your transform (choosing either to compress the extra file into a cab or leave uncompressed, I added mine to a component that installs to the INSTALLDIR.

    6. For the install the position of the 'Install Exec Sequence' may be different to my example, it depends on what method the vendor MSI ha used to install the drivers. If the 'MsiProcessDrivers' action is present in the sequence you will probably have to move it so that it occurs after we add the certificate.

    7. We'll need to create a custom action for install and another to un-install as per the tables below - both need be 'New EXE - Path referencing a directory'.

    NAME - InstallCert  
    *Action*  
    Working Directory INSTALLDIR
    File Name & Command Line certutil -addstore "TrustedPublisher" "[INSTALLDIR]mycert.cer"
    Return Processing
    Synchronous (Ignores exit code)
    In-Script Execution Deferred Execution in System Context
    *Sequence*  
    Install Exec Sequence
    After InstallFiles
    Install Exec Condition
    NOT Installed

     

    NAME - UnInstallCert  
    *Action*  
    Working Directory INSTALLDIR
    File Name & Command Line certutil -delstore "TrustedPublisher" "[INSTALLDIR]mycert.cer"
    Return Processing
    Synchronous (Ignores exit code)
    In-Script Execution Deferred Execution in System Context
    *Sequence*  
    Install Exec Sequence
    After SelfUnregModules
    Install Exec Condition
    REMOVE="ALL"

     

    8. Save and compile the MSI.

     

    You can easily test whether your custom actions are working by completing an install and checking the trusted publishers section in the certificate manager..........or just complete an install and see if you're prompted by the Windows Security dialog.