forked from ChrisTitusTech/winutil
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathInstall-WinUtilProgramChoco.ps1
More file actions
258 lines (204 loc) · 9.82 KB
/
Install-WinUtilProgramChoco.ps1
File metadata and controls
258 lines (204 loc) · 9.82 KB
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
function Install-WinUtilProgramChoco {
<#
.SYNOPSIS
Manages the installation or uninstallation of a list of Chocolatey packages.
.PARAMETER Programs
A string array containing the programs to be installed or uninstalled.
.PARAMETER Action
Specifies the action to perform: "Install" or "Uninstall". The default value is "Install".
.DESCRIPTION
This function processes a list of programs to be managed using Chocolatey. Depending on the specified action, it either installs or uninstalls each program in the list, updating the taskbar progress accordingly. After all operations are completed, temporary output files are cleaned up.
.EXAMPLE
Install-WinUtilProgramChoco -Programs @("7zip","chrome") -Action "Uninstall"
#>
param(
[Parameter(Mandatory, Position = 0)]
[string[]]$Programs,
[Parameter(Position = 1)]
[String]$Action = "Install"
)
function Initialize-OutputFile {
<#
.SYNOPSIS
Initializes an output file by removing any existing file and creating a new, empty file at the specified path.
.PARAMETER filePath
The full path to the file to be initialized.
.DESCRIPTION
This function ensures that the specified file is reset by removing any existing file at the provided path and then creating a new, empty file. It is useful when preparing a log or output file for subsequent operations.
.EXAMPLE
Initialize-OutputFile -filePath "C:\temp\output.txt"
#>
param ($filePath)
Remove-Item -Path $filePath -Force -ErrorAction SilentlyContinue
New-Item -ItemType File -Path $filePath | Out-Null
}
function Invoke-ChocoCommand {
<#
.SYNOPSIS
Executes a Chocolatey command with the specified arguments and returns the exit code.
.PARAMETER arguments
The arguments to be passed to the Chocolatey command.
.DESCRIPTION
This function runs a specified Chocolatey command by passing the provided arguments to the `choco` executable. It waits for the process to complete and then returns the exit code, allowing the caller to determine success or failure based on the exit code.
.RETURNS
[int]
The exit code of the Chocolatey command.
.EXAMPLE
$exitCode = Invoke-ChocoCommand -arguments "install 7zip -y"
#>
param ($arguments)
return (Start-Process -FilePath "choco" -ArgumentList $arguments -Wait -PassThru).ExitCode
}
function Test-UpgradeNeeded {
<#
.SYNOPSIS
Checks if an upgrade is needed for a Chocolatey package based on the content of a log file.
.PARAMETER filePath
The path to the log file that contains the output of a Chocolatey install command.
.DESCRIPTION
This function reads the specified log file and checks for keywords that indicate whether an upgrade is needed. It returns a boolean value indicating whether the terms "reinstall" or "already installed" are present, which suggests that the package might need an upgrade.
.RETURNS
[bool]
True if the log file indicates that an upgrade is needed; otherwise, false.
.EXAMPLE
$isUpgradeNeeded = Test-UpgradeNeeded -filePath "C:\temp\install-output.txt"
#>
param ($filePath)
return Get-Content -Path $filePath | Select-String -Pattern "reinstall|already installed" -Quiet
}
function Update-TaskbarProgress {
<#
.SYNOPSIS
Updates the taskbar progress based on the current installation progress.
.PARAMETER currentIndex
The current index of the program being installed or uninstalled.
.PARAMETER totalPrograms
The total number of programs to be installed or uninstalled.
.DESCRIPTION
This function calculates the progress of the installation or uninstallation process and updates the taskbar accordingly. The taskbar is set to "Normal" if all programs have been processed, otherwise, it is set to "Error" as a placeholder.
.EXAMPLE
Update-TaskbarProgress -currentIndex 3 -totalPrograms 10
#>
param (
[int]$currentIndex,
[int]$totalPrograms
)
$progressState = if ($currentIndex -eq $totalPrograms) { "Normal" } else { "Error" }
Invoke-WPFUIThread -ScriptBlock { Set-WinUtilTaskbaritem -state $progressState -value ($currentIndex / $totalPrograms) }
}
function Install-ChocoPackage {
<#
.SYNOPSIS
Installs a Chocolatey package and optionally upgrades it if needed.
.PARAMETER Program
A string containing the name of the Chocolatey package to be installed.
.PARAMETER currentIndex
The current index of the program in the list of programs to be managed.
.PARAMETER totalPrograms
The total number of programs to be installed.
.DESCRIPTION
This function installs a Chocolatey package by running the `choco install` command. If the installation output indicates that an upgrade might be needed, the function will attempt to upgrade the package. The taskbar progress is updated after each package is processed.
.EXAMPLE
Install-ChocoPackage -Program $Program -currentIndex 0 -totalPrograms 5
#>
param (
[string]$Program,
[int]$currentIndex,
[int]$totalPrograms
)
$installOutputFile = "$env:TEMP\Install-WinUtilProgramChoco.install-command.output.txt"
Initialize-OutputFile $installOutputFile
Write-Host "Starting installation of $Program with Chocolatey."
try {
$installStatusCode = Invoke-ChocoCommand "install $Program -y --log-file $installOutputFile"
if ($installStatusCode -eq 0) {
if (Test-UpgradeNeeded $installOutputFile) {
$upgradeStatusCode = Invoke-ChocoCommand "upgrade $Program -y"
Write-Host "$Program was" $(if ($upgradeStatusCode -eq 0) { "upgraded successfully." } else { "not upgraded." })
}
else {
Write-Host "$Program installed successfully."
}
}
else {
Write-Host "Failed to install $Program."
}
}
catch {
Write-Host "Failed to install $Program due to an error: $_"
}
finally {
Update-TaskbarProgress $currentIndex $totalPrograms
}
}
function Uninstall-ChocoPackage {
<#
.SYNOPSIS
Uninstalls a Chocolatey package and any related metapackages.
.PARAMETER Program
A string containing the name of the Chocolatey package to be uninstalled.
.PARAMETER currentIndex
The current index of the program in the list of programs to be managed.
.PARAMETER totalPrograms
The total number of programs to be uninstalled.
.DESCRIPTION
This function uninstalls a Chocolatey package and any related metapackages (e.g., .install or .portable variants). It updates the taskbar progress after processing each package.
.EXAMPLE
Uninstall-ChocoPackage -Program $Program -currentIndex 0 -totalPrograms 5
#>
param (
[string]$Program,
[int]$currentIndex,
[int]$totalPrograms
)
$uninstallOutputFile = "$env:TEMP\Install-WinUtilProgramChoco.uninstall-command.output.txt"
Initialize-OutputFile $uninstallOutputFile
Write-Host "Searching for metapackages of $Program (.install or .portable)"
$chocoPackages = ((choco list | Select-String -Pattern "$Program(\.install|\.portable)?").Matches.Value) -join " "
if ($chocoPackages) {
Write-Host "Starting uninstallation of $chocoPackages with Chocolatey."
try {
$uninstallStatusCode = Invoke-ChocoCommand "uninstall $chocoPackages -y"
Write-Host "$Program" $(if ($uninstallStatusCode -eq 0) { "uninstalled successfully." } else { "failed to uninstall." })
}
catch {
Write-Host "Failed to uninstall $Program due to an error: $_"
}
finally {
Update-TaskbarProgress $currentIndex $totalPrograms
}
}
else {
Write-Host "$Program is not installed."
}
}
$totalPrograms = $Programs.Count
if ($totalPrograms -le 0) {
throw "Parameter 'Programs' must have at least one item."
}
Write-Host "==========================================="
Write-Host "-- Configuring Chocolatey packages ---"
Write-Host "==========================================="
for ($currentIndex = 0; $currentIndex -lt $totalPrograms; $currentIndex++) {
$Program = $Programs[$currentIndex]
Set-WinUtilProgressBar -label "$Action $($Program)" -percent ($currentIndex / $totalPrograms * 100)
Invoke-WPFUIThread -ScriptBlock { Set-WinUtilTaskbaritem -value ($currentIndex / $totalPrograms)}
switch ($Action) {
"Install" {
Install-ChocoPackage -Program $Program -currentIndex $currentIndex -totalPrograms $totalPrograms
}
"Uninstall" {
Uninstall-ChocoPackage -Program $Program -currentIndex $currentIndex -totalPrograms $totalPrograms
}
default {
throw "Invalid action parameter value: '$Action'."
}
}
}
Set-WinUtilProgressBar -label "$($Action)ation done" -percent 100
# Cleanup Output Files
$outputFiles = @("$env:TEMP\Install-WinUtilProgramChoco.install-command.output.txt", "$env:TEMP\Install-WinUtilProgramChoco.uninstall-command.output.txt")
foreach ($filePath in $outputFiles) {
Remove-Item -Path $filePath -Force -ErrorAction SilentlyContinue
}
}