CoreGit [changelog]
[gists] [register] [login]
gists / post_install.ps1 public plaintext
by erikbye ยท updated 2026-04-15 11:52
Raw Download
post_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
#Requires -RunAsAdministrator
<#
.SYNOPSIS
    Windows Post-Installation Automation Script
.DESCRIPTION
    Automates software installation via Chocolatey and applies Windows customizations.
    Fully automated - no prompts or user interaction required.
.PARAMETER dev
    Include development-specific software (Docker Desktop)
.EXAMPLE
    .\post_install.ps1
    .\post_install.ps1 -dev
#>

param(
    [switch]$dev
)

# ============================================================================
# CONFIGURATION
# ============================================================================

$cacheFolder = "c:\temp\chocolatey_cache"
$logFolder = "c:\temp"
$chocoLogFile = Join-Path $logFolder "chocolatey_main.log"

# Software packages to install (same on every machine)
$software = @(
    # Browsers & Internet
    "vivaldi",              # Web browser (replaced Firefox)

    # Security & Privacy
    "keepassxc",            # Password manager

    # File Management & Transfer
    "winscp",               # SFTP/FTP client (replaced FileZilla)
    "7zip",                 # File compression

    # Development Tools
    "vscode",               # Code editor
    "python",               # Python runtime
    "nodejs",
    "git",                  # Version control
    "gow",                  # GNU utilities for Windows

    # Media & Creative
    "vlc",                  # Media player
    "foobar",               # Media player
    "plex",                 # Media server
    "audacity",             # Audio editor
    "blender",              # 3D creation suite
    "ffmpeg",               # Media processing
    "yt-dlp",               # Video downloader
    "imagemagick",

    # Gaming
    "steam",                # Game platform
    "geforce-experience",   # NVIDIA GPU management

    # Utilities
    "powertoys",            # Microsoft PowerToys
    "qbittorrent",          # Torrent client
    "zerotier-one",         # Virtual networking

    # System
    "wsl2"                  # Windows Subsystem for Linux
)

# Development-specific software (only with -dev switch)
$devSoftware = @()
if ($dev) {
    $devSoftware = @(
        "docker-desktop"    # Container platform
    )
}

# Combine all software
$allSoftware = $software + $devSoftware

# ============================================================================
# ERROR HANDLING & VALIDATION
# ============================================================================

# Set error action preference
$ErrorActionPreference = "Stop"

Write-Host "`n========================================" -ForegroundColor Cyan
Write-Host "  Windows Post-Installation Script" -ForegroundColor Cyan
Write-Host "========================================`n" -ForegroundColor Cyan

# Check internet connectivity
Write-Host "[1/6] Checking internet connectivity..." -ForegroundColor Yellow
try {
    $null = Test-Connection -ComputerName chocolatey.org -Count 1 -Quiet -ErrorAction Stop
    Write-Host "      Internet connection OK`n" -ForegroundColor Green
} catch {
    Write-Host "      ERROR: No internet connection detected!" -ForegroundColor Red
    Write-Host "      Cannot proceed with installations.`n" -ForegroundColor Red
    exit 1
}

# ============================================================================
# SETUP DIRECTORIES
# ============================================================================

Write-Host "[2/6] Setting up directories..." -ForegroundColor Yellow
try {
    if (!(Test-Path -Path $cacheFolder)) {
        New-Item -ItemType Directory -Force -Path $cacheFolder | Out-Null
    }
    if (!(Test-Path -Path $logFolder)) {
        New-Item -ItemType Directory -Force -Path $logFolder | Out-Null
    }
    Set-Location -Path $logFolder
    Write-Host "      Cache: $cacheFolder" -ForegroundColor Gray
    Write-Host "      Logs:  $logFolder`n" -ForegroundColor Gray
} catch {
    Write-Host "      ERROR: Failed to create directories: $_`n" -ForegroundColor Red
    exit 1
}

# ============================================================================
# INSTALL CHOCOLATEY
# ============================================================================

Write-Host "[3/6] Checking Chocolatey installation..." -ForegroundColor Yellow
try {
    $choco = Get-Command -Name "choco" -ErrorAction SilentlyContinue

    if (!$choco) {
        Write-Host "      Chocolatey not found. Installing..." -ForegroundColor Yellow
        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'))

        # Refresh environment to get choco in PATH
        $env:Path = [System.Environment]::GetEnvironmentVariable("Path","Machine") + ";" + [System.Environment]::GetEnvironmentVariable("Path","User")

        # Verify installation
        $choco = Get-Command -Name "choco" -ErrorAction SilentlyContinue
        if (!$choco) {
            throw "Chocolatey installation failed - choco command not found after install"
        }
        Write-Host "      Chocolatey installed successfully" -ForegroundColor Green
    } else {
        Write-Host "      Chocolatey already installed" -ForegroundColor Green
    }

    # Enable global confirmation (no prompts)
    $result = choco feature enable -n allowGlobalConfirmation 2>&1
    Write-Host "      Auto-confirmation enabled`n" -ForegroundColor Gray

} catch {
    Write-Host "      ERROR: Chocolatey installation failed: $_`n" -ForegroundColor Red
    exit 1
}

# ============================================================================
# CHECK INSTALLED PACKAGES
# ============================================================================

