|
<# |
|
.SYNOPSIS |
|
This script performs the installation or uninstallation of an application(s). |
|
.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: Application |
|
[string]$appVendor = 'Google' |
|
[string]$appName = 'Chrome' |
|
[string]$appVersion = '65.0.3325.181' |
|
[string]$appArch = 'x64' |
|
[string]$appLang = 'EN' |
|
[string]$appRevision = '01' |
|
[string]$appScriptVersion = '1.0.0' |
|
[string]$appScriptDate = '10/05/2018' |
|
[string]$appScriptAuthor = 'Lee Ramsay' |
|
##*=============================================== |
|
## 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.6.8' |
|
[string]$deployAppScriptDate = '02/06/2016' |
|
[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 'Chrome' -AllowDefer -DeferTimes 3 -CheckDiskSpace -PersistPrompt |
|
|
|
## Show Progress Message (with the default message) |
|
Show-InstallationProgress |
|
|
|
## <Perform Pre-Installation tasks here> |
|
|
|
# helpful chrome cleanup link |
|
# http://www.itninja.com/question/how-to-uninstall-any-version-google-chrome-there-is-no-uninstall-string-how-to-identify-the-version-and-uninstall-by-path-appdata-google-version-uninstall |
|
Execute-MSI -Action 'Uninstall' -Path '{82386CE6-6D7B-4912-A99B-2B86E3108EBC}' -ContinueOnError:$true |
|
$regKeyApplications | %{ |
|
if(test-path "$_\{82386CE6-6D7B-4912-A99B-2B86E3108EBC}") { Remove-RegistryKey -Key "$_\{82386CE6-6D7B-4912-A99B-2B86E3108EBC}" } |
|
} |
|
Execute-MSI -Action 'Uninstall' -Path '{B7C7346E-405F-3494-8C7F-7CE63551D9A2}' -ContinueOnError:$true |
|
$regKeyApplications | %{ |
|
if(test-path "$_\{B7C7346E-405F-3494-8C7F-7CE63551D9A2}") { Remove-RegistryKey -Key "$_\{B7C7346E-405F-3494-8C7F-7CE63551D9A2}" } |
|
} |
|
# this seems to be the only GUID like identifier under the clientstate reg 'folder', |
|
# and the only reliable, documented place where the uninstall instructions are. |
|
( |
|
'HKLM:\SOFTWARE\Wow6432Node\Google\Update\ClientState\{8A69D345-D564-463C-AFF1-A69D9E530F96}' |
|
) | % { |
|
if (Test-Path "$_" -Type Container) { #if above key is present, run uninstall |
|
$uninstall_key = Get-ItemProperty -Path "$_" |
|
$uninstall_exe = ($uninstall_key).UninstallString |
|
$uninstall_params = ($uninstall_key).UninstallArguments.TrimStart() #contains an empty space at the start of line *shrugs* |
|
$uninstall_params = "--force-uninstall $uninstall_params" #adding --force-uninstall, which basically means 'silent' |
|
Execute-Process -Path "$uninstall_exe" -Parameters "$uninstall_params" -WaitForMSIExec:$true -ContinueOnError:$true |
|
} |
|
} |
|
|
|
Get-ItemProperty -Path "Registry::HKEY_CLASSES_ROOT\Installer\Products\*" | ?{ $_.ProductName -eq "Google Chrome" } | %{ Remove-Item -Path $_.PSPath -Recurse }# need to pickup uninstaller and remove from registry |
|
|
|
|
|
|
|
##*=============================================== |
|
##* 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 $_ } } |
|
} |
|
|
|
## <Perform Installation tasks here> |
|
Execute-MSI -Action 'Install' -Path 'googlechromestandaloneenterprise64.msi' -Parameters "REBOOT=ReallySuppress /QN" |
|
|
|
##*=============================================== |
|
##* POST-INSTALLATION |
|
##*=============================================== |
|
[string]$installPhase = 'Post-Installation' |
|
|
|
## <Perform Post-Installation tasks here> |
|
Remove-File -Path "$envCommonDesktop\Google Chrome.lnk" |
|
Remove-File -Path "$envUserDesktop\Google Chrome.lnk" |
|
|
|
## <Copy master preferences file> |
|
|
|
if (Test-Path $envProgramFilesX86\Google\Chrome) { Copy-File -Path "$dirfiles\master_preferences" -Destination "$envProgramFilesX86\Google\Chrome\Application\master_preferences" } |
|
if (Test-Path $envProgramFiles\Google\Chrome) { Copy-File -Path "$dirfiles\master_preferences" -Destination "$envProgramFiles\Google\Chrome\Application\master_preferences" } |
|
|
|
#not sure about this one |
|
#Set-PinnedApplication -Action 'UnpinfromTaskbar' -FilePath "$envProgramFilesX86\Google\Chrome\Application\chrome.exe" |
|
|
|
## Display a message at the end of the install |
|
#If (-not $useDefaultMsi) { Show-InstallationPrompt -Message 'lee sucks.' -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 'Chrome' -CloseAppsCountdown 60 |
|
|
|
## Show Progress Message (with the default message) |
|
Show-InstallationProgress |
|
|
|
## <Perform Pre-Uninstallation tasks here> |
|
|
|
##*=============================================== |
|
##* 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 |
|
} |
|
|
|
# <Perform Uninstallation tasks here> |
|
|
|
# helpful chrome cleanup link, need to adapt |
|
# http://www.itninja.com/question/how-to-uninstall-any-version-google-chrome-there-is-no-uninstall-string-how-to-identify-the-version-and-uninstall-by-path-appdata-google-version-uninstall |
|
|
|
Execute-MSI -Action 'Uninstall' -Path '{82386CE6-6D7B-4912-A99B-2B86E3108EBC}' -ContinueOnError:$true |
|
$regKeyApplications | %{ |
|
if(test-path "$_\{82386CE6-6D7B-4912-A99B-2B86E3108EBC}") { Remove-RegistryKey -Key "$_\{82386CE6-6D7B-4912-A99B-2B86E3108EBC}" } |
|
} |
|
Execute-MSI -Action 'Uninstall' -Path '{B7C7346E-405F-3494-8C7F-7CE63551D9A2}' -ContinueOnError:$true |
|
$regKeyApplications | %{ |
|
if(test-path "$_\{B7C7346E-405F-3494-8C7F-7CE63551D9A2}") { Remove-RegistryKey -Key "$_\{B7C7346E-405F-3494-8C7F-7CE63551D9A2}" } |
|
} |
|
# this seems to be the only GUID like identifier under the clientstate reg 'folder', |
|
# and the only reliable, documented place where the uninstall instructions are. |
|
( |
|
'HKLM:\SOFTWARE\Wow6432Node\Google\Update\ClientState\{8A69D345-D564-463C-AFF1-A69D9E530F96}' |
|
) | % { |
|
if (Test-Path "$_" -Type Container) { #if above key is present, run uninstall |
|
$uninstall_key = Get-ItemProperty -Path "$_" |
|
$uninstall_exe = ($uninstall_key).UninstallString |
|
$uninstall_params = ($uninstall_key).UninstallArguments.TrimStart() #contains an empty space at the start of line *shrugs* |
|
$uninstall_params = "--force-uninstall $uninstall_params" #adding --force-uninstall, which basically means 'silent' |
|
Execute-Process -Path "$uninstall_exe" -Parameters "$uninstall_params" -WaitForMSIExec:$true -ContinueOnError:$true |
|
} |
|
} |
|
|
|
# need to pickup uninstaller and remove from registry |
|
Get-ItemProperty -Path "Registry::HKEY_CLASSES_ROOT\Installer\Products\*" | ?{ $_.ProductName -eq "Google Chrome" } | %{ Remove-Item -Path $_.PSPath -Recurse } |
|
|
|
##*=============================================== |
|
##* POST-UNINSTALLATION |
|
##*=============================================== |
|
[string]$installPhase = 'Post-Uninstallation' |
|
|
|
## <Perform Post-Uninstallation tasks here> |
|
|
|
|
|
} |
|
|
|
##*=============================================== |
|
##* 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 |
|
} |
Very Useful Thank you