-
-
Notifications
You must be signed in to change notification settings - Fork 274
/
Manage-Chocolatey.psm1
201 lines (169 loc) · 8.53 KB
/
Manage-Chocolatey.psm1
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
Import-Module -DisableNameChecking "$PSScriptRoot\Install-PackageManager.psm1"
Import-Module -DisableNameChecking "$PSScriptRoot\Manage-DailyUpgradeJob.psm1"
Import-Module -DisableNameChecking "$PSScriptRoot\..\Title-Templates.psm1"
Import-Module -DisableNameChecking "$PSScriptRoot\..\ui\Show-MessageDialog.psm1"
$Script:DoneTitle = "Information"
$Script:DoneMessage = "Process Completed!"
function Install-Chocolatey() {
[CmdletBinding()]
param (
[Switch] $Force
)
Begin {
$ChocolateyParams = @{
Name = "Chocolatey"
CheckExistenceBlock = { choco --version }
InstallCommandBlock =
{
Set-ExecutionPolicy Bypass -Scope Process -Force
[System.Net.ServicePointManager]::SecurityProtocol = [System.Net.ServicePointManager]::SecurityProtocol -bor 3072
Invoke-Expression ((New-Object System.Net.WebClient).DownloadString('https://chocolatey.org/install.ps1'))
}
PostInstallBlock = { choco install --ignore-dependencies --yes "chocolatey-core.extension" "chocolatey-fastanswers.extension" }
}
}
Process {
If ($Force) {
# Install Chocolatey on Windows
Install-PackageManager -PackageManagerFullName $ChocolateyParams.Name -CheckExistenceBlock $ChocolateyParams.CheckExistenceBlock -InstallCommandBlock $ChocolateyParams.InstallCommandBlock -PostInstallBlock $ChocolateyParams.PostInstallBlock -Force
} Else {
Install-PackageManager -PackageManagerFullName $ChocolateyParams.Name -CheckExistenceBlock $ChocolateyParams.CheckExistenceBlock -InstallCommandBlock $ChocolateyParams.InstallCommandBlock -PostInstallBlock $ChocolateyParams.PostInstallBlock
}
If (!$Force) {
Show-MessageDialog -Title "$DoneTitle" -Message "$DoneMessage"
}
}
}
# Adapted From: https://community.chocolatey.org/courses/installation/uninstalling#script
function Uninstall-Chocolatey() {
Process {
$VerbosePreference = 'Continue'
if (-not $env:ChocolateyInstall) {
$message = @(
"The ChocolateyInstall environment variable was not found."
"Chocolatey is not detected as installed. Nothing to do."
) -join "`n"
Write-Warning $message
return Show-MessageDialog -Title "$DoneTitle" -Message "$DoneMessage"
}
if (-not (Test-Path $env:ChocolateyInstall)) {
$message = @(
"No Chocolatey installation detected at '$env:ChocolateyInstall'."
"Nothing to do."
) -join "`n"
Write-Warning $message
return Show-MessageDialog -Title "$DoneTitle" -Message "$DoneMessage"
}
<#
Using the .NET registry calls is necessary here in order to preserve environment variables embedded in PATH values;
Powershell's registry provider doesn't provide a method of preserving variable references, and we don't want to
accidentally overwrite them with absolute path values. Where the registry allows us to see "%SystemRoot%" in a PATH
entry, PowerShell's registry provider only sees "C:\Windows", for example.
#>
$userKey = [Microsoft.Win32.Registry]::CurrentUser.OpenSubKey('Environment', $true)
$userPath = $userKey.GetValue('PATH', [string]::Empty, 'DoNotExpandEnvironmentNames').ToString()
$machineKey = [Microsoft.Win32.Registry]::LocalMachine.OpenSubKey('SYSTEM\ControlSet001\Control\Session Manager\Environment\', $true)
$machinePath = $machineKey.GetValue('PATH', [string]::Empty, 'DoNotExpandEnvironmentNames').ToString()
$backupPATHs = @(
"User PATH: $userPath"
"Machine PATH: $machinePath"
)
$backupFile = "C:\PATH_backups_ChocolateyUninstall.txt"
$backupPATHs | Set-Content -Path $backupFile -Encoding UTF8 -Force
$warningMessage = @"
This could cause issues after reboot where nothing is found if something goes wrong.
In that case, look at the backup file for the original PATH values in '$backupFile'.
"@
if ($userPath -like "*$env:ChocolateyInstall*") {
Write-Verbose "Chocolatey Install location found in User Path. Removing..."
Write-Warning $warningMessage
$newUserPATH = @(
$userPath -split [System.IO.Path]::PathSeparator |
Where-Object { $_ -and $_ -ne "$env:ChocolateyInstall\bin" }
) -join [System.IO.Path]::PathSeparator
# NEVER use [Environment]::SetEnvironmentVariable() for PATH values; see https://github.com/dotnet/corefx/issues/36449
# This issue exists in ALL released versions of .NET and .NET Core as of 12/19/2019
$userKey.SetValue('PATH', $newUserPATH, 'ExpandString')
}
if ($machinePath -like "*$env:ChocolateyInstall*") {
Write-Verbose "Chocolatey Install location found in Machine Path. Removing..."
Write-Warning $warningMessage
$newMachinePATH = @(
$machinePath -split [System.IO.Path]::PathSeparator |
Where-Object { $_ -and $_ -ne "$env:ChocolateyInstall\bin" }
) -join [System.IO.Path]::PathSeparator
# NEVER use [Environment]::SetEnvironmentVariable() for PATH values; see https://github.com/dotnet/corefx/issues/36449
# This issue exists in ALL released versions of .NET and .NET Core as of 12/19/2019
$machineKey.SetValue('PATH', $newMachinePATH, 'ExpandString')
}
# Adapt for any services running in subfolders of ChocolateyInstall
$agentService = Get-Service -Name chocolatey-agent -ErrorAction SilentlyContinue
if ($agentService -and $agentService.Status -eq 'Running') {
$agentService.Stop()
}
# TODO: add other services here
Remove-Item -Path $env:ChocolateyInstall -Recurse -Force
'ChocolateyInstall', 'ChocolateyLastPathUpdate' | ForEach-Object {
foreach ($scope in 'User', 'Machine') {
[Environment]::SetEnvironmentVariable($_, [string]::Empty, $scope)
}
}
$machineKey.Close()
$userKey.Close()
if ($env:ChocolateyToolsLocation -and (Test-Path $env:ChocolateyToolsLocation)) {
Remove-Item -Path $env:ChocolateyToolsLocation -Recurse -Force
}
foreach ($scope in 'User', 'Machine') {
[Environment]::SetEnvironmentVariable('ChocolateyToolsLocation', [string]::Empty, $scope)
}
Show-MessageDialog -Title "$DoneTitle" -Message "$DoneMessage"
}
}
function Register-ChocolateyDailyUpgrade() {
Begin {
$ChocolateyJobParams = @{
Name = "Chocolatey"
Time = "13:00"
UpdateScriptBlock =
{
Remove-Item -Path "$env:TEMP\Win-Debloat-Tools\logs\*" -Include "ChocolateyDailyUpgrade_*.log"
Start-Transcript -Path "$env:TEMP\Win-Debloat-Tools\logs\ChocolateyDailyUpgrade_$(Get-Date -Format "yyyy-MM-dd_HH-mm-ss").log"
choco upgrade all --ignore-dependencies --yes | Out-Host
Stop-Transcript
}
}
}
Process {
Register-DailyUpgradeJob -PackageManagerFullName $ChocolateyJobParams.Name -Time $ChocolateyJobParams.Time -UpdateScriptBlock $ChocolateyJobParams.UpdateScriptBlock
Show-MessageDialog -Title "$DoneTitle" -Message "$DoneMessage"
}
}
function Unregister-ChocolateyDailyUpgrade() {
Begin {
$JobName = "Chocolatey Daily Upgrade"
}
Process {
Unregister-DailyUpgradeJob -Name $JobName
Show-MessageDialog -Title "$DoneTitle" -Message "$DoneMessage"
}
}
function Remove-AllChocolateyPackage() {
Begin {
Import-Module -DisableNameChecking "$PSScriptRoot\Manage-Software.psm1"
$Ask = "Are you sure you want to remove:`n$((choco list) -match '\w \d.*\d' | ForEach-Object { "`n- $_" })`n`nPress YES to confirm."
$Question = Show-Question -Title "Remove ALL Chocolatey Packages?" -Message $Ask -BoxIcon "Warning"
}
Process {
switch ($Question) {
'Yes' {
Uninstall-Software -Name "All Chocolatey Packages" -Packages @("all") -PackageProvider 'Chocolatey'
}
'No' {
Write-Host "Aborting..."
}
'Cancel' {
Write-Host "Aborting..." # With Yes, No and Cancel, the user can press Esc to exit
}
}
}
}