Skip to content

Instantly share code, notes, and snippets.

@ciekawy
Created March 2, 2026 14:29
Show Gist options
  • Select an option

  • Save ciekawy/f0a8b83c7cc838fc139b27a5a5845f0a to your computer and use it in GitHub Desktop.

Select an option

Save ciekawy/f0a8b83c7cc838fc139b27a5a5845f0a to your computer and use it in GitHub Desktop.
WEB-9: Unified Windows Server 2022 init script (network + packages + SSH + .NET)
# Windows Server 2022 Unified Init Script - WEB-9
# Run in Administrator PowerShell after fresh Windows install
#
# Usage: irm <tinyurl> | iex
#
# This script handles the complete post-installation setup:
# 1. VirtIO network driver (if CD drive mounted)
# 2. DNS configuration
# 3. Chocolatey + packages (.NET SDK, Git, PowerShell 7)
# 4. OpenSSH Server with key-based authentication
# 5. Test .NET project creation
#
# Requires: Administrator privileges, internet access (or VirtIO ISO for network)
param(
[string]$SshPublicKey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIO9VR+9HrxMs+2NxN2h8Td6rCDP8eupti1BtqFK1pSdX coder@myfirst"
)
$ErrorActionPreference = "Continue"
Set-ExecutionPolicy Bypass -Scope Process -Force
function Write-Step {
param([string]$Step, [string]$Message)
Write-Host "`n[$Step] $Message" -ForegroundColor Cyan
}
function Write-Ok { param([string]$Message) Write-Host " OK: $Message" -ForegroundColor Green }
function Write-Warn { param([string]$Message) Write-Host " WARN: $Message" -ForegroundColor Yellow }
function Write-Err { param([string]$Message) Write-Host " ERROR: $Message" -ForegroundColor Red }
Write-Host "=== Windows Server 2022 Unified Init ===" -ForegroundColor Green
Write-Host "Starting at $(Get-Date -Format 'yyyy-MM-dd HH:mm:ss')" -ForegroundColor Gray
# --- Step 1: Network ---
Write-Step "1/6" "Checking network..."
$adapter = Get-NetAdapter -ErrorAction SilentlyContinue
if (-not $adapter) {
Write-Warn "No network adapter found. Looking for VirtIO driver ISO..."
$cdDrives = Get-Volume | Where-Object { $_.DriveType -eq 'CD-ROM' -and $_.DriveLetter }
foreach ($drive in $cdDrives) {
$letter = $drive.DriveLetter
$driverPath = "${letter}:\NetKVM\2k22\amd64"
if (Test-Path $driverPath) {
Write-Host " Installing VirtIO network driver from ${letter}:\" -ForegroundColor Yellow
pnputil /add-driver "${driverPath}\*.inf" /install
Start-Sleep -Seconds 5
break
}
}
$adapter = Get-NetAdapter -ErrorAction SilentlyContinue
if (-not $adapter) {
Write-Err "No network adapter found even after VirtIO install!"
Write-Host " Attach VirtIO ISO from Linux: hcloud server attach-iso <vm> 116716" -ForegroundColor Yellow
Write-Host " Then re-run this script." -ForegroundColor Yellow
exit 1
}
}
Write-Ok "Network adapter: $($adapter.Name) ($($adapter.Status))"
# Configure DNS
$adapterAlias = $adapter.Name
Set-DnsClientServerAddress -InterfaceAlias $adapterAlias -ServerAddresses ("8.8.8.8","8.8.4.4")
Write-Ok "DNS set to 8.8.8.8, 8.8.4.4"
# Test connectivity
$ping = Test-NetConnection 8.8.8.8 -WarningAction SilentlyContinue
if ($ping.TcpTestSucceeded -or $ping.PingSucceeded) {
Write-Ok "Internet connectivity confirmed"
} else {
Write-Warn "Ping failed but continuing (ICMP may be blocked)"
}
# --- Step 2: Chocolatey ---
Write-Step "2/6" "Installing Chocolatey..."
if (Get-Command choco -ErrorAction SilentlyContinue) {
Write-Ok "Chocolatey already installed"
} else {
[System.Net.ServicePointManager]::SecurityProtocol = 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")
Write-Ok "Chocolatey installed"
}
# --- Step 3: Packages ---
Write-Step "3/6" "Installing packages (this takes ~10 minutes)..."
choco install -y powershell-core dotnet-8.0-sdk git 2>&1 | Out-Null
$env:PATH = [System.Environment]::GetEnvironmentVariable("Path","Machine") + ";" + [System.Environment]::GetEnvironmentVariable("Path","User")
# Verify installs using full paths
$dotnetPath = "C:\Program Files\dotnet\dotnet.exe"
$gitPath = "C:\Program Files\Git\cmd\git.exe"
if (Test-Path $dotnetPath) { Write-Ok ".NET SDK: $(& $dotnetPath --version)" }
else { Write-Err ".NET SDK not found at $dotnetPath" }
if (Test-Path $gitPath) { Write-Ok "Git: $(& $gitPath --version)" }
else { Write-Err "Git not found at $gitPath" }
$pwshPath = "C:\Program Files\PowerShell\7\pwsh.exe"
if (Test-Path $pwshPath) { Write-Ok "PowerShell 7 installed" }
else { Write-Warn "PowerShell 7 not found (non-blocking)" }
# --- Step 4: OpenSSH ---
Write-Step "4/6" "Configuring SSH..."
# Use Windows built-in OpenSSH (more reliable than Chocolatey version)
$sshCapability = Get-WindowsCapability -Online | Where-Object Name -like 'OpenSSH.Server*'
if ($sshCapability.State -ne 'Installed') {
Add-WindowsCapability -Online -Name OpenSSH.Server~~~~0.0.1.0 | Out-Null
Write-Ok "OpenSSH Server installed via Windows Capability"
} else {
Write-Ok "OpenSSH Server already installed"
}
# Write minimal sshd_config
$sshdConfig = @"
PubkeyAuthentication yes
PasswordAuthentication no
Match Group administrators
AuthorizedKeysFile C:/ProgramData/ssh/administrators_authorized_keys
"@
$sshdConfig | Set-Content -Path "C:\ProgramData\ssh\sshd_config" -Force
Write-Ok "sshd_config written"
# Start service
Start-Service sshd -ErrorAction SilentlyContinue
Set-Service -Name sshd -StartupType Automatic -ErrorAction SilentlyContinue
$sshService = Get-Service sshd -ErrorAction SilentlyContinue
if ($sshService -and $sshService.Status -eq 'Running') {
Write-Ok "SSH service running"
} else {
Write-Err "SSH service failed to start! Check: Get-EventLog -LogName Application -Source sshd -Newest 5"
}
# Firewall rule
New-NetFirewallRule -Name "OpenSSH-Server-In-TCP" -DisplayName "OpenSSH Server" `
-Enabled True -Direction Inbound -Protocol TCP -Action Allow -LocalPort 22 `
-ErrorAction SilentlyContinue | Out-Null
Write-Ok "Firewall rule configured"
# --- Step 5: SSH Key ---
Write-Step "5/6" "Adding SSH public key..."
$authorizedKeysFile = "C:\ProgramData\ssh\administrators_authorized_keys"
New-Item -Path $authorizedKeysFile -ItemType File -Force -Value $SshPublicKey | Out-Null
icacls.exe $authorizedKeysFile /inheritance:r | Out-Null
icacls.exe $authorizedKeysFile /grant "SYSTEM:(F)" | Out-Null
icacls.exe $authorizedKeysFile /grant "BUILTIN\Administrators:(F)" | Out-Null
Restart-Service sshd -ErrorAction SilentlyContinue
Write-Ok "SSH key added and service restarted"
# --- Step 6: Test Project ---
Write-Step "6/6" "Creating test .NET project..."
if (Test-Path $dotnetPath) {
New-Item -ItemType Directory -Path C:\Projects -Force | Out-Null
Set-Location C:\Projects
if (-not (Test-Path "C:\Projects\HelloWindows")) {
& $dotnetPath new console -n HelloWindows -o HelloWindows 2>&1 | Out-Null
}
Set-Location HelloWindows
$buildResult = & $dotnetPath build 2>&1
if ($LASTEXITCODE -eq 0) {
Write-Ok "HelloWindows project built successfully"
} else {
Write-Err "Build failed: $buildResult"
}
} else {
Write-Warn "Skipping test project (.NET SDK not available)"
}
# --- Summary ---
Write-Host "`n=== Setup Complete ===" -ForegroundColor Green
Write-Host "Finished at $(Get-Date -Format 'yyyy-MM-dd HH:mm:ss')" -ForegroundColor Gray
$ip = (Get-NetIPAddress -AddressFamily IPv4 | Where-Object { $_.InterfaceAlias -notlike "*Loopback*" } | Select-Object -First 1).IPAddress
Write-Host "`nConnection Info:" -ForegroundColor Cyan
Write-Host " SSH: ssh -i ~/.ssh/id_windows_poc Administrator@$ip" -ForegroundColor White
Write-Host " .NET build: ssh ... `"cd C:\Projects\HelloWindows & \`"C:\Program Files\dotnet\dotnet.exe\`" build`"" -ForegroundColor White
Write-Host "`nInstalled:" -ForegroundColor Cyan
if (Test-Path $dotnetPath) { Write-Host " .NET SDK $(& $dotnetPath --version)" }
if (Test-Path $gitPath) { Write-Host " Git $(& $gitPath --version)" }
if (Test-Path $pwshPath) { Write-Host " PowerShell 7" }
Write-Host " OpenSSH Server ($(Get-Service sshd -ErrorAction SilentlyContinue | Select-Object -ExpandProperty Status))"
Write-Host "`n✅ Ready for remote development!" -ForegroundColor Green
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment