Public/Install-Software.ps1
<#
.SYNOPSIS Installs software from an EXE or MSI file. .COMPONENT QuickSoft .DESCRIPTION This function installs software from a specified EXE or MSI file. It automatically detects the file type and handles installation accordingly. For MSI files, it defaults to silent installation (/qn) unless custom arguments are provided. Supports logging to a file if specified. .PARAMETER FilePath The full path to the EXE or MSI file to install. .PARAMETER Arguments Optional arguments to pass to the installer. For MSI files, custom arguments override the default silent installation (/qn). .PARAMETER Log Optional path to a log file. If provided, installation logs will be written to this file in addition to the console. .EXAMPLE Install-Software -FilePath "C:\installer.exe" Installs the software from the specified EXE file. .EXAMPLE Install-Software -FilePath "C:\package.msi" -Arguments "/qn /norestart" Installs the MSI package silently without restarting the system. .EXAMPLE Install-Software -FilePath "C:\package.msi" -Log "C:\install.log" Installs the MSI package silently and logs the process to the specified file. .OUTPUTS None. Writes installation progress and results to the console and optionally to a log file. .NOTES Name: Install-Software Author: AutomateSilent Version: 1.0.1 Last Updated: 2025-02-04 #> function Install-Software { [CmdletBinding()] param ( [Parameter( Position = 0, Mandatory = $true, ValueFromPipeline = $true, ValueFromPipelineByPropertyName = $true, HelpMessage = "The full path to the EXE or MSI file to install." )] [ValidateScript({ Test-Path $_ })] [string]$FilePath, [Parameter( Position = 1, Mandatory = $false, ValueFromPipelineByPropertyName = $true, HelpMessage = "Optional arguments to pass to the installer." )] [string]$Arguments, [Parameter( Position = 2, Mandatory = $false, ValueFromPipelineByPropertyName = $true, HelpMessage = "Optional path to a log file." )] [string]$Log ) begin { function Write-InstallLog { param($Message) $timestamp = Get-Date -Format "yyyy-MM-dd HH:mm:ss" $logMessage = "[$timestamp] $Message" if ($Log) { Add-Content -Path $Log -Value $logMessage } Write-Host $logMessage } try { # Convert to absolute path to avoid any path-related issues $FilePath = (Resolve-Path $FilePath).Path Write-Verbose "Initializing installation process for $FilePath" } catch { Write-Error "Initialization failed: $_" return } } process { try { $extension = [System.IO.Path]::GetExtension($FilePath).TrimStart('.').ToLower() if ($extension -notin 'exe', 'msi') { Write-InstallLog "ERROR: Unsupported file type '$extension'. Only EXE and MSI are supported." return } Write-InstallLog "Starting installation: $FilePath" if ($extension -eq 'exe') { $params = @{ FilePath = $FilePath Wait = $true PassThru = $true Verb = 'RunAs' # Ensures elevated privileges } if ($Arguments) { $params.ArgumentList = $Arguments } $process = Start-Process @params } else { # Default MSI arguments (silent install) $msiArgs = if ($Arguments) { Write-InstallLog "Using custom MSI arguments: $Arguments" "/i `"$FilePath`" $Arguments" } else { Write-InstallLog "Using default MSI arguments: /i `"$FilePath`" /qn" "/i `"$FilePath`" /qn" } # Use full path to msiexec and run with proper verb $process = Start-Process "C:\Windows\System32\msiexec.exe" -ArgumentList $msiArgs -Wait -PassThru -Verb RunAs } Write-InstallLog "Exit code: $($process.ExitCode). $(if ($process.ExitCode -ne 0) {'Installation failed!'} else {'Success!'})" } catch { Write-InstallLog "ERROR: $($_.Exception.Message)" } } end { Write-Verbose "Installation process completed for $FilePath" } } |