#!/usr/bin/env pwsh <# .SYNOPSIS Installer for termscp on Windows. .DESCRIPTION Downloads the latest (or a specified) termscp release for Windows from GitHub, extracts the binary into an install directory and adds it to the current user's PATH. .PARAMETER Version The termscp version to install (defaults to the latest released version). .PARAMETER InstallDir The directory the termscp.exe binary is installed into. Defaults to "$env:LOCALAPPDATA\Programs\termscp". .PARAMETER Force Skip the confirmation prompt during installation. Alias: -Yes. .EXAMPLE irm https://termscp.rs/install.ps1 | iex .EXAMPLE .\install.ps1 -Version 1.0.0 -Force #> [CmdletBinding()] param( [string]$Version = "1.0.0", [string]$InstallDir = "$env:LOCALAPPDATA\Programs\termscp", [Alias("Yes")] [switch]$Force ) $ErrorActionPreference = "Stop" $GithubUrl = "https://github.com/veeso/termscp/releases/download/v$Version" # -- output helpers ---------------------------------------------------------- function Write-Info { param([string]$Message) Write-Host "> " -ForegroundColor DarkGray -NoNewline Write-Host $Message } function Write-Warn { param([string]$Message) Write-Host "! $Message" -ForegroundColor Yellow } function Write-Err { param([string]$Message) Write-Host "x $Message" -ForegroundColor Red } function Write-Completed { param([string]$Message) Write-Host "✓ " -ForegroundColor Green -NoNewline Write-Host $Message } function Confirm-Action { param([string]$Message) if ($Force) { return } $answer = Read-Host "? $Message [y/N]" if ($answer -ne "y" -and $answer -ne "yes") { Write-Err 'Aborting (please answer "yes" to continue)' exit 1 } } # -- platform detection ------------------------------------------------------ # Currently supporting: # - x86_64 (AMD64) # - aarch64 (ARM64) function Get-TermscpTarget { $arch = $env:PROCESSOR_ARCHITECTURE if ($env:PROCESSOR_ARCHITEW6432) { $arch = $env:PROCESSOR_ARCHITEW6432 } switch ($arch.ToUpper()) { "AMD64" { return "x86_64-pc-windows-msvc" } "ARM64" { return "aarch64-pc-windows-msvc" } default { Write-Err "Unsupported architecture: $arch" Write-Info "Only x86_64 (AMD64) and aarch64 (ARM64) are supported by this installer." Write-Info "Alternatively you can install termscp with Cargo : cargo install termscp --locked" exit 1 } } } # -- installation ------------------------------------------------------------ function Install-Termscp { $target = Get-TermscpTarget $asset = "termscp-v$Version-$target.zip" $url = "$GithubUrl/$asset" Write-Host "" Write-Host " Termscp configuration" Write-Info "Version: $Version" Write-Info "Target: $target" Write-Info "Install dir: $InstallDir" Write-Host "" Confirm-Action "Install termscp $Version?" $tmpDir = Join-Path ([System.IO.Path]::GetTempPath()) "termscp-$([System.IO.Path]::GetRandomFileName())" New-Item -ItemType Directory -Force -Path $tmpDir | Out-Null try { $archive = Join-Path $tmpDir $asset Write-Info "Downloading termscp from $url …" try { Invoke-WebRequest -Uri $url -OutFile $archive -UseBasicParsing } catch { Write-Err "Failed to download termscp: $($_.Exception.Message)" Write-Warn "If you believe this is a bug, please report an issue at " exit 1 } Write-Info "Extracting archive …" Expand-Archive -Path $archive -DestinationPath $tmpDir -Force if (-not (Test-Path $InstallDir)) { New-Item -ItemType Directory -Force -Path $InstallDir | Out-Null } $binary = Join-Path $tmpDir "termscp.exe" if (-not (Test-Path $binary)) { Write-Err "termscp.exe not found in the downloaded archive" exit 1 } Write-Info "Installing termscp to $InstallDir …" Copy-Item -Path $binary -Destination (Join-Path $InstallDir "termscp.exe") -Force Add-ToUserPath -Directory $InstallDir } finally { Remove-Item -Path $tmpDir -Recurse -Force -ErrorAction SilentlyContinue } } function Add-ToUserPath { param([string]$Directory) $userPath = [Environment]::GetEnvironmentVariable("Path", "User") $entries = @() if ($userPath) { $entries = $userPath.Split(";") | Where-Object { $_ -ne "" } } if ($entries -contains $Directory) { return } Write-Info "Adding $Directory to your user PATH …" $newPath = (@($entries) + $Directory) -join ";" [Environment]::SetEnvironmentVariable("Path", $newPath, "User") # make termscp available in the current session too $env:Path = "$env:Path;$Directory" Write-Warn "Restart your terminal for the PATH change to take effect in new sessions." } # -- main -------------------------------------------------------------------- Install-Termscp Write-Completed "Congratulations! Termscp has successfully been installed on your system!" Write-Info "If you're a new user, you might be interested in reading the user manual " Write-Info "Remember that if you encounter any issue, you can report them on Github " Write-Info "Feel free to open an issue also if you have an idea which could improve the project" Write-Info "I hope you'll enjoy using termscp :D" exit 0