cd ../

user@dainky:~/tools/windows-linux-scp$

windows-linux-scp.ps1

PowerShell Bash SCP Active

Overview

This PowerShell script automates file transfers between Windows and Linux systems using the SCP (Secure Copy Protocol). It eliminates the need for manual file copying and provides a reliable, secure way to move files across different operating systems.

The script leverages OpenSSH's scp command (built into Windows 10/11) to transfer files over SSH, ensuring encrypted and authenticated connections. Perfect for developers, sysadmins, and anyone managing cross-platform environments.

Features

  • Secure file transfer using SSH/SCP protocol
  • Cross-platform compatibility (Windows ↔ Linux)
  • Automated authentication with SSH keys
  • Support for both single files and directories
  • Error handling and connection verification
  • Progress indicators for large file transfers
  • Easy configuration through variables

Script Code

windows-linux-scp.ps1
# push.ps1 (v2) — upload files/folders from Windows → Linux via SCP
# - Supports directories 
# - Multiple sources in one run
# - Override Dest/Host/User/Port at runtime
# Example:
#   .\push.ps1 -Source "C:\work\site\dist","C:\pics\logo.png" -Dest "/var/www/html/assets"
#I assume you know how to use this if you're even looking at this, and have allowed scripts on your powershell.

param(
  [Parameter(Mandatory=$true)]
  [string[]]$Source,

  [string]$Dest = "/home/dainky/uploads", #Change to your destination, make sure it exists
  [string]$HostName = "10.0.6.31", #Change to your IP
  [string]$UserName = "dainky",	   #Change to your username 
  [int]$Port = 22,		   #Change to your port if needed

  
  [string]$IdentityFile
)

$ErrorActionPreference = 'Stop'

# Path to Windows OpenSSH scp
$scpExe = "$env:SystemRoot\System32\OpenSSH\scp.exe"
if (-not (Test-Path $scpExe)) {
  throw "OpenSSH client not found. Install 'OpenSSH Client' in Windows Optional Features."
}

# Build the remote target (user@host:"/remote/path")
$remote = ("{0}@{1}:`"{2}`"" -f $UserName, $HostName, $Dest)

foreach ($s in $Source) {
  # Resolve to absolute Windows path; supports quotes/spaces
  $resolved = (Resolve-Path $s).Path
  $isDir = (Get-Item $resolved).PSIsContainer

  $args = @()
  if ($isDir) { $args += "-r" }                 # recurse for folders
  $args += "-P"; $args += $Port
  if ($IdentityFile -and (Test-Path $IdentityFile)) {
    $args += "-i"; $args += $IdentityFile
  }
  $args += "--"                                 # stop option parsing
  $args += $resolved
  $args += $remote

  Write-Host ("Uploading {0} → {1}@{2}:{3} ..." -f $resolved, $UserName, $HostName, $Dest) -ForegroundColor Cyan

  & $scpExe @args
}

Write-Host "Done." -ForegroundColor Green

How to Use

Step 1: Prerequisites

Ensure OpenSSH client is installed on Windows (pre-installed on Windows 10 1809+ and Windows 11). Enable PowerShell script execution with Set-ExecutionPolicy RemoteSigned. Set up SSH key authentication for passwordless transfers (optional but recommended).

Step 2: Configure Default Parameters

Edit the default parameters in the script: $Dest (destination path on Linux), $HostName (Linux server IP), $UserName (SSH username), and $Port (SSH port, default 22). These can be overridden at runtime.

Step 3: Run the Script

Execute with the mandatory -Source parameter: .\push.ps1 -Source "C:\path\to\file.txt". For multiple files/folders: .\push.ps1 -Source "C:\folder","C:\file.png" -Dest "/custom/path". Override any defaults as needed.

Step 4: Monitor Transfer

Watch the console for upload progress. The script displays "Uploading..." messages in cyan and "Done." in green when complete. Errors will stop execution and display the specific issue.