InstallShield.psm1
Set-StrictMode -Version Latest function Get-InstallshieldInstallString { [OutputType([string])] [CmdletBinding()] param ( [Parameter(Mandatory)] [ValidateNotNullOrEmpty()] [string]$InstallerFilePath, [Parameter(Mandatory)] [ValidateNotNullOrEmpty()] [string]$IssFilePath, [Parameter()] [ValidateNotNullOrEmpty()] [string]$LogFilePath, [Parameter()] [ValidateNotNullOrEmpty()] [string]$ExtraSwitches ) begin { $ErrorActionPreference = 'Stop' } process { try { Write-Log -Message 'Creating the InstallShield setup install string' ## We're adding common InstallShield switches here. -s is silent, -f1 specifies where the ## ISS file we createed previously lives, -f2 specifies a log file location and /SMS is a special ## switch that prevents the setup.exe was exiting prematurely. if (-not $PSBoundParameters.ContainsKey('LogFilePath')) { $LogFilePath = "$(Get-SystemTempFolderPath)\$($InstallerFilePath | Split-Path -Leaf).log" } if (-not $ExtraSwitches) { $InstallArgs = "-s -f1`"$IssFilePath`" -f2`"$LogFilePath`" /SMS" } else { $InstallArgs = "-s -f1`"$IssFilePath`" $ExtraSwitches -f2`"$LogFilePath`" /SMS" } } catch { Write-Log -Message "Error: $($_.Exception.Message) - Line Number: $($_.InvocationInfo.ScriptLineNumber)" -LogLevel '3' $PSCmdlet.ThrowTerminatingError($_) } } } function Uninstall-InstallShieldPackage { <# .SYNOPSIS This function runs an uninstall for any InstallShield packaged software. This function utilitizes an InstallShield ISS file to silently uninstall the application. .PARAMETER Name One or more software titles of the InstallShield package you'd like to uninstall. .PARAMETER IssFilePath The file path where the pre-built silent answer file (ISS) is located. .PARAMETER SetupFilePath The file path where the EXE InstallShield installer is located. .PARAMETER LogFilePath The log file path where the InstallShield installer will log results. If not log file path is specified it will be created in the system temp folder. #> [OutputType()] [CmdletBinding()] param ( [Parameter(Mandatory = $true)] [string[]]$Name, [Parameter(Mandatory = $true)] [ValidateScript({ Test-Path -Path $_ -PathType 'Leaf' })] [string]$IssFilePath, [Parameter(Mandatory = $true)] [ValidateScript({ Test-Path -Path $_ -PathType 'Leaf' })] [string]$SetupFilePath, [ValidateScript({ Test-Path -Path ($_ | Split-Path -Parent) -PathType 'Container' })] [string]$LogFilePath = "(Get-SystemTempFolderPath)\IssSetupLog.log" ) process { try { foreach ($Product in $Name) { Write-Log -Message "Beginning uninstall for Installshield product '$Name'" ## Find the uninstall string to find the cached setup.exe $Products = Get-InstalledSoftware $Product ## If multiple products are found, remove them all foreach ($p in $Products) { $UninstallString = $p.UninstallString ## Check to ensure anything is in the UninstallString property if (-not $p.UninstallString) { Write-Log -Message "No uninstall string found for product $Title" -LogLevel '2' } elseif ($p.UninstallString -match '(\w:\\[a-zA-Z0-9 _.() { }-]+\\.*.exe)+') { ## Test to ensure the cached setup.exe exists if (-not (Test-Path $Matches[0])) { Write-Log -Message "Installer file path not found in $($p.UninstallString) or cannot be found on the file system" -LogLevel '2' } else { $InstallerFilePath = $Matches[0] Write-Log -Message "Valid installer file path is $InstallerFilePath" } } if (-not $InstallerFilePath) { if (-not $SetupFilePath) { Write-Log -Message "No setup folder path specified. This software cannot be removed" -LogLevel '2' continue } else { $InstallerFilePath = $SetupFilePath } } ## Run the setup.exe passing the ISS file to uninstall if ($InstallshieldLogFilePath) { $MyLogFilePath = $InstallshieldLogFilePath } else { $MyLogFilePath = $script:LogFilePath } $InstallArgs = "/s /f1`"$IssFilePath`" /f2`"$MyLogFilePath`" /SMS" Write-Log -Message "Running the install syntax `"$InstallerFilePath`" $InstallArgs" $Process = Start-Process "`"$InstallerFilePath`"" -ArgumentList $InstallArgs -Wait -NoNewWindow -PassThru if (-not (Test-InstalledSoftware $Title)) { Write-Log -Message "The product $Title was successfully removed!" } else { Write-Log -Message "The product $Title was not removed. Attempting secondary uninstall method" -LogLevel '2' ## Parse out the EXE file path and arguments. This regex could be improved on big time. $FilePathRegex = '(([a-zA-Z]\:|\\)\\([^\\]+\\)*[^\/:*?"<>|]+\.[a-zA-Z]{3})" (.+)' if ($UninstallString -match $FilePathRegex) { $InstallerFilePath = $matches[1] $InstallArgs = $matches[4] $InstallArgs = "$InstallArgs /s /f1`"$IssFilePath`" /f2`"$MyLogFilePath`" /SMS" Write-Log -Message "Running the install syntax `"$InstallerFilePath`" $InstallArgs" $Process = Start-Process "`"$InstallerFilePath`"" -ArgumentList $InstallArgs -Wait -NoNewWindow -PassThru if (-not (Test-InstalledSoftware $Title)) { throw "The product '$Title' was not removed!" } } else { throw "Could not parse out the setup installer and arguments from uninstall string. The product '$Title' was not removed!" } } } } } catch { Write-Log -Message "Error: $($_.Exception.Message) - Line Number: $($_.InvocationInfo.ScriptLineNumber)" -LogLevel '3' $PSCmdlet.ThrowTerminatingError($_) } } } |