-
Notifications
You must be signed in to change notification settings - Fork 8
/
Install.ps1
372 lines (324 loc) · 17.7 KB
/
Install.ps1
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
# Standalone application install script for VDI environment - (C)2023 Jonathan Pitre
#Requires -Version 5.1
#Requires -RunAsAdministrator
#---------------------------------------------------------[Initialisations]--------------------------------------------------------
#region Initialisations
$ProgressPreference = "SilentlyContinue"
$ErrorActionPreference = "SilentlyContinue"
# Set the script execution policy for this process
Try { Set-ExecutionPolicy -ExecutionPolicy 'ByPass' -Scope 'Process' -Force } Catch {}
# Unblock ps1 script
Get-ChildItem -Recurse *.ps*1 | Unblock-File
$env:SEE_MASK_NOZONECHECKS = 1
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
[System.Net.WebRequest]::DefaultWebProxy.Credentials = [System.Net.CredentialCache]::DefaultCredentials
$Modules = @("PSADT", "Evergreen") # Modules list
Function Get-ScriptPath
{
<#
.SYNOPSIS
Get-ScriptPath returns the path of the current script.
.OUTPUTS
System.String
#>
[CmdletBinding()]
[OutputType([string])]
Param()
Begin
{
Remove-Variable appScriptPath
}
Process
{
If ($psEditor) { Split-Path -Path $psEditor.GetEditorContext().CurrentFile.Path } # Visual Studio Code
ElseIf ($MyInvocation.MyCommand.CommandType -eq "ExternalScript") { Split-Path -Path $My$MyInvocation.MyCommand.Source } # PS1 converted to EXE
ElseIf ($null -ne $HostInvocation) { $HostInvocation.MyCommand.Path } # SAPIEN PowerShell Studio
ElseIf ($psISE) { Split-Path -Path $psISE.CurrentFile.FullPath } # Windows PowerShell ISE
ElseIf ($MyInvocation.PSScriptRoot) { $MyInvocation.PSScriptRoot } # Windows PowerShell 3.0+
ElseIf ($MyInvocation.MyCommand.Path) { Split-Path -Path $MyInvocation.MyCommand.Path -Parent } # Windows PowerShell
Else
{
Write-Host -Object "Unable to resolve script's file path!" -ForegroundColor Red
Exit 1
}
}
}
Function Get-ScriptName
{
<#
.SYNOPSIS
Get-ScriptName returns the name of the current script.
.OUTPUTS
System.String
#>
[CmdletBinding()]
[OutputType([string])]
Param()
Begin
{
Remove-Variable appScriptName
}
Process
{
If ($psEditor) { Split-Path -Path $psEditor.GetEditorContext().CurrentFile.Path -Leaf } # Visual Studio Code Host
ElseIf ($psEXE) { [System.Diagnotics.Process]::GetCurrentProcess.Name } # PS1 converted to EXE
ElseIf ($null -ne $HostInvocation) { $HostInvocation.MyCommand.Name } # SAPIEN PowerShell Studio
ElseIf ($psISE) { $psISE.CurrentFile.DisplayName.Trim("*") } # Windows PowerShell ISE
ElseIf ($MyInvocation.MyCommand.Name) { $MyInvocation.MyCommand.Name } # Windows PowerShell
Else
{
Write-Host -Object "Uanble to resolve script's file name!" -ForegroundColor Red
Exit 1
}
}
}
Function Initialize-Module
{
<#
.SYNOPSIS
Initialize-Module install and import modules from PowerShell Galllery.
.OUTPUTS
System.String
#>
[CmdletBinding()]
Param
(
[Parameter(Mandatory = $true)]
[string]$Module
)
Write-Host -Object "Importing $Module module..." -ForegroundColor Green
# If module is imported say that and do nothing
If (Get-Module | Where-Object { $_.Name -eq $Module })
{
Write-Host -Object "Module $Module is already imported." -ForegroundColor Green
}
Else
{
# If module is not imported, but available on disk then import
If ( [boolean](Get-Module -ListAvailable | Where-Object { $_.Name -eq $Module }) )
{
$InstalledModuleVersion = (Get-InstalledModule -Name $Module).Version
$ModuleVersion = (Find-Module -Name $Module).Version
$ModulePath = (Get-InstalledModule -Name $Module).InstalledLocation
$ModulePath = (Get-Item -Path $ModulePath).Parent.FullName
If ([version]$ModuleVersion -gt [version]$InstalledModuleVersion)
{
Update-Module -Name $Module -Force
Remove-Item -Path $ModulePath\$InstalledModuleVersion -Force -Recurse
Write-Host -Object "Module $Module was updated." -ForegroundColor Green
}
Import-Module -Name $Module -Force -Global -DisableNameChecking
Write-Host -Object "Module $Module was imported." -ForegroundColor Green
}
Else
{
# Install Nuget
If (-not(Get-PackageProvider -ListAvailable -Name NuGet))
{
Install-PackageProvider -Name NuGet -MinimumVersion 2.8.5.201 -Force
Write-Host -Object "Package provider NuGet was installed." -ForegroundColor Green
}
# Add the Powershell Gallery as trusted repository
If ((Get-PSRepository -Name "PSGallery").InstallationPolicy -eq "Untrusted")
{
Set-PSRepository -Name "PSGallery" -InstallationPolicy Trusted
Write-Host -Object "PowerShell Gallery is now a trusted repository." -ForegroundColor Green
}
# Update PowerShellGet
$InstalledPSGetVersion = (Get-PackageProvider -Name PowerShellGet).Version
$PSGetVersion = [version](Find-PackageProvider -Name PowerShellGet).Version
If ($PSGetVersion -gt $InstalledPSGetVersion)
{
Install-PackageProvider -Name PowerShellGet -Force
Write-Host -Object "PowerShellGet Gallery was updated." -ForegroundColor Green
}
# If module is not imported, not available on disk, but is in online gallery then install and import
If (Find-Module -Name $Module | Where-Object { $_.Name -eq $Module })
{
# Install and import module
Install-Module -Name $Module -AllowClobber -Force -Scope AllUsers
Import-Module -Name $Module -Force -Global -DisableNameChecking
Write-Host -Object "Module $Module was installed and imported." -ForegroundColor Green
}
Else
{
# If the module is not imported, not available and not in the online gallery then abort
Write-Host -Object "Module $Module was not imported, not available and not in an online gallery, exiting." -ForegroundColor Red
EXIT 1
}
}
}
}
[string]$appScriptPath = Get-ScriptPath # Get the current script path
[string]$appScriptName = Get-ScriptName # Get the current script name
# Install and import modules list
Foreach ($Module in $Modules)
{
Initialize-Module -Module $Module
}
#endregion
#-----------------------------------------------------------[Functions]------------------------------------------------------------
#region Functions
#endregion
#----------------------------------------------------------[Declarations]----------------------------------------------------------
#region Declarations
$appVendor = "Google"
$appName = "Chrome"
$appLongName = "Enterprise"
$appArchitecture = "x64"
$appChannel = "stable"
$appProcesses = @("chrome", "GoogleUpdate", "chrome_proxy", "elevation_service")
$appServices = @("gupdate", "gupdatem", "GoogleChromeElevationService")
$appInstallParameters = "/QB"
$Evergreen = Get-EvergreenApp -Name GoogleChrome | Where-Object { $_.Architecture -eq $appArchitecture -and $_.Channel -eq $appChannel -and $_.Type -eq "msi"}
$appVersion = $Evergreen.Version
$appURL = $Evergreen.URI
$appSetup = Split-Path -Path $appURL -Leaf
$appConfigURL = "https://raw.githubusercontent.com/JonathanPitre/Apps/master/Google/Chrome%20Enterprise/master_preferences"
$appConfig = Split-Path -Path $appConfigURL -Leaf
$appDestination = "$env:ProgramFiles\$appVendor\$appName\Application"
[boolean]$IsAppInstalled = [boolean](Get-InstalledApplication -Name "$appVendor $appName" -Exact)
$appInstalledVersion = (Get-InstalledApplication -Name "$appVendor $appName" -Exact).DisplayVersion | Select-Object -First 1
#endregion
#-----------------------------------------------------------[Execution]------------------------------------------------------------
#region Execution
If ([version]$appVersion -gt [version]$appInstalledVersion)
{
Set-Location -Path $appScriptPath
If (-Not(Test-Path -Path $appVersion)) { New-Folder -Path $appVersion }
Set-Location -Path $appVersion
# Delete machine policies to prevent issue during installation
Remove-RegistryKey -Key "HKLM:\SOFTWARE\Policies\$appVendor\Update" -Recurse -ContinueOnError $True
Remove-RegistryKey -Key "HKLM:\SOFTWARE\Policies\$appVendor\$appName" -Recurse -ContinueOnError $True
Remove-RegistryKey -Key "HKLM:\SOFTWARE\WOW6432Node\Policies\$appVendor\Temp" -Recurse -ContinueOnError $True
Remove-RegistryKey -Key "HKLM:\SOFTWARE\WOW6432Node\Policies\$appVendor\Update" -Recurse -ContinueOnError $True
Remove-RegistryKey -Key "HKLM:\SOFTWARE\WOW6432Node\Policies\$appVendor\$appName" -Recurse -ContinueOnError $True
# Uninstall previous versions
Get-Process -Name $appProcesses | Stop-Process -Force
If ($IsAppInstalled)
{
Write-Log -Message "Uninstalling previous versions..." -Severity 1 -LogType CMTrace -WriteHost $True
Remove-MSIApplications -Name "$appVendor $appName" -Parameters $appInstallParameters
Remove-MSIApplications -Name $($appVendor)Update -Parameters $appInstallParameters
}
# Uninstall Google Update
If (Test-Path -Path "$env%LocalAppData\$appVendor\Update\$($appVendor)Update.exe")
{
Write-Log -Message "Removing previous $appVendor $appName $appLongName folder to fix issues with new installation." -Severity 1 -LogType CMTrace -WriteHost $True
Execute-Process -Path "$envLocalAppData\$appVendor\Update\$($appVendor)Update.exe" -Parameters "-uninstall" -IgnoreExitCodes 1606220281 -ContinueOnError $True
}
If (Test-Path -Path "$envProgramFilesX86\$appVendor\Update\$($appVendor)Update.exe")
{
Write-Log -Message "Removing previous $appVendor $appName $appLongName folder to fix issues with new installation." -Severity 1 -LogType CMTrace -WriteHost $True
Execute-Process -Path "$envProgramFilesX86\$appVendor\Update\$($appVendor)Update.exe" -Parameters "-uninstall" -IgnoreExitCodes * -ContinueOnError $True
}
# Remove previous install folders
Remove-Folder -Path "$envLocalAppData\$appVendor\$appName" -ContinueOnError $True
Remove-Folder -Path "$envLocalAppData\$appVendor\Update" -ContinueOnError $True
Remove-Folder -Path "$envLocalAppData\$appVendor\Software Reporter Tool" -ContinueOnError $True
Remove-Folder -Path "$envLocalAppData\$appVendor\Policies" -ContinueOnError $True
Remove-Folder -Path "$envLocalAppData\$appVendor\Temp" -ContinueOnError $True
Remove-Folder -Path "$envLocalAppData\$appVendor\CrashReports" -ContinueOnError $True
Remove-Folder -Path "$envProgramFilesX86\$appVendor\$appName" -ContinueOnError $True
Remove-Folder -Path "$envProgramFilesX86\$appVendor\Update" -ContinueOnError $True
Remove-Folder -Path "$envProgramFilesX86\$appVendor\Policies" -ContinueOnError $True
Remove-Folder -Path "$envProgramFilesX86\$appVendor\Temp" -ContinueOnError $True
Remove-Folder -Path "$envProgramFilesX86\$appVendor\CrashReports" -ContinueOnError $True
Remove-Folder -Path "$envProgramFiles\$appVendor\$appName" -ContinueOnError $True
Remove-Folder -Path "$envProgramFiles\$appVendor\Update" -ContinueOnError $True
Remove-Folder -Path "$envProgramFiles\$appVendor\Policies" -ContinueOnError $True
Remove-Folder -Path "$envProgramFiles\$appVendor\Temp" -ContinueOnError $True
Remove-Folder -Path "$envProgramFiles\$appVendor\CrashReports" -ContinueOnError $True
# Remove previous registry entries
If ([boolean](Get-RegistryKey -Key "HKCU:\Software\Google\Chrome")) { Remove-RegistryKey -Key "HKCU:\Software\Google\Chrome" -Recurse -ContinueOnError $True }
If ([boolean](Get-RegistryKey -Key "HKCU:\Software\Google\Update")) { Remove-RegistryKey -Key "HKCU:\Software\Google\Update" -Recurse -ContinueOnError $True }
If ([boolean](Get-RegistryKey -Key "HKLM:\SOFTWARE\Google\Chrome")) { Remove-RegistryKey -Key "HKLM:\SOFTWARE\Google\Chrome" -Recurse -ContinueOnError $True }
If ([boolean](Get-RegistryKey -Key "HKLM:\SOFTWARE\Google\Update")) { Remove-RegistryKey -Key "HKLM:\SOFTWARE\Google\Update" -Recurse -ContinueOnError $True }
If ([boolean](Get-RegistryKey -Key "HKLM:\SOFTWARE\WOW6432Node\Google\Update")) { Remove-RegistryKey -Key "HKLM:\SOFTWARE\WOW6432Node\Google\Update" -Recurse -ContinueOnError $True }
# Download latest setup file(s)
If (-Not(Test-Path -Path "$appScriptPath\$appVersion\$appSetup"))
{
Write-Log -Message "Downloading $appVendor $appName $appLongName $appVersion..." -Severity 1 -LogType CMTrace -WriteHost $True
Invoke-WebRequest -UseBasicParsing -Uri $appURL -OutFile "$appScriptPath\$appVersion\$appSetup"
}
Else
{
Write-Log -Message "File(s) already exists, download was skipped." -Severity 1 -LogType CMTrace -WriteHost $True
}
# Download required config file
If (-Not(Test-Path -Path "$appScriptPath\$appConfig"))
{
Write-Log -Message "Downloading $appVendor $appName Config.." -Severity 1 -LogType CMTrace -WriteHost $True
Invoke-WebRequest -UseBasicParsing -Uri $appConfigURL -OutFile "$appScriptPath\$appConfig"
}
Else
{
Write-Log -Message "File(s) already exists, download was skipped." -Severity 1 -LogType CMTrace -WriteHost $True
}
# Install latest version
Write-Log -Message "Installing $appVendor $appName $appLongName $appVersion..." -Severity 1 -LogType CMTrace -WriteHost $True
Execute-MSI -Action Install -Path $appSetup -Parameters $appInstallParameters
Write-Log -Message "Applying customizations..." -Severity 1 -LogType CMTrace -WriteHost $True
# Copy preferences file
Copy-File -Path "$appScriptPath\master_preferences" -Destination $appDestination
# Stop and disable unneeded scheduled tasks
Get-ScheduledTask -TaskName "$appVendor*" | Stop-ScheduledTask
Get-ScheduledTask -TaskName "$appVendor*" | Disable-ScheduledTask
# Stop and disable unneeded services
Stop-ServiceAndDependencies -Name $appServices[0]
#Stop-ServiceAndDependencies -Name $appServices[1]
#Stop-ServiceAndDependencies -Name $appServices[2]
Set-ServiceStartMode -Name $appServices[0] -StartMode "Manual"
#Set-ServiceStartMode -Name $appServices[1] -StartMode "Disabled"
#Set-ServiceStartMode -Name $appServices[2] -StartMode "Disabled"
# Remove Active Setup - https://dennisspan.com/google-chrome-on-citrix-deep-dive/#StubPath
Remove-RegistryKey -Key "HKLM:\SOFTWARE\Microsoft\Active Setup\Installed Components\{8A69D345-D564-463c-AFF1-A69D9E530F96}" -Name "StubPath"
# Disable autoupdate
Set-RegistryKey -Key "HKLM:\SOFTWARE\Google\Update" -Name "Update{8A69D345-D564-463C-AFF1-A69D9E530F96}" -Value "0" -Type DWord
Set-RegistryKey -Key "HKLM:\SOFTWARE\Google\Update" -Name "UpdateDefault" -Value "0" -Type DWord
# Disable per-user installation
Set-RegistryKey -Key "HKLM:\SOFTWARE\Google\Update" -Name "Install{8A69D345-D564-463C-AFF1-A69D9E530F96}" -Value "0" -Type DWord
# Disable default browser check
Set-RegistryKey -Key "HKLM:\SOFTWARE\Google\Update" -Name "DefaultBrowserSettingEnabled" -Value "0" -Type DWord
# Creates a pinned taskbar icons for all users
New-Shortcut -Path "$envSystemDrive\Users\Default\AppData\Roaming\Microsoft\Internet Explorer\Quick Launch\User Pinned\Taskbar\$appVendor $appName.lnk" -TargetPath "$appDestination\$($appProcesses[0]).exe" -IconLocation "$appDestination\$($appProcesses[0]).exe" -Description "$appVendor $appName" -WorkingDirectory "$appDestination"
# Configure application shortcut
Remove-File -Path "$envCommonDesktop\$appVendor $appName.lnk" -ContinueOnError $True
Remove-File -Path "$envUserDesktop\$appVendor $appName.lnk" -ContinueOnError $True
# Fix an issue with Citrix Virtual Delivery Agent - https://support.google.com/chrome/a/answer/7380899?hl=en
[boolean]$isCitrixVdaInstalled = [boolean](Get-InstalledApplication -Name "Citrix .*Virtual Delivery Agent.*" -RegEx)
$ctxHookExcludedProcesses = ""
If ($isCitrixVdaInstalled)
{
$ctxHookExcludedProcesses = (Get-RegistryKey -Key "HKLM:\SOFTWARE\Citrix\CtxHook" -Value "ExcludedImageNames")
$ctxHookProcessesToAdd = @("chrome.exe", "nacl64.exe")
If (-Not([String]::IsNullOrEmpty($ctxHookExcludedProcesses)))
{
ForEach ($ctxHookProcessToAdd in $ctxHookProcessesToAdd)
{
If ($ctxHookExcludedProcesses -like "*$ctxHookProcessToAdd*")
{
Write-Log -Message "The $ctxHookProcessToAdd processes have already been added." -Severity 2 -LogType CMTrace -WriteHost $True
}
Else
{
$ctxHookExcludedProcesses = $ctxHookExcludedProcesses + "," + $ctxHookProcessToAdd
}
}
}
Else
{
$ctxHookExcludedProcesses = "chrome.exe,nacl64.exe"
}
Set-RegistryKey -Key "HKLM:\SOFTWARE\Citrix\CtxHook" -Name "ExcludedImageNames" -Value $ctxHookExcludedProcesses -Type String
Write-Log -Message "$appVendor $appName $appLongName fix for Citrix Virtual Delivery Agent was applied successfully!" -Severity 1 -LogType CMTrace -WriteHost $True
}
# Go back to the parent folder
Set-Location ..
Write-Log -Message "$appVendor $appName $appLongName $appVersion was installed successfully!" -Severity 1 -LogType CMTrace -WriteHost $True
}
Else
{
Write-Log -Message "$appVendor $appName $appLongName $appInstalledVersion is already installed." -Severity 1 -LogType CMTrace -WriteHost $True
}
#endregion