<# .SYNOPSIS Install a curated list of VS Code extensions on Windows. .DESCRIPTION Installs the bundled extension list using the VS Code 'code' CLI. Sets the current process's ExecutionPolicy to RemoteSigned (no machine-wide change) so the script can run on a default Windows configuration. .PARAMETER ProfileName Optional VS Code profile name. If supplied, extensions are installed into that profile. VS Code creates the profile if it doesn't already exist. Quote names that contain spaces. .EXAMPLE PS> .\install.ps1 .EXAMPLE PS> .\install.ps1 -ProfileName "WorkSetup" .NOTES If PowerShell refuses to run the file, invoke it as: powershell -ExecutionPolicy Bypass -File .\install.ps1 #> [CmdletBinding()] param( [Parameter(Mandatory = $false, Position = 0)] [string]$ProfileName = "" ) # Loosen execution policy for THIS process only (no persisted change). try { $current = Get-ExecutionPolicy -Scope Process -ErrorAction Stop if ($current -in @('Restricted', 'AllSigned', 'Undefined')) { Set-ExecutionPolicy -Scope Process -ExecutionPolicy RemoteSigned -Force -ErrorAction Stop } } catch { Write-Verbose ("Could not adjust process execution policy: {0}" -f $_.Exception.Message) } $ErrorActionPreference = 'Stop' $Extensions = @( 'docker.docker', 'github.github-vscode-theme', 'GitHub.vscode-github-actions', 'ms-azuretools.vscode-containers', 'ms-vscode-remote.vscode-remote-extensionpack', 'pkief.material-icon-theme' ) $codeCmd = Get-Command code -ErrorAction SilentlyContinue if (-not $codeCmd) { Write-Host "" Write-Host "Error: the 'code' command is not on your PATH." -ForegroundColor Red Write-Host " Install VS Code from https://code.visualstudio.com/ and make sure" -ForegroundColor Yellow Write-Host ' "Add to PATH" was checked during setup, then re-open your terminal.' -ForegroundColor Yellow exit 1 } $extraArgs = @() if (-not [string]::IsNullOrWhiteSpace($ProfileName)) { $extraArgs += @('--profile', $ProfileName) } $header = "Installing $($Extensions.Count) extension(s)" if ($ProfileName) { $header += " into profile '$ProfileName'" } Write-Host ("{0}..." -f $header) -ForegroundColor Cyan Write-Host "" $installed = 0 $failed = 0 $failedList = @() foreach ($ext in $Extensions) { Write-Host -NoNewline (" -> {0,-55} " -f $ext) try { $output = & code @extraArgs --install-extension $ext --force 2>&1 if ($LASTEXITCODE -eq 0) { Write-Host "ok" -ForegroundColor Green $installed++ } else { Write-Host "FAILED" -ForegroundColor Red $failed++ $failedList += $ext $output | ForEach-Object { Write-Host " $_" -ForegroundColor DarkRed } } } catch { Write-Host "FAILED" -ForegroundColor Red $failed++ $failedList += $ext Write-Host (" {0}" -f $_.Exception.Message) -ForegroundColor DarkRed } } Write-Host "" Write-Host ("Done. Installed: {0}, Failed: {1}" -f $installed, $failed) if ($failed -gt 0) { Write-Host "Failed extensions:" -ForegroundColor Red foreach ($f in $failedList) { Write-Host (" - {0}" -f $f) -ForegroundColor Red } exit 1 }