From f46446ae374ae31ad813afa5af37f8f234165c24 Mon Sep 17 00:00:00 2001 From: David Yoder Date: Thu, 12 Oct 2023 22:11:17 -0400 Subject: [PATCH] added func Install-MSI --- Tools.ps1 | 60 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 60 insertions(+) diff --git a/Tools.ps1 b/Tools.ps1 index bbf43f1..267f42b 100644 --- a/Tools.ps1 +++ b/Tools.ps1 @@ -225,6 +225,66 @@ Function Install-Program { Else { Write-Output "The specified file could not be found: ""${Path}""" } } +# Function to silently install an MSI package either locally or after downloading it from a URL +Function Install-MSI { + param( + [Parameter(Mandatory=$true,ValueFromPipeline=$true)][string]$Path, + [Parameter(Mandatory=$false)][System.Collections.ArrayList]$Properties = @(), + [Parameter(Mandatory=$false)][string]$Log = $Global:LogFile, + [Parameter(Mandatory=$false)][switch]$DeleteMSI = $false, + [Parameter(Mandatory=$false)][int]$MaxRunTimeSeconds = 594 + ) + + # If $Path is a URL, then try to download the file + If ( IsURL -Value $Path ) { $Path = Download-File -URL $Path } + + # Make sure $FilePath exists + If ( !(Test-Path $Path ) ) { Write-Error "The specified file doesn't exist: ""${Path}""" ; Return } + + # Make sure $MaxRuntimeMinutes is a positive integer + If ( $MaxRunTimeSeconds -lt 0 ) { + $MaxRunTimeSeconds = 594 + Write-Output "The specified maximum run time is invalid and has been changed to ${MaxRunTimeSeconds} seconds" + } + + # Build the install command + [System.Collections.ArrayList]$MSIParameters = @('/i',"""${Path}""") + If ( ![string]::IsNullOrEmpty($Log) ) { + If ( Test-Path $Log ) { $MSIParameters.Add('/l+!*') | Out-Null } Else { $MSIParameters.Add('/l!*') | Out-Null } + $MSIParameters.Add("""${Log}""") | Out-Null + } + If ( ![string]::IsNullOrEmpty($Properties) ) { $MSIParameters.Add($Properties) | Out-Null } + + # Run a job to install the MSI + Write-Output "Waiting ${MaxRunTimeSeconds} seconds for the following command: msiexec.exe ${MSIParameters}" + $InstallMSI = Start-Job -ScriptBlock { PROCESS{ msiexec.exe $_ } } -InputObject $MSIParameters + + # Wait for the job to end or the timeout to be reached + $endTime = (Get-Date).AddSeconds($MaxRunTimeSeconds) + While ( $(Get-Date) -le $endTime ) { + If ( (Get-Job -Name $InstallMSI.Name).JobStateInfo.State -eq "Completed" ) { Break } + Start-Sleep -Seconds 1 + } + + # Stop the installation if it's still running + If ( (Get-Job -Name $InstallMSI.Name).JobStateInfo.State -ne "Completed" ) { + Write-Output "Timeout reached, stopping installation process" + Stop-Job -Job $InstallMSI + } + + # Clean up the job + $result = Receive-Job -Job $InstallMSI + Remove-Job -Job $InstallMSI -Force + If ( [string]::IsNullOrEmpty($result) ) { Write-Output "Installation finished!" } Else { Write-Output "Installation finished with the following output:`n${result}" } + + # Delete the MSI + If ( $DeleteMSI ) { + Write-Output "Deleting ""${Path}""" + Try { Remove-Item -Path $Path -Force -ErrorAction SilentlyContinue } + Catch { Write-Error $_.Exception.Message } + } +} + # Compare current Windows version with a supplied version # The value supplied must be a string and must include at least 1 decimal Function IsWindowsVersion {