A comprehensive PowerShell script for SSH connections and secure file transfers.
-
Multiple Transfer Methods:
- Native OpenSSH (SCP) - Built into Windows 10/11
- Posh-SSH Module (SFTP/SCP) - More features and control
-
Flexible Operations:
- Upload files to remote server
- Download files from remote server
- Execute remote SSH commands
- SSH key authentication support
- Custom port support
-
Enable OpenSSH Client (Windows 10/11):
# Run as Administrator Add-WindowsCapability -Online -Name OpenSSH.Client~~~~0.0.1.0
-
Verify Installation:
ssh -V
# Install Posh-SSH module
Install-Module -Name Posh-SSH -Force -Scope CurrentUser# Using native SCP
Transfer-FileWithSCP `
-HostName "server.example.com" `
-UserName "myuser" `
-LocalPath "C:\Documents\report.pdf" `
-RemotePath "/home/myuser/report.pdf" `
-Direction "Upload"# Using native SCP
Transfer-FileWithSCP `
-HostName "server.example.com" `
-UserName "myuser" `
-LocalPath "C:\Downloads\backup.zip" `
-RemotePath "/home/myuser/backups/backup.zip" `
-Direction "Download"# Upload with private key authentication
Transfer-FileWithSCP `
-HostName "server.example.com" `
-UserName "myuser" `
-LocalPath "C:\data\file.txt" `
-RemotePath "/home/myuser/file.txt" `
-PrivateKeyPath "C:\Users\myuser\.ssh\id_rsa" `
-Direction "Upload"# Run a command on remote server
$output = Invoke-SSHCommand `
-HostName "server.example.com" `
-UserName "myuser" `
-Command "df -h"
Write-Host $output# Upload multiple files
$files = Get-ChildItem "C:\Documents\*.pdf"
foreach ($file in $files) {
Transfer-FileWithSCP `
-HostName "server.example.com" `
-UserName "myuser" `
-LocalPath $file.FullName `
-RemotePath "/home/myuser/documents/$($file.Name)" `
-Direction "Upload"
}Upload or download files using native OpenSSH SCP.
Parameters:
HostName(required): Remote server hostname or IPUserName(required): SSH usernameLocalPath(required): Local file pathRemotePath(required): Remote file pathPort(optional): SSH port (default: 22)Direction(required): 'Upload' or 'Download'PrivateKeyPath(optional): Path to private key file
Upload or download files using Posh-SSH module (SFTP).
Parameters:
HostName(required): Remote server hostname or IPUserName(required): SSH usernamePassword(required): SSH passwordLocalPath(required): Local file pathRemotePath(required): Remote file pathPort(optional): SSH port (default: 22)Direction(required): 'Upload' or 'Download'
Execute commands on remote server using native SSH.
Parameters:
HostName(required): Remote server hostname or IPUserName(required): SSH usernameCommand(required): Command to executePort(optional): SSH port (default: 22)PrivateKeyPath(optional): Path to private key file
Execute commands using Posh-SSH module.
Parameters:
HostName(required): Remote server hostname or IPUserName(required): SSH usernamePassword(required): SSH passwordCommand(required): Command to executePort(optional): SSH port (default: 22)
# Upload all files from a directory
$sourceDir = "C:\Projects\website"
$targetDir = "/var/www/html"
Get-ChildItem -Path $sourceDir -Recurse -File | ForEach-Object {
$relativePath = $_.FullName.Substring($sourceDir.Length)
$remotePath = "$targetDir$($relativePath -replace '\\', '/')"
Transfer-FileWithSCP `
-HostName "webserver.com" `
-UserName "webadmin" `
-LocalPath $_.FullName `
-RemotePath $remotePath `
-Direction "Upload"
}# Daily backup script
$date = Get-Date -Format "yyyy-MM-dd"
$backupFile = "C:\Backups\backup-$date.zip"
$remoteBackupDir = "/home/user/backups"
# Create backup
Compress-Archive -Path "C:\Data\*" -DestinationPath $backupFile
# Upload to server
Transfer-FileWithSCP `
-HostName "backup-server.com" `
-UserName "backupuser" `
-LocalPath $backupFile `
-RemotePath "$remoteBackupDir/backup-$date.zip" `
-PrivateKeyPath "C:\Users\user\.ssh\backup_key" `
-Direction "Upload"
# Verify on remote server
$remoteFiles = Invoke-SSHCommand `
-HostName "backup-server.com" `
-UserName "backupuser" `
-Command "ls -lh $remoteBackupDir" `
-PrivateKeyPath "C:\Users\user\.ssh\backup_key"
Write-Host "Remote backup files:" -ForegroundColor Green
Write-Host $remoteFiles# For large files, use Posh-SSH with progress monitoring
function Transfer-LargeFile {
param($HostName, $UserName, $Password, $LocalPath, $RemotePath)
Write-Host "Transferring large file: $LocalPath" -ForegroundColor Yellow
Transfer-FileWithPoshSSH `
-HostName $HostName `
-UserName $UserName `
-Password $Password `
-LocalPath $LocalPath `
-RemotePath $RemotePath `
-Direction "Upload"
}-
"ssh: command not found"
- OpenSSH Client is not installed
- Solution: Run
Add-WindowsCapability -Online -Name OpenSSH.Client~~~~0.0.1.0as Administrator
-
"Permission denied (publickey)"
- SSH key authentication failed
- Solution: Check private key permissions and ensure public key is in
~/.ssh/authorized_keyson remote server
-
"Connection refused"
- SSH service not running or firewall blocking
- Solution: Verify SSH service is running on remote server and port 22 (or custom port) is open
-
"Host key verification failed"
- Host key not in known_hosts
- Solution: Run
ssh-keyscan server.com >> ~/.ssh/known_hostsor connect manually first
# Add -v flag for verbose output
& ssh -v user@server.com
# For SCP, add -v flag
& scp -v file.txt user@server.com:/path/-
Use SSH Keys Instead of Passwords
# Generate SSH key pair ssh-keygen -t ed25519 -C "[email protected]" # Copy public key to server type $env:USERPROFILE\.ssh\id_ed25519.pub | ssh user@server.com "cat >> ~/.ssh/authorized_keys"
-
Protect Private Keys
- Store private keys in
~/.ssh/directory - Set appropriate permissions (Windows: Remove inheritance, keep only your user)
- Store private keys in
-
Use Strong Passwords
- When using password authentication, use strong, unique passwords
- Consider using SecureString in scripts:
$securePassword = Read-Host "Enter password" -AsSecureString
-
Limit Access
- Configure SSH server to use key-only authentication
- Disable root login
- Use non-standard SSH ports when possible
This script is provided as-is for educational and practical use.
Feel free to submit issues and enhancement requests!