-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathremote-development-setup.ps1
More file actions
410 lines (330 loc) · 13 KB
/
Copy pathremote-development-setup.ps1
File metadata and controls
410 lines (330 loc) · 13 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
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
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
# Remote Development Setup Script for Windows 11
# Configures tools for remote development with Ubuntu servers
# Run as Administrator in PowerShell 7+
#Requires -Version 7.0
# Note: admin privileges are enforced at runtime via Assert-Administrator in Main()
# rather than via #Requires, so this script can be dot-sourced for behavioral testing
# without a forced elevation.
[CmdletBinding()]
param(
[switch]$SkipSSH,
[switch]$SkipVSCode,
[switch]$SkipPortForwarding
)
# Shared logging via CommonFunctions (Write-InfoMessage / Success / WarningMessage / ErrorMessage / Section)
Import-Module (Join-Path -Path $PSScriptRoot -ChildPath '..\lib\CommonFunctions.psm1') -Force
# Setup SSH client and keys
function Initialize-SSHClient {
[CmdletBinding()]
param([bool]$Skip = $SkipSSH.IsPresent)
if ($Skip) {
Write-InfoMessage "Skipping SSH setup"
return
}
Write-InfoMessage "Setting up SSH client for remote development..."
# Enable OpenSSH Client (should be available on Windows 11)
$sshClient = Get-WindowsCapability -Online | Where-Object Name -like 'OpenSSH.Client*'
if ($sshClient.State -ne "Installed") {
Write-InfoMessage "Installing OpenSSH Client..."
Add-WindowsCapability -Online -Name OpenSSH.Client~~~~0.0.1.0
}
# Create SSH directory if it doesn't exist
$sshDir = "$env:USERPROFILE\.ssh"
if (!(Test-Path $sshDir)) {
New-Item -ItemType Directory -Path $sshDir -Force | Out-Null
# Set proper permissions
icacls $sshDir /inheritance:r /grant:r "$env:USERNAME:(OI)(CI)F"
}
# Check if SSH key exists
$sshKeyPath = "$sshDir\id_ed25519"
if (!(Test-Path $sshKeyPath)) {
Write-InfoMessage "SSH key not found. Generating new ED25519 key..."
$email = Read-Host "Enter your email for SSH key"
ssh-keygen -t ed25519 -C $email -f $sshKeyPath -N `"`"
Write-Success "SSH key generated at: $sshKeyPath"
Write-InfoMessage "Public key content:"
Get-Content "$sshKeyPath.pub"
Write-WarningMessage "Copy the public key above to your Ubuntu server's ~/.ssh/authorized_keys"
}
else {
Write-Success "SSH key already exists at: $sshKeyPath"
}
# Start SSH agent and add key
Start-Service ssh-agent
Set-Service ssh-agent -StartupType Automatic
ssh-add $sshKeyPath
Write-Success "SSH client configured"
}
# Setup VS Code for remote development
function Initialize-VSCodeRemote {
[CmdletBinding()]
param([bool]$Skip = $SkipVSCode.IsPresent)
if ($Skip) {
Write-InfoMessage "Skipping VS Code remote setup"
return
}
Write-InfoMessage "Setting up VS Code for remote development..."
# Check if VS Code is installed
if (!(Get-Command code -ErrorAction SilentlyContinue)) {
Write-WarningMessage "VS Code not found. Installing via Winget..."
winget install --id Microsoft.VisualStudioCode --silent
# Refresh PATH
$env:Path = [System.Environment]::GetEnvironmentVariable("Path", "Machine") + ";" + [System.Environment]::GetEnvironmentVariable("Path", "User")
}
# Install essential remote development extensions
$RemoteExtensions = @(
'ms-vscode-remote.remote-ssh',
'ms-vscode-remote.remote-ssh-edit',
'ms-vscode-remote.remote-containers',
'ms-vscode-remote.vscode-remote-extensionpack',
'ms-vscode.remote-explorer',
'ms-vscode.remote-server'
)
foreach ($Extension in $RemoteExtensions) {
try {
Write-InfoMessage "Installing VS Code extension: $Extension"
code --install-extension $Extension --force
Write-Success "$Extension installed"
}
catch {
Write-WarningMessage "Failed to install $Extension"
}
}
# Create VS Code SSH config template
$sshConfigPath = "$env:USERPROFILE\.ssh\config"
if (!(Test-Path $sshConfigPath)) {
$sshConfigContent = @"
# SSH Config for Remote Development
# Add your server configurations here
# Example Ubuntu Server Configuration
# Host ubuntu-server
# HostName your-server-ip-or-hostname
# User your-username
# Port 22
# IdentityFile ~/.ssh/id_ed25519
# ForwardAgent yes
# ServerAliveInterval 60
# ServerAliveCountMax 3
# Example Ubuntu Desktop Configuration
# Host ubuntu-desktop
# HostName your-desktop-ip-or-hostname
# User your-username
# Port 22
# IdentityFile ~/.ssh/id_ed25519
# ForwardAgent yes
# ServerAliveInterval 60
# ServerAliveCountMax 3
"@
Set-Content -Path $sshConfigPath -Value $sshConfigContent -Encoding UTF8
Write-Success "SSH config template created at: $sshConfigPath"
Write-InfoMessage "Edit the SSH config file to add your server details"
}
Write-Success "VS Code remote development configured"
}
# Setup port forwarding utilities
function Initialize-PortForwarding {
[CmdletBinding()]
param([bool]$Skip = $SkipPortForwarding.IsPresent)
if ($Skip) {
Write-InfoMessage "Skipping port forwarding setup"
return
}
Write-InfoMessage "Setting up port forwarding utilities..."
# Create port forwarding helper scripts
$scriptsDir = "$env:USERPROFILE\Development\Scripts"
New-Item -ItemType Directory -Path $scriptsDir -Force | Out-Null
# SSH tunnel script
$tunnelScript = @'
# SSH Tunnel Helper Script
# Usage: .\ssh-tunnel.ps1 -Server "server-name" -LocalPort 3000 -RemotePort 3000
param(
[Parameter(Mandatory=$true)]
[string]$Server,
[Parameter(Mandatory=$true)]
[int]$LocalPort,
[Parameter(Mandatory=$true)]
[int]$RemotePort,
[string]$RemoteHost = "localhost"
)
Write-Host "Creating SSH tunnel: localhost:$LocalPort -> $Server:$RemoteHost:$RemotePort" -ForegroundColor Green
Write-Host "Press Ctrl+C to stop the tunnel" -ForegroundColor Yellow
ssh -L ${LocalPort}:${RemoteHost}:${RemotePort} $Server -N
'@
Set-Content -Path "$scriptsDir\ssh-tunnel.ps1" -Value $tunnelScript -Encoding UTF8
# Multiple tunnels script
$multiTunnelScript = @'
# Multiple SSH Tunnels Helper Script
# Usage: .\ssh-multi-tunnel.ps1 -Server "server-name"
param(
[Parameter(Mandatory=$true)]
[string]$Server
)
Write-Host "Creating multiple SSH tunnels to $Server" -ForegroundColor Green
Write-Host "Common development ports:" -ForegroundColor Yellow
Write-Host " 3000 -> React/Node.js dev server" -ForegroundColor Cyan
Write-Host " 8000 -> Python dev server" -ForegroundColor Cyan
Write-Host " 8080 -> Alternative HTTP" -ForegroundColor Cyan
Write-Host " 5432 -> PostgreSQL" -ForegroundColor Cyan
Write-Host " 3306 -> MySQL" -ForegroundColor Cyan
Write-Host " 6379 -> Redis" -ForegroundColor Cyan
Write-Host " 9000 -> Portainer" -ForegroundColor Cyan
Write-Host ""
Write-Host "Press Ctrl+C to stop all tunnels" -ForegroundColor Yellow
# Start multiple tunnels in background
$jobs = @()
$ports = @(3000, 8000, 8080, 5432, 3306, 6379, 9000)
foreach ($port in $ports) {
$job = Start-Job -ScriptBlock {
param($server, $port)
ssh -L ${port}:localhost:${port} $server -N
} -ArgumentList $Server, $port
$jobs += $job
Write-Host "Started tunnel for port $port (Job ID: $($job.Id))" -ForegroundColor Green
}
# Wait for user to stop
try {
Write-Host "All tunnels started. Press Ctrl+C to stop..." -ForegroundColor Yellow
while ($true) {
Start-Sleep -Seconds 1
}
}
finally {
Write-Host "Stopping all tunnels..." -ForegroundColor Yellow
$jobs | Stop-Job
$jobs | Remove-Job
Write-Host "All tunnels stopped." -ForegroundColor Green
}
'@
Set-Content -Path "$scriptsDir\ssh-multi-tunnel.ps1" -Value $multiTunnelScript -Encoding UTF8
Write-Success "Port forwarding utilities created in: $scriptsDir"
}
# Install additional remote development tools
function Install-RemoteDevTool {
Write-InfoMessage "Installing additional remote development tools..."
# Install useful tools via Chocolatey if available
if (Get-Command choco -ErrorAction SilentlyContinue) {
$tools = @(
'putty',
'winscp',
'mremoteng',
'terminus',
'mobaxterm'
)
foreach ($tool in $tools) {
try {
Write-InfoMessage "Installing $tool..."
choco install $tool -y --no-progress
Write-Success "$tool installed"
}
catch {
Write-WarningMessage "Failed to install $tool"
}
}
}
# Install Windows Terminal if not present
if (!(Get-Command wt -ErrorAction SilentlyContinue)) {
Write-InfoMessage "Installing Windows Terminal..."
winget install --id Microsoft.WindowsTerminal --silent
}
Write-Success "Remote development tools installed"
}
# Configure Windows Terminal for remote development
function Initialize-WindowsTerminal {
Write-InfoMessage "Configuring Windows Terminal for remote development..."
$terminalSettingsPath = "$env:LOCALAPPDATA\Packages\Microsoft.WindowsTerminal_8wekyb3d8bbwe\LocalState\settings.json"
if (Test-Path $terminalSettingsPath) {
Write-InfoMessage "Windows Terminal settings found. Consider adding SSH profiles manually."
Write-InfoMessage "Settings location: $terminalSettingsPath"
# Create example SSH profile
$exampleProfile = @"
Example SSH profile for Windows Terminal settings.json:
{
"guid": "{new-guid-here}",
"name": "Ubuntu Server",
"commandline": "ssh ubuntu-server",
"icon": "ms-appx:///ProfileIcons/{9acb9455-ca41-5af7-950f-6bca1bc9722f}.png",
"colorScheme": "Ubuntu",
"startingDirectory": "~"
}
Add this to the "profiles" -> "list" array in your Windows Terminal settings.
"@
Write-InfoMessage $exampleProfile
}
else {
Write-WarningMessage "Windows Terminal settings not found. Install Windows Terminal first."
}
Write-Success "Windows Terminal configuration guidance provided"
}
# Create development workspace structure
function Initialize-DevelopmentWorkspace {
Write-InfoMessage "Setting up development workspace structure..."
$workspaceDir = "$env:USERPROFILE\Development\Remote"
$directories = @(
"$workspaceDir\Projects",
"$workspaceDir\Scripts",
"$workspaceDir\Configs",
"$workspaceDir\Logs"
)
foreach ($dir in $directories) {
New-Item -ItemType Directory -Path $dir -Force | Out-Null
}
# Create remote development guide
$guideContent = @"
# Remote Development Workspace
This directory contains tools and configurations for remote development.
## Directory Structure
- **Projects/**: Local copies of remote projects
- **Scripts/**: Helper scripts for remote development
- **Configs/**: SSH configs and other configuration files
- **Logs/**: Connection logs and debugging information
## Quick Start
1. Configure SSH keys and server connections
2. Use VS Code Remote-SSH extension to connect to servers
3. Use port forwarding scripts for accessing remote services
4. Keep local copies of important projects in Projects/
## Useful Commands
```powershell
# Connect to server via SSH
ssh server-name
# Create SSH tunnel for web development
.\Scripts\ssh-tunnel.ps1 -Server "ubuntu-server" -LocalPort 3000 -RemotePort 3000
# Create multiple tunnels for development
.\Scripts\ssh-multi-tunnel.ps1 -Server "ubuntu-server"
# Open VS Code connected to remote server
code --remote ssh-remote+server-name /path/to/project
```
## Tips
- Use SSH config file (~/.ssh/config) to define server shortcuts
- Set up SSH key forwarding for Git operations on remote servers
- Use VS Code Remote-Containers for consistent development environments
- Keep sensitive data on remote servers, not local machine
"@
Set-Content -Path "$workspaceDir\README.md" -Value $guideContent -Encoding UTF8
Write-Success "Development workspace created at: $workspaceDir"
}
# Main execution function
function Main {
Assert-Administrator
Write-Section "Starting Remote Development Setup"
Initialize-SSHClient
Initialize-VSCodeRemote
Initialize-PortForwarding
Install-RemoteDevTool
Initialize-WindowsTerminal
Initialize-DevelopmentWorkspace
Write-Success "Remote development setup completed successfully!"
Write-InfoMessage "[*] Next steps:"
Write-InfoMessage " 1. Copy your SSH public key to remote servers"
Write-InfoMessage " 2. Edit ~/.ssh/config to add your server configurations"
Write-InfoMessage " 3. Test SSH connection: ssh server-name"
Write-InfoMessage " 4. Open VS Code and use Remote-SSH extension"
Write-InfoMessage " 5. Use port forwarding scripts for accessing remote services"
Write-InfoMessage "[*] Development workspace: $env:USERPROFILE\Development\Remote"
Write-InfoMessage "[*] SSH config: $env:USERPROFILE\.ssh\config"
Write-InfoMessage "[*] Helper scripts: $env:USERPROFILE\Development\Scripts"
}
# Run Main when invoked as a script. When dot-sourced for testing, skip auto-run
# so test files can load function definitions into scope and exercise them with mocks.
if ($MyInvocation.InvocationName -ne '.') {
Main
}