Write-Host "[4/6] Scanning for already-installed packages..." -ForegroundColor Yellow
try {
    # Get list of installed packages
    $installedList = choco list --local-only --limit-output 2>&1 | Out-String
    $installedPackages = $installedList -split "`n" | ForEach-Object {
        if ($_ -match '^([^|]+)\|') {
            $matches[1].Trim()
        }
    } | Where-Object { $_ }

    # Filter out already-installed packages
    $packagesToInstall = @()
    $skippedPackages = @()

    foreach ($pkg in $allSoftware) {
        if ($installedPackages -contains $pkg) {
            $skippedPackages += $pkg
        } else {
            $packagesToInstall += $pkg
        }
    }

    Write-Host "      Found $($installedPackages.Count) total installed packages" -ForegroundColor Gray
    Write-Host "      Skipping $($skippedPackages.Count) already-installed packages" -ForegroundColor Cyan
    Write-Host "      Will install $($packagesToInstall.Count) new packages`n" -ForegroundColor Green

    if ($skippedPackages.Count -gt 0) {
        Write-Host "      Already installed:" -ForegroundColor Gray
        foreach ($pkg in $skippedPackages) {
            Write-Host "        - $pkg" -ForegroundColor DarkGray
        }
        Write-Host ""
    }

} catch {
    Write-Host "      WARNING: Could not check installed packages: $_" -ForegroundColor Yellow
    Write-Host "      Proceeding with all packages...`n" -ForegroundColor Yellow
    $packagesToInstall = $allSoftware
}

# ============================================================================
# INSTALL PACKAGES
# ============================================================================

if ($packagesToInstall.Count -eq 0) {
    Write-Host "[5/6] All packages already installed - nothing to do!`n" -ForegroundColor Green
} else {
    Write-Host "[5/6] Installing $($packagesToInstall.Count) packages..." -ForegroundColor Yellow
    Write-Host "      This may take a while. Logging to individual files in $logFolder`n" -ForegroundColor Gray

    $successful = @()
    $failed = @()
    $total = $packagesToInstall.Count
    $current = 0

    foreach ($pkg in $packagesToInstall) {
        $current++
        $percent = [math]::Round(($current / $total) * 100)

        # Display progress
        Write-Host "      [$current/$total] " -NoNewline -ForegroundColor Cyan
        Write-Host "$pkg " -NoNewline -ForegroundColor White
        Write-Progress -Activity "Installing Chocolatey Packages" -Status "$pkg ($current of $total)" -PercentComplete $percent

        try {
            # Install package with individual log file
            $pkgLogFile = Join-Path $logFolder "$pkg.log"
            $output = choco install $pkg -y --cache=$cacheFolder --log-file=$pkgLogFile 2>&1

            if ($LASTEXITCODE -eq 0) {
                Write-Host "[OK]" -ForegroundColor Green
                $successful += $pkg
            } else {
                Write-Host "[FAILED - see $pkg.log]" -ForegroundColor Red
                $failed += $pkg
            }
        } catch {
            Write-Host "[ERROR: $_]" -ForegroundColor Red
            $failed += $pkg
        }
    }

    Write-Progress -Activity "Installing Chocolatey Packages" -Completed
    Write-Host ""
}

# ============================================================================
# WINDOWS CUSTOMIZATIONS
# ============================================================================

Write-Host "[6/6] Applying Windows customizations..." -ForegroundColor Yellow
try {
    # Restore old Windows 10 File Explorer context menu (removes "Show more options")
    reg.exe add "HKCU\Software\Classes\CLSID\{86ca1aa0-34aa-4e8b-a509-50c905bae2a2}\InprocServer32" /f /ve 2>&1 | Out-Null
    Write-Host "      Windows 10 context menu enabled`n" -ForegroundColor Green
} catch {
    Write-Host "      WARNING: Failed to apply registry customization: $_`n" -ForegroundColor Yellow
}

# ============================================================================
# SUMMARY
# ============================================================================

Write-Host "========================================" -ForegroundColor Cyan
Write-Host "  INSTALLATION SUMMARY" -ForegroundColor Cyan
Write-Host "========================================" -ForegroundColor Cyan

if ($packagesToInstall.Count -gt 0) {
    Write-Host "Successful: " -NoNewline -ForegroundColor Green
    Write-Host "$($successful.Count)/$total" -ForegroundColor White

    if ($failed.Count -gt 0) {
        Write-Host "Failed:     " -NoNewline -ForegroundColor Red
        Write-Host "$($failed.Count)/$total" -ForegroundColor White
        Write-Host "`nFailed packages:" -ForegroundColor Red
        foreach ($pkg in $failed) {
            Write-Host "  - $pkg (check $logFolder\$pkg.log)" -ForegroundColor Red
        }
    }
} else {
    Write-Host "No new packages installed" -ForegroundColor Green
}

if ($skippedPackages.Count -gt 0) {
    Write-Host "Skipped:    " -NoNewline -ForegroundColor Cyan
    Write-Host "$($skippedPackages.Count) (already installed)" -ForegroundColor White
}

Write-Host "`nLogs saved to: $logFolder" -ForegroundColor Gray
Write-Host "`nNOTE: Some packages may require a system restart to function properly." -ForegroundColor Yellow
Write-Host "========================================`n" -ForegroundColor Cyan

# Exit with error code if any packages failed
if ($failed.Count -gt 0) {
    exit 1
} else {
    exit 0
}