Initial upload script — PDF to FTP with archive

This commit is contained in:
2026-06-29 19:28:44 -05:00
parent 3c80aa7b36
commit f0d2767bce
5 changed files with 136 additions and 2 deletions
+4
View File
@@ -0,0 +1,4 @@
# Never commit real credentials
ftp-config.ini
archive/
*.pdf
+27 -2
View File
@@ -1,3 +1,28 @@
# ftp-uploader # FTP Uploader
Simple click-to-run FTP upload script for Windows Drop PDFs in a folder, double-click `upload.bat` to send them to FTP, done.
Uploaded files are moved to an `archive` subfolder automatically.
## Setup (per practice folder)
1. Copy `upload.bat`, `upload.ps1`, and `ftp-config.ini` into the folder
2. Edit `ftp-config.ini` with the FTP credentials for that practice
3. Drop PDFs into the folder
4. Double-click `upload.bat`
## ftp-config.ini options
| Key | Required | Description |
|-----|----------|-------------|
| `host` | Yes | FTP server hostname or IP |
| `port` | No | Port (default: 21) |
| `username` | Yes | FTP username |
| `password` | Yes | FTP password |
| `remote_path` | No | Remote folder path (default: `/`) |
| `tls` | No | Set to `true` for FTPS (default: `false`) |
## Behaviour
- Only `.pdf` files in the folder are uploaded (not subfolders)
- Files that fail are left in place for the next run to retry
- Successfully uploaded files move to `archive\`
+9
View File
@@ -0,0 +1,9 @@
# FTP configuration for this practice folder.
# Fill in the details below and keep this file private.
host=ftp.example.com
port=21
username=youruser
password=yourpassword
remote_path=/incoming
tls=false
+3
View File
@@ -0,0 +1,3 @@
@echo off
powershell.exe -ExecutionPolicy Bypass -File "%~dp0upload.ps1"
pause
+93
View File
@@ -0,0 +1,93 @@
# FTP/FTPS PDF Uploader
# Place this script and ftp-config.ini in the same folder as your PDFs.
# Run via upload.bat (double-click).
$scriptDir = Split-Path -Parent $MyInvocation.MyCommand.Path
$configFile = Join-Path $scriptDir "ftp-config.ini"
if (-not (Test-Path $configFile)) {
Write-Host "ERROR: ftp-config.ini not found." -ForegroundColor Red
Write-Host "Create ftp-config.ini in the same folder as this script." -ForegroundColor Red
exit 1
}
# Parse config
$config = @{}
foreach ($line in Get-Content $configFile) {
if ($line -match '^\s*([^=;#\s]+)\s*=\s*(.+?)\s*$') {
$config[$matches[1]] = $matches[2]
}
}
$ftpHost = $config["host"]
$ftpPort = if ($config["port"]) { [int]$config["port"] } else { 21 }
$username = $config["username"]
$password = $config["password"]
$remotePath = if ($config["remote_path"]) { $config["remote_path"].TrimEnd("/") } else { "/" }
$useTls = $config["tls"] -eq "true"
if (-not $ftpHost -or -not $username -or -not $password) {
Write-Host "ERROR: ftp-config.ini is missing required fields (host, username, password)." -ForegroundColor Red
exit 1
}
$archiveDir = Join-Path $scriptDir "archive"
if (-not (Test-Path $archiveDir)) {
New-Item -ItemType Directory -Path $archiveDir | Out-Null
}
$pdfs = Get-ChildItem -Path $scriptDir -Filter "*.pdf" -File
if ($pdfs.Count -eq 0) {
Write-Host "No PDF files found in this folder." -ForegroundColor Yellow
exit 0
}
$protocol = if ($useTls) { "ftps" } else { "ftp" }
Write-Host ""
Write-Host "Uploading $($pdfs.Count) PDF(s) to $protocol://$ftpHost$remotePath" -ForegroundColor Cyan
Write-Host ""
$ok = 0
$fail = 0
foreach ($pdf in $pdfs) {
$remoteFile = "$remotePath/$($pdf.Name)"
$uri = "ftp://${ftpHost}:${ftpPort}${remoteFile}"
Write-Host " $($pdf.Name) ..." -NoNewline
try {
$req = [System.Net.FtpWebRequest]::Create($uri)
$req.Method = [System.Net.WebRequestMethods+Ftp]::UploadFile
$req.Credentials = New-Object System.Net.NetworkCredential($username, $password)
$req.EnableSsl = $useTls
$req.UseBinary = $true
$req.UsePassive = $true
$req.KeepAlive = $false
$bytes = [System.IO.File]::ReadAllBytes($pdf.FullName)
$req.ContentLength = $bytes.Length
$stream = $req.GetRequestStream()
$stream.Write($bytes, 0, $bytes.Length)
$stream.Close()
$resp = $req.GetResponse()
$resp.Close()
Move-Item -Path $pdf.FullName -Destination (Join-Path $archiveDir $pdf.Name) -Force
Write-Host " uploaded" -ForegroundColor Green
$ok++
}
catch {
Write-Host " FAILED: $($_.Exception.Message)" -ForegroundColor Red
$fail++
}
}
Write-Host ""
if ($fail -eq 0) {
Write-Host "Done: $ok file(s) uploaded and archived." -ForegroundColor Green
} else {
Write-Host "Done: $ok uploaded, $fail failed (left in place for retry)." -ForegroundColor Yellow
}