From 1e6b19485ef2325c9f39c550d60a5ac441198e33 Mon Sep 17 00:00:00 2001 From: Dan Barton Date: Mon, 5 May 2025 11:53:25 -0400 Subject: [PATCH] FireFox ESR using existential detection method to allow for separate 3rd party patching to manage updates --- Apps/FirefoxESR/Deploy-Application.ps1 | 217 +++++++++++++++++++++++++ Apps/FirefoxESR/app.json | 60 +++++++ Apps/FirefoxESR/appList.json | 15 ++ 3 files changed, 292 insertions(+) create mode 100644 Apps/FirefoxESR/Deploy-Application.ps1 create mode 100644 Apps/FirefoxESR/app.json create mode 100644 Apps/FirefoxESR/appList.json diff --git a/Apps/FirefoxESR/Deploy-Application.ps1 b/Apps/FirefoxESR/Deploy-Application.ps1 new file mode 100644 index 0000000..b20b83e --- /dev/null +++ b/Apps/FirefoxESR/Deploy-Application.ps1 @@ -0,0 +1,217 @@ +<# +.SYNOPSIS + This script performs the installation or uninstallation of an application(s). + # LICENSE # + PowerShell App Deployment Toolkit - Provides a set of functions to perform common application deployment tasks on Windows. + Copyright (C) 2017 - Sean Lillis, Dan Cunningham, Muhammad Mashwani, Aman Motazedian. + This program is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. + You should have received a copy of the GNU Lesser General Public License along with this program. If not, see . +.DESCRIPTION + The script is provided as a template to perform an install or uninstall of an application(s). + The script either performs an "Install" deployment type or an "Uninstall" deployment type. + The install deployment type is broken down into 3 main sections/phases: Pre-Install, Install, and Post-Install. + The script dot-sources the AppDeployToolkitMain.ps1 script which contains the logic and functions required to install or uninstall an application. +.PARAMETER DeploymentType + The type of deployment to perform. Default is: Install. +.PARAMETER DeployMode + Specifies whether the installation should be run in Interactive, Silent, or NonInteractive mode. Default is: Interactive. Options: Interactive = Shows dialogs, Silent = No dialogs, NonInteractive = Very silent, i.e. no blocking apps. NonInteractive mode is automatically set if it is detected that the process is not user interactive. +.PARAMETER AllowRebootPassThru + Allows the 3010 return code (requires restart) to be passed back to the parent process (e.g. SCCM) if detected from an installation. If 3010 is passed back to SCCM, a reboot prompt will be triggered. +.PARAMETER TerminalServerMode + Changes to "user install mode" and back to "user execute mode" for installing/uninstalling applications for Remote Destkop Session Hosts/Citrix servers. +.PARAMETER DisableLogging + Disables logging to file for the script. Default is: $false. +.EXAMPLE + powershell.exe -Command "& { & '.\Deploy-Application.ps1' -DeployMode 'Silent'; Exit $LastExitCode }" +.EXAMPLE + powershell.exe -Command "& { & '.\Deploy-Application.ps1' -AllowRebootPassThru; Exit $LastExitCode }" +.EXAMPLE + powershell.exe -Command "& { & '.\Deploy-Application.ps1' -DeploymentType 'Uninstall'; Exit $LastExitCode }" +.EXAMPLE + Deploy-Application.exe -DeploymentType "Install" -DeployMode "Silent" +.NOTES + Toolkit Exit Code Ranges: + 60000 - 68999: Reserved for built-in exit codes in Deploy-Application.ps1, Deploy-Application.exe, and AppDeployToolkitMain.ps1 + 69000 - 69999: Recommended for user customized exit codes in Deploy-Application.ps1 + 70000 - 79999: Recommended for user customized exit codes in AppDeployToolkitExtensions.ps1 +.LINK + http://psappdeploytoolkit.com +#> +[CmdletBinding()] +Param ( + [Parameter(Mandatory=$false)] + [ValidateSet('Install','Uninstall')] + [string]$DeploymentType = 'Install', + [Parameter(Mandatory=$false)] + [ValidateSet('Interactive','Silent','NonInteractive')] + [string]$DeployMode = 'Interactive', + [Parameter(Mandatory=$false)] + [switch]$AllowRebootPassThru = $false, + [Parameter(Mandatory=$false)] + [switch]$TerminalServerMode = $false, + [Parameter(Mandatory=$false)] + [switch]$DisableLogging = $false +) + +Try { + ## Set the script execution policy for this process + Try { Set-ExecutionPolicy -ExecutionPolicy 'ByPass' -Scope 'Process' -Force -ErrorAction 'Stop' } Catch {} + + ##*=============================================== + ##* VARIABLE DECLARATION + ##*=============================================== + ## Variables: Main Application + [string]$appVendor = '###APPPUBLISHER###' + [string]$appName = '###INTUNEAPPNAME###' + [string]$appVersion = '###VERSION###' + [string]$appArch = '' + [string]$appLang = '' + ## Variables: Additional applications + ## - Not required + ## Variables: Application package details + [string]$appRevision = '1.0' + [string]$appScriptVersion = '3.7.0' + [string]$appScriptDate = '###DATETIME###' + [string]$appScriptAuthor = 'IntuneAppFactory' + ##*=============================================== + ## Variables: Install Titles (Only set here to override defaults set by the toolkit) + [string]$installName = '' + [string]$installTitle = '' + + ##* Do not modify section below + #region DoNotModify + + ## Variables: Exit Code + [int32]$mainExitCode = 0 + + ## Variables: Script + [string]$deployAppScriptFriendlyName = 'Deploy Application' + [version]$deployAppScriptVersion = [version]'3.7.0' + [string]$deployAppScriptDate = '02/13/2018' + [hashtable]$deployAppScriptParameters = $psBoundParameters + + ## Variables: Environment + If (Test-Path -LiteralPath 'variable:HostInvocation') { $InvocationInfo = $HostInvocation } Else { $InvocationInfo = $MyInvocation } + [string]$scriptDirectory = Split-Path -Path $InvocationInfo.MyCommand.Definition -Parent + + ## Dot source the required App Deploy Toolkit Functions + Try { + [string]$moduleAppDeployToolkitMain = "$scriptDirectory\AppDeployToolkit\AppDeployToolkitMain.ps1" + If (-not (Test-Path -LiteralPath $moduleAppDeployToolkitMain -PathType 'Leaf')) { Throw "Module does not exist at the specified location [$moduleAppDeployToolkitMain]." } + If ($DisableLogging) { . $moduleAppDeployToolkitMain -DisableLogging } Else { . $moduleAppDeployToolkitMain } + } + Catch { + If ($mainExitCode -eq 0){ [int32]$mainExitCode = 60008 } + Write-Error -Message "Module [$moduleAppDeployToolkitMain] failed to load: `n$($_.Exception.Message)`n `n$($_.InvocationInfo.PositionMessage)" -ErrorAction 'Continue' + ## Exit the script, returning the exit code to SCCM + If (Test-Path -LiteralPath 'variable:HostInvocation') { $script:ExitCode = $mainExitCode; Exit } Else { Exit $mainExitCode } + } + + #endregion + ##* Do not modify section above + ##*=============================================== + ##* END VARIABLE DECLARATION + ##*=============================================== + + If ($deploymentType -ine 'Uninstall') { + ##*=============================================== + ##* PRE-INSTALLATION + ##*=============================================== + [string]$installPhase = 'Pre-Installation' + + ## Show Welcome Message, close Internet Explorer if required, allow up to 3 deferrals, verify there is enough disk space to complete the install, and persist the prompt + #Show-InstallationWelcome -CloseApps 'iexplore' -AllowDefer -DeferTimes 3 -CheckDiskSpace -PersistPrompt + + ## Show Progress Message (with the default message) + #Show-InstallationProgress + + ## + + ## SAMPLE: Uninstall any previous versions of application by calling the command from Uninstall-string + #Remove-MSIApplications -Name "" + + ## SAMPLE: Uninstall any previous versions of application by referencing the product code and call msiexec /x + #Remove-MSIApplicationsEx -Name "" + + ##*=============================================== + ##* INSTALLATION + ##*=============================================== + [string]$installPhase = 'Installation' + + ## Handle Zero-Config MSI Installations + If ($useDefaultMsi) { + [hashtable]$ExecuteDefaultMSISplat = @{ Action = 'Install'; Path = $defaultMsiFile }; If ($defaultMstFile) { $ExecuteDefaultMSISplat.Add('Transform', $defaultMstFile) } + Execute-MSI @ExecuteDefaultMSISplat; If ($defaultMspFiles) { $defaultMspFiles | ForEach-Object { Execute-MSI -Action 'Patch' -Path $_ } } + } + + ## ******************************************* + + ## SAMPLE: EXE + $exeInstall = "###SETUPFILENAME###" + $exeInstallParams = "/S /MaintenanceService=false" + Execute-Process -Path "$($dirFiles)\$($exeInstall)" -Parameters "$($exeInstallParams)" + + ##*=============================================== + ##* POST-INSTALLATION + ##*=============================================== + [string]$installPhase = 'Post-Installation' + + ## + + ## Display a message at the end of the install + #If (-not $useDefaultMsi) { Show-InstallationPrompt -Message 'You can customize text to appear at the end of an install or remove it completely for unattended installations.' -ButtonRightText 'OK' -Icon Information -NoWait } + } + ElseIf ($deploymentType -ieq 'Uninstall') + { + ##*=============================================== + ##* PRE-UNINSTALLATION + ##*=============================================== + [string]$installPhase = 'Pre-Uninstallation' + + ## Show Welcome Message, close Internet Explorer with a 60 second countdown before automatically closing + #Show-InstallationWelcome -CloseApps 'iexplore' -CloseAppsCountdown 60 + + ## Show Progress Message (with the default message) + #Show-InstallationProgress + + ## + + ##*=============================================== + ##* UNINSTALLATION + ##*=============================================== + [string]$installPhase = 'Uninstallation' + + ## Handle Zero-Config MSI Uninstallations + If ($useDefaultMsi) { + [hashtable]$ExecuteDefaultMSISplat = @{ Action = 'Uninstall'; Path = $defaultMsiFile }; If ($defaultMstFile) { $ExecuteDefaultMSISplat.Add('Transform', $defaultMstFile) } + Execute-MSI @ExecuteDefaultMSISplat + } + + # ******************************************* + + #Uninstall any previous versions of application by calling the command from Uninstall-string + Execute-Process -Path "%ProgramFiles%\Mozilla Firefox\uninstall\helper.exe" -Parameters "/S" + + ##*=============================================== + ##* POST-UNINSTALLATION + ##*=============================================== + [string]$installPhase = 'Post-Uninstallation' + + ## + + } + + ##*=============================================== + ##* END SCRIPT BODY + ##*=============================================== + + ## Call the Exit-Script function to perform final cleanup operations + Exit-Script -ExitCode $mainExitCode +} +Catch { + [int32]$mainExitCode = 60001 + [string]$mainErrorMessage = "$(Resolve-Error)" + Write-Log -Message $mainErrorMessage -Severity 3 -Source $deployAppScriptFriendlyName + Show-DialogBox -Text $mainErrorMessage -Icon 'Stop' + Exit-Script -ExitCode $mainExitCode +} \ No newline at end of file diff --git a/Apps/FirefoxESR/app.json b/Apps/FirefoxESR/app.json new file mode 100644 index 0000000..9b3c690 --- /dev/null +++ b/Apps/FirefoxESR/app.json @@ -0,0 +1,60 @@ +{ + "PackageInformation": { + "SetupType": "EXE", + "SetupFile": "Deploy-Application.exe", + "SourceFolder": "Source", + "OutputFolder": "Package", + "IconFile": "Icon.png", + "IconURL": "" + }, + "Information": { + "DisplayName": "", + "AppVersion": "", + "Description": "Firefox Extended Support Release (ESR) is an official version of Firefox developed for large organizations like universities and businesses that need to set up and maintain Firefox on a large scale.", + "Publisher": "", + "Notes": "", + "Owner": "", + "ScopeTagName": "Default" + }, + "Program": { + "InstallCommand": "Deploy-Application.exe Install", + "UninstallCommand": "Deploy-Application.exe Uninstall", + "InstallExperience": "system", + "DeviceRestartBehavior": "suppress" + }, + "RequirementRule": { + "MinimumSupportedWindowsRelease": "W10_22H2", + "Architecture": "x64" + }, + "CustomRequirementRule": [ + ], + "DetectionRule": [ + { + "Type": "File", + "DetectionMethod": "Existence", + "Path": "C:\\Program Files\\Mozilla Firefox", + "FileOrFolder": "firefox.exe", + "Check32BitOn64System": "false", + "DetectionType": "exists" + } + ], + "Assignment": [ + { + "Type": "Group", + "GroupID": "your_group_id", + "Intent": "available", + "GroupMode": "include", + "Notification": "showAll", + "UseLocalTime": true, + "FilterName": "", + "FilterMode": "", + "AvailableTime": "", + "DeadlineTime": "", + "DeliveryOptimizationPriority": "", + "EnableRestartGracePeriod": "", + "RestartGracePeriodInMinutes": "", + "RestartCountDownDisplayInMinutes": "", + "RestartNotificationSnoozeInMinutes": "" + } + ] +} \ No newline at end of file diff --git a/Apps/FirefoxESR/appList.json b/Apps/FirefoxESR/appList.json new file mode 100644 index 0000000..bcfb2c3 --- /dev/null +++ b/Apps/FirefoxESR/appList.json @@ -0,0 +1,15 @@ +{ + "IntuneAppName": "Mozilla Firefox ESR", + "IntuneAppNamingConvention": "AppName", + "AppPublisher": "Mozilla", + "AppSource": "Evergreen", + "AppID": "MozillaFirefox", + "AppFolderName": "FireFox", + "FilterOptions": [ + { + "Architecture": "x64", + "Type": "exe", + "Channel": "Extended Support" + } + ] +} \ No newline at end of file