Public/Invoke-MsiExec.ps1
function Invoke-MsiExec { <# .DESCRIPTION Install or uninstall software using msiexec .PARAMETER FilePath Specify the path to the MSI or MSP file .PARAMETER Guid Specify the GUID of a software to uninstall .PARAMETER Install Instruct msiexec to operate in install mode .PARAMETER Uninstall Instruct msiexec to operate in uninstall mode .PARAMETER Patch Instruct msiexec to operate in patch mode .PARAMETER Arguments Specify additional arguments to pass to msiexec .PARAMETER ExitCodes Specify non-standard exit codes (Comma seperated list) .EXAMPLE Install an MSI Invoke-MsiExec -Install -FilePath "$PSScriptRoot\Setup.msi" -Arguments '/qn /norestart TRANSFORMS="$PSScriptRoot\Settings.mst"' Install an MSI file with non-standard exit codes 2 and 8 Invoke-MsiExec -Install -FilePath "$PSScriptRoot\Setup.msi" -Arguments '/qn /norestart' -ExitCodes '2,8' Install an MSP file Invoke-Msiexec -Patch -FilePath "$PSScriptRoot\Patch.msp" -Arguments '/qn /norestart' Uninstall an MSI Invoke-MsiExec -Uninstall -Guid "{00000000-0000-0000-0000-000000000000}" -Arguments '/qn /norestart' .NOTES Created by: Jon Anderson (@ConfigJon) Modified: 2023-07-03 #> [CmdletBinding()] param( [parameter(Mandatory = $false)][ValidateScript({ if(!($_ | Test-Path)) { throw "$_ was not found" } if(!($_ | Test-Path -PathType Leaf)) { throw "$_ is not a file path" } if(($_ -notmatch "(\.msi)") -and ($_ -notmatch "(\.msp)")) { throw "$_ is not an MSI or MSP file" } return $true })] [System.IO.FileInfo]$FilePath, [parameter(Mandatory = $false)][ValidateScript({ if($_ -notmatch ("^(\{){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}$")) { throw "$_ is not a properly formatted GUID" } })] [String]$Guid, [parameter(Mandatory = $false)][ValidateNotNullOrEmpty()] [String]$Arguments, [parameter(Mandatory = $false)][ValidateNotNullOrEmpty()] [String]$ExitCodes, [parameter(Mandatory = $false)][ValidateNotNullOrEmpty()] [Switch]$Install, [parameter(Mandatory = $false)][ValidateNotNullOrEmpty()] [Switch]$Uninstall, [parameter(Mandatory = $false)][ValidateNotNullOrEmpty()] [Switch]$Patch ) if(!($Install) -and !($Uninstall) -and !($Patch)) { Stop-Script -ErrorMessage "One of the Install or Uninstall or Patch parameters must be specified" } if($Install -and ($Uninstall -or $Patch)) { Stop-Script -ErrorMessage "Only one of the Install or Uninstall or Patch parameters may be specified" } if($Uninstall -and ($Install -or $Patch)) { Stop-Script -ErrorMessage "Only one of the Install or Uninstall or Patch parameters may be specified" } if($Patch -and ($Install -or $Uninstall)) { Stop-Script -ErrorMessage "Only one of the Install or Uninstall or Patch parameters may be specified" } if($Install -and !($FilePath)) { Stop-Script -ErrorMessage "The FilePath parameter must be specified when using the Install parameter" } if($Patch -and !($FilePath)) { Stop-Script -ErrorMessage "The FilePath parameter must be specified when using the Patch parameter" } if($Install -and $Guid) { Stop-Script -ErrorMessage "The Guid parameter should not be specified when using the Install parameter" } if($Patch -and $Guid) { Stop-Script -ErrorMessage "The Guid parameter should not be specified when using the Patch parameter" } $ArgumentList = New-Object 'System.Collections.Generic.List[string]' if($ExitCodes) { $ExitSplit = $ExitCodes.Split(',') } if($Install) { $ArgumentList.Add('/i') } if($Uninstall) { $ArgumentList.Add('/x') } if($Patch) { $ArgumentList.Add('/p') } if($FilePath) { $StringFilePath = $FilePath.ToString() $StringFilePath = $StringFilePath.insert(0,'"') $StringFilePath+='"' $ArgumentList.Add($StringFilePath) } if($Guid) { $ArgumentList.Add($Guid) } if($Arguments) { $Arguments = $ExecutionContext.InvokeCommand.ExpandString($Arguments) $ArgumentList.Add($Arguments) } Write-LogEntry -Value "Running Command: MsiExec.exe $ArgumentList" -Severity 1 $ExitCode = (Start-Process -FilePath "MsiExec.exe" -ArgumentList $ArgumentList -Wait -PassThru).ExitCode if(($ExitCode -ne 0) -and ($ExitCode -ne 3010) -and !($ExitSplit -contains $ExitCode)) { Stop-Script -ErrorMessage "Msiexec.exe terminated with an error: $ExitCode" } Write-LogEntry -Value "The exit code is $ExitCode" -Severity 1 } |