Action for Advertised Shortcuts in"Execute-MSI"

Topics: Archive - Toolkit Extensions
Jul 18, 2014 at 5:22 PM
Edited Jul 18, 2014 at 5:27 PM
I wanted to be able to advertise shortcuts, and let people be able to install software completely once they needed it. Typically it's for software that I'd deploy to everyone, but only the people who look for it will need to have it installed. Instead of Msiexec /i it uses msiexec /jm.

I am not a "real" programmer, so this is not really tested in any way, and I'm sure Advertised Shortcuts does not work on all MSI files. This is just a small edit of the function in appdeploytoolkit-main.ps1. But here goes:
Function Execute-MSI {
<#
.SYNOPSIS
    Executes msiexec.exe to perform the following actions for MSI & MSP files and MSI product codes: install, uninstall, patch, repair, active setup, advertise.
.DESCRIPTION
    Executes msiexec.exe to perform the following actions for MSI & MSP files and MSI product codes: install, uninstall, patch, repair, active setup, advertise.
    Sets default switches to be passed to msiexec based on the preferences in the XML configuration file, e.g. "REBOOT=ReallySuppress /QB!"
    Automatically generates a log file name and creates a verbose log file for all msiexec operations.
    NB: Expects the MSI or MSP file to be located in the "Files" sub directory of the App Deploy Toolkit. Expects transform files to be in the same directory as the MSI file.
.EXAMPLE
    Execute-MSI -Action Install -Path "Adobe_FlashPlayer_11.2.202.233_x64_EN.msi"
    Installs an MSI
.EXAMPLE
    Execute-MSI -Action Install -Path "Adobe_FlashPlayer_11.2.202.233_x64_EN.msi" -Transform "Adobe_FlashPlayer_11.2.202.233_x64_EN_01.mst" -Parameters "/QN"
    Installs an MSI, applying a transform and overriding the default MSI toolkit parameters
.EXAMPLE
    Execute-MSI -Action Uninstall -Path "{26923b43-4d38-484f-9b9e-de460746276c}"
    Uninstalls an MSI using a product code
.EXAMPLE
    Execute-MSI -Action Patch -Path "Adobe_Reader_11.0.3_EN.msp"
    Installs an MSP
.PARAMETER Action
    The action to perform ["Install","Uninstall","Patch","Repair","ActiveSetup"]
.PARAMETER Path
    The path to the MSI/MSP file or the product code of the installed MSI.
.PARAMETER Transform
    The name of the transform file(s). The transform file is expected to be in the same directory as the MSI file.
.PARAMETER Parameters
    Overrides the default parameters specified in the XML configuration file. Install default is "REBOOT=ReallySuppress /QB!", uninstall default is "REBOOT=ReallySuppress /QN"
.PARAMETER LogName
    Overrides the default log file name.
    The default log file name is generated from the MSI file name or for uninstallations, the product code is resolved to the displayname and version of the application.
.PARAMETER WorkingDirectory
    Overrides the working directory.
    The working directory is set to the location of the MSI file.
.PARAMETER ContinueOnError
    Continue if an exit code is returned by msiexec that is not recognised by the App Deploy Toolkit.
.NOTES
.LINK
    Http://psappdeploytoolkit.codeplex.com
#>
    Param(
        [ValidateSet("Install","Uninstall","Patch","Repair","ActiveSetup","Advertise")]
        [string] $Action = $null,
        [string] $Path = $(throw "Path to MSI/MSP file required or Product Code required"),
        [string] $Transform = $null,
        [string] $Parameters = $null,
        [string] $LogName = $null,
        [string] $WorkingDirectory,
        [boolean] $ContinueOnError = $false # Fail if there is an error (Default)
    )

    # Build the log file name
    If (!($logName)) {
        # If the path matches a product code, resolve the product code to an application name and version
        If ($path -match "^(\{{0,1}([0-9a-fA-F]){8}-([0-9a-fA-F]){4}-([0-9a-fA-F]){4}-([0-9a-fA-F]){4}-([0-9a-fA-F]){12}\}{0,1})$") {
            Write-Log "Execute-MSI: Product code specified, attempting to resolve product code to an application name and version..."
            $productCodeNameVersion = (Get-InstalledApplication -ProductCode $path | Select DisplayName,DisplayVersion -First 1 -ErrorAction SilentlyContinue)
            If ($productCodeNameVersion -ne $null) {
                If ($($productCodeNameVersion.Publisher) -ne $null) {
                    $logName = ($productCodeNameVersion.Publisher + "_" + $productCodeNameVersion.DisplayName + "_" + $productCodeNameVersion.DisplayVersion) -replace " ","" -replace "\\","" -replace "/",""
                }
                Else {
                    $logName = ( $productCodeNameVersion.DisplayName + "_" + $productCodeNameVersion.DisplayVersion) -replace " ","" -replace "\\","" -replace "/",""
                }
            }
            Else {
                $logName = (([System.IO.FileInfo]$path).BaseName)
            }
        }
        Else {
            $logName = (([System.IO.FileInfo]$path).BaseName)
        }
    }

    If ($configToolkitCompressLogs) {
        # Build the log file path
        $logPath = Join-Path $logTempFolder $logName
    }
    Else {
        # Create the Log directory if it doesn't already exist
        If (!(Test-Path -path $configMSILogDir -ErrorAction SilentlyContinue )) { New-Item $configMSILogDir -Type directory -ErrorAction SilentlyContinue | Out-Null }
        # Build the log file path
        $logPath = Join-Path $configMSILogDir $logName
    }

    # Set the installation Parameters
    $msiUninstallDefaultParams = $configMSISilentParams
    If ($deployModeSilent -eq $true) {
        $msiInstallDefaultParams = $configMSISilentParams
    }
    Else {
        $msiInstallDefaultParams = $configMSIInstallParams
    }

    # Build the MSI Parameters
    Switch ($action) {
        "Install"           { $option = "/i"; $msiLogFile = $logPath + "_Install"; $msiDefaultParams = $msiInstallDefaultParams }
        "Uninstall"         { $option = "/x"; $msiLogFile = $logPath + "_Uninstall"; $msiDefaultParams = $msiUninstallDefaultParams }
        "Patch"             { $option = "/update"; $msiLogFile = $logPath + "_Patch"; $msiDefaultParams = $msiInstallDefaultParams }
        "Repair"            { $option = "/f"; $msiLogFile = $logPath + "_Repair"; $msiDefaultParams = $msiInstallDefaultParams }
        "ActiveSetup"       { $option = "/fups"; $msiLogFile = $logPath + "_ActiveSetup" }
        "Advertise"         { $option = "/jm"; $msiLogFile = $logPath + "_Advertise"; $msiDefaultParams = $msiInstallDefaultParams }
    }

    # Append .log to the logfile path and enclose in quotes
    If (([System.IO.FileInfo]$msiLogFile).Extension -ne "log") {
        $msiLogFile = $msiLogFile + ".log"
        $msiLogFile = "`"$msiLogFile`""
    }

    # If the MSI is in the Files directory, set the full path to the MSI
    If (Test-Path (Join-Path $dirFiles $path -ErrorAction SilentlyContinue) -ErrorAction SilentlyContinue) {
        $msiFile = (Join-Path $dirFiles $path)
    }
    Else {
        $msiFile = $Path
    }

    # Set the working directory of the MSI
    $workingDirectory = Split-Path $msiFile -Parent

    # Enclose the MSI file in quotes to avoid issues with spaces when running msiexec
    $msiFile = "`"$msiFile`""
    # Enclose the MST file in quotes to avoid issues with spaces when running msiexec
    $mstFile = "`"$transform`""

    If ($transform -and $Parameters) {
        $argsMSI = "$option $msiFile TRANSFORMS=$mstFile $Parameters $configMSILoggingOptions $msiLogFile"
    }
    ElseIf ($transform) {
        $argsMSI = "$option $msiFile TRANSFORMS=$mstFile $msiDefaultParams $configMSILoggingOptions $msiLogFile"
    }
    ElseIf ($Parameters) {
        $argsMSI = "$option $msiFile $Parameters $configMSILoggingOptions $msiLogFile"
    }
    Else {
        $argsMSI = "$option $msiFile $msiDefaultParams $configMSILoggingOptions $msiLogFile"
    }

    # Call the Execute-Process function
    If ($ContinueOnError -eq $true) {
        Execute-Process -FilePath $exeMsiexec -Arguments $argsMSI -WorkingDirectory $WorkingDirectory -WindowStyle Normal -ContinueOnError $true
    }
    Else {
        Execute-Process -FilePath $exeMsiexec -Arguments $argsMSI -WorkingDirectory $WorkingDirectory -WindowStyle Normal
    }
}