1. Overview
SSH Backup (BackupScheduler) is a .NET 10 Windows application that provides automated, scheduled backups to remote SSH/SFTP servers. It supports two backup strategies—ZIP archives and incremental folder sync—and can be controlled through a WPF GUI or run unattended from Windows Task Scheduler in headless mode.
📦 Dual Backup Modes
Choose ZIP (versioned, encrypted) or incremental sync (rsync-like) per folder.
🔒 AES-256 Encryption
Password-protected ZIP files keep your data secure at rest on the server.
🤖 Headless Mode
Run ssh_backup.exe --headless for fully automated, unattended backups.
🌐 Remote API
Centralized configuration & log collection via HTTP API for multi-machine management.
🔄 Incremental Sync
Pure .NET solution—no external rsync required. Only uploads changed files.
🗂️ Organized Storage
Each folder gets its own subdirectory on the server with automatic old-backup cleanup.
Backup Organization on Server
2. Getting Started
System Requirements
- OS: Windows 10 / 11 (64-bit)
- .NET Runtime: .NET 10.0 Desktop Runtime (x64)
- Network: Access to an SSH/SFTP server
Quick-Start Steps
- Install .NET 10 Desktop Runtime — download here
- Launch
ssh_backup.exe - Click Settings and fill in your SSH host, port, username, password, remote path, and (optionally) ZIP password
- Add folders/files with the Add Folder / Add File buttons
- Choose mode per folder: leave Incremental Sync unchecked for ZIP, checked for sync
- Click Start Backup to run a test
- Verify files on the remote server
- Set up Task Scheduler for automation (see Section 5)
3. Backup Modes
📦 ZIP Backup Mode
Creates timestamped, AES-256-encrypted ZIP archives.
Old archives are automatically deleted when the retention limit is reached.
- File format:
backup_YYYYMMDD_HHMMSS.zip - Uploaded to
/remote/path/{foldername}/ - Configurable retention via Max Backup Files
- Point-in-time recovery from any version
Best for: documents, databases, source code, anything that compresses well or needs versioning.
🔄 Incremental Sync Mode
Pure .NET implementation—no external rsync needed.
Compares size + modification time; uploads only new or changed files.
- 2-second timestamp tolerance for filesystem differences
- Preserves modification times on remote
- Creates missing directories automatically
- Real-time progress: uploaded vs. skipped counts
Best for: media libraries, large file collections, data that changes frequently.
Feature Comparison
| Feature | ZIP Mode | Incremental Sync |
|---|---|---|
| Versioning | ✓ Multiple versions | ✗ Single copy |
| Encryption | ✓ AES-256 | ✗ (SSH transport only) |
| Compression | ✓ ZIP compression | ✗ Raw files |
| Bandwidth | Re-uploads full archive | Only changes |
| Retention Limit | ✓ Configurable | N/A (single copy) |
| External Dependencies | None | None |
Mixed-Mode Backups
Different folders can use different modes in the same backup job:
How Incremental Sync Works
4. GUI Application
Main Window
- Folder list — shows path, method (ZIP / Incremental), and sync checkbox
- Add Folder / Add File — browse and add items to backup
- Remove Selected — remove a folder from the list
- Settings — open configuration dialog
- Start Backup — run an immediate backup
- View Log — open the built-in log viewer
- About — version and credits
- Progress bar & status text — real-time feedback
- Remote Path display — shows current destination with source indicator (local / API)
- Last Backup time — displayed in the header area
Settings Window
| Field | Required | Description |
|---|---|---|
| SSH Host | Yes | Hostname or IP of SFTP server |
| SSH Port | No | Default: 22 |
| Username | Yes | SSH login name |
| SSH Password | Yes | Stored encrypted via DPAPI |
| Remote Path | Yes | Destination directory, e.g. /backup |
| ZIP Password | No | AES-256 encryption for archives |
| Max Backup Files | No | Retention limit per folder (0 = unlimited) |
| Remote Server URL | No | Base URL for management API |
| Remote API Key | No | API authentication key (encrypted) |
| Upload Log File | No | Send logs to API after backup |
5. Task Scheduler & Headless Mode
SSH Backup can run without a GUI by passing --headless. This makes it ideal for
Windows Task Scheduler, scripts, or any automation tool.
Command-Line Usage
Exit Codes
| Code | Meaning |
|---|---|
0 | Backup completed successfully |
1 | Backup failed (check logs) |
2 | Missing required settings — configure via GUI first |
3 | Remote API fetch failed |
4 | Backups disabled by remote server |
Quick Setup (5 Minutes)
- Configure settings — open the GUI, fill in SSH details, add folders, test a backup
- Test headless mode — open PowerShell:
cd "C:\Program Files\SSHBackup" .\ssh_backup.exe --headless echo $LASTEXITCODE # should be 0
- Open Task Scheduler —
Win+R → taskschd.msc - Create Basic Task:
- Name:
SSH Backup - Daily - Trigger: Daily at 2:00 AM
- Action: Start a program
- Program:
C:\Program Files\SSHBackup\ssh_backup.exe - Arguments:
--headless
- Name:
- Advanced settings:
- ☑ Run whether user is logged on or not
- ☑ Run with highest privileges
- ☑ If the task fails, restart every 15 minutes (up to 3 times)
- Test — right-click the task → Run, then check the log
PowerShell One-Liners
Example Console Output
6. Remote API Integration
SSH Backup can fetch configuration from a central server and report back via HTTP API.
A single Server URL is used for all endpoints; authentication is via an
X-API-Key header.
Endpoints
| Purpose | Method | Path |
|---|---|---|
| Fetch / Test Settings | GET | /backup/api/settings_secure.php?username={user} |
| Upload Log | POST | /backup/api/log_upload.php |
Settings Response
How It's Used
- On every startup (GUI and headless), the app calls the settings endpoint
- If
enabledisfalse, GUI shows a warning; headless exits with code 4 backupDirectoryandmaxBackupFilesoverride local values- Values are saved to the registry (
RemoteApiPath,RemoteApiMaxBackups) for offline fallback
7. Log Upload Feature
After each backup (success or failure), SSH Backup can POST the full log to your API for centralized monitoring, alerting, and auditing.
Enable in 4 Steps
- Open Settings
- Fill in Remote Server URL and API Key
- Check "Upload log file to remote server after backup completes"
- Click Save
API Request Format
Filename Convention
What's in the Log?
Use Cases
📊 Centralized Monitoring
Collect logs from multiple machines into one API. Build dashboards, generate reports.
🔍 Remote Troubleshooting
Review logs via API without accessing each machine.
🔔 Alerting
API can parse logs and trigger email/SMS/Slack notifications on failure.
📈 Auditing
Store logs in a database for compliance, regulatory review, or historical analysis.
8. Server-Side API Implementation
You need to host two endpoints on your own server. Below are starter examples in PHP and Python.
Directory Structure
Shared Authentication (PHP)
settings_secure.php (PHP)
log_upload.php (PHP)
Python Flask Example
Testing Your Endpoints
9. Configuration Reference
Registry Location
All settings are stored per-user at:
HKEY_CURRENT_USER\Software\SSHBackup
| Key | Type | Description |
|---|---|---|
Host | String | SFTP server hostname / IP |
Port | String | SSH port (default "22") |
Username | String | SSH username |
SSHPassword | Encrypted | SSH password (DPAPI) |
ZipPassword | Encrypted | ZIP encryption password (DPAPI) |
RemotePath | String | Destination directory on server |
MaxBackupFiles | String | ZIP retention limit per folder (0 = unlimited) |
RemoteServerUrl | String | API base URL |
RemoteApiKey | Encrypted | API authentication key (DPAPI) |
RemoteApiPath | String | Last path received from API |
RemoteApiMaxBackups | String | Last retention limit received from API |
UploadLogFile | String | "true" / "false" |
FolderSetting0, 1, … | String | path|enabled — enabled=True → sync, False → ZIP |
Exporting / Importing Settings
.reg files contain DPAPI-encrypted passwords.
They can only be decrypted by the same Windows user account on the same machine.
Log Files
| File | Location | Purpose |
|---|---|---|
backup_log.txt | %LocalAppData%\SSHBackup\logs\ | Main backup activity log |
error.log | Application directory | Unhandled exceptions |
10. Troubleshooting
Application Won't Start
Symptom: Double-clicking the exe does nothing or shows an error
- Verify .NET 10.0 Desktop Runtime (x64) is installed:
dotnet --list-runtimes - Check
error.login the application folder - Try running as Administrator
- Ensure all DLLs are present:
Renci.SshNet.dll,BouncyCastle.Cryptography.dll,DotNetZip.dll
Authentication Failed
Symptom: Log shows "Authentication failed" or "Permission denied"
- Verify credentials with PuTTY or another SSH client
- Check firewall rules on port 22
- Ensure the SSH server is running
- Confirm the remote path exists and is writable by the SSH user
Headless Mode: "Missing required settings"
Exit code 2
- Open the GUI and configure settings first
- Ensure the Task Scheduler task runs as the same user who configured settings
- Registry settings are per-user (
HKCU)
API Settings Not Applying
Symptom: Remote settings not reflected in the app
- Verify Server URL and API Key in Settings
- Click Test Connection to check reachability
- Test manually:
curl -H "X-API-Key: KEY" \ "http://SERVER/backup/api/settings_secure.php?username=test"
- Check that your API returns valid JSON with
backupDirectory,maxBackupFiles,enabled
Log Upload Fails
Symptom: Backup succeeds but log upload shows an error
- Common HTTP status codes:
401— invalid API key404— endpoint URL incorrect500— server-side error
- Test manually:
curl -X POST \ -H "X-API-Key: KEY" \ -H "Content-Type: application/json" \ -d '{"log":"test","filename":"test.log","mode":"file"}' \ http://SERVER/backup/api/log_upload.php
- The backup is still successful even if the upload fails
Old Backups Not Being Deleted
Symptom: More ZIP files than the configured retention limit
- Verify the folder uses ZIP mode (not Sync)
Max Backup Files = 0means unlimited — set a positive number- Check remote directory permissions (SSH user needs delete rights)
Slow Backup Performance
Tips
- Use Sync mode for large/media files (avoids re-uploading unchanged data)
- Schedule during off-hours to avoid network congestion
- Use wired Ethernet instead of Wi-Fi
- Exclude temporary files and caches from backup