-
Notifications
You must be signed in to change notification settings - Fork 21
Expand file tree
/
Copy pathinstall.ps1
More file actions
130 lines (118 loc) · 4.94 KB
/
install.ps1
File metadata and controls
130 lines (118 loc) · 4.94 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
#Requires -Version 5.1
$ErrorActionPreference = "Stop"
# Require admin: choco installs system-wide, and some winget packages also need elevation.
$principal = [Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()
if (-not $principal.IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)) {
Write-Host "This script must be run from an elevated PowerShell (Run as Administrator)." -ForegroundColor Red
Read-Host "Press Enter to exit"
exit 1
}
Write-Host "Bootstrapping dotfiles via chezmoi..." -ForegroundColor Green
# Pick a package manager: prefer winget (preinstalled on Windows 10/11), fall back to
# Chocolatey (needed on Windows Server 2022 and other systems without winget).
function Install-Chocolatey {
Write-Host "Installing Chocolatey..." -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://community.chocolatey.org/install.ps1'))
$env:PATH = [System.Environment]::GetEnvironmentVariable("PATH", "Machine") + ";" +
[System.Environment]::GetEnvironmentVariable("PATH", "User")
}
if (Get-Command winget -ErrorAction SilentlyContinue) {
$pm = "winget"
} else {
if (-not (Get-Command choco -ErrorAction SilentlyContinue)) { Install-Chocolatey }
$pm = "choco"
}
# True if any installed app's DisplayName matches the pattern (covers both per-user
# and machine-wide MSI/EXE installers — needed because choco doesn't install MSIX).
function Test-InstalledApp {
param([string]$DisplayNamePattern)
$keys = @(
'HKLM:\Software\Microsoft\Windows\CurrentVersion\Uninstall\*',
'HKLM:\Software\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall\*',
'HKCU:\Software\Microsoft\Windows\CurrentVersion\Uninstall\*'
)
[bool](Get-ItemProperty $keys -ErrorAction SilentlyContinue |
Where-Object { $_.DisplayName -like $DisplayNamePattern })
}
Write-Host "Using package manager: $pm" -ForegroundColor Green
# Install required tools if missing.
# 1Password (GUI) provides the SSH agent used to clone the repo.
$tools = @(
@{
Name = "1Password"
Winget = "AgileBits.1Password"
Choco = "1password"
Check = {
[bool](Get-AppxPackage -Name 'Agilebits.1Password' -ErrorAction SilentlyContinue) -or
(Test-InstalledApp '1Password*')
}
}
@{
Name = "1Password CLI"
Winget = "AgileBits.1Password.CLI"
Choco = "1password-cli"
Check = { [bool](Get-Command op -ErrorAction SilentlyContinue) }
}
@{
Name = "git"
Winget = "Git.Git"
Choco = "git"
Check = { [bool](Get-Command git -ErrorAction SilentlyContinue) }
}
@{
Name = "chezmoi"
Winget = "twpayne.chezmoi"
Choco = "chezmoi"
Check = { [bool](Get-Command chezmoi -ErrorAction SilentlyContinue) }
}
@{
Name = "PowerShell"
Winget = "Microsoft.PowerShell"
Choco = "powershell-core"
Check = { [bool](Get-Command pwsh -ErrorAction SilentlyContinue) }
}
@{
Name = "gsudo"
Winget = "gerardog.gsudo"
Choco = "gsudo"
Check = { [bool](Get-Command gsudo -ErrorAction SilentlyContinue) }
}
)
$opJustInstalled = $false
foreach ($tool in $tools) {
if (-not (& $tool.Check)) {
Write-Host "Installing $($tool.Name)..." -ForegroundColor Yellow
if ($pm -eq "winget") {
winget install --exact --silent `
--accept-package-agreements --accept-source-agreements `
--source winget $tool.Winget
} else {
choco install -y $tool.Choco
}
if ($tool.Name -eq "1Password") { $opJustInstalled = $true }
}
}
# A fresh 1Password install needs sign-in + SSH agent toggle before the git clone will succeed.
if ($opJustInstalled) {
Write-Host ""
Write-Host "Open 1Password, sign in, then enable Settings -> Developer -> 'Use the SSH agent'." -ForegroundColor Yellow
Write-Host "Re-run this script once that's done." -ForegroundColor Yellow
Read-Host "Press Enter to exit"
exit 0
}
# Refresh PATH so newly-installed binaries are visible in this session.
$env:PATH = [System.Environment]::GetEnvironmentVariable("PATH", "Machine") + ";" +
[System.Environment]::GetEnvironmentVariable("PATH", "User")
Write-Host "Running chezmoi init..." -ForegroundColor Green
# Use Windows OpenSSH so the 1Password SSH agent (a named pipe) is reachable.
# Git for Windows' bundled MSYS ssh can't talk to Windows named pipes, and
# chezmoi's built-in go-git can't either — so force system git for the clone.
$winSsh = "$env:WINDIR\System32\OpenSSH\ssh.exe"
if (Test-Path $winSsh) {
$env:GIT_SSH_COMMAND = "`"$winSsh`""
}
chezmoi init --apply --ssh --use-builtin-git=false claytron