|
|
1 өдөр өмнө | |
|---|---|---|
| README.md | 1 өдөр өмнө | |
| Send-FilesToSftp.ps1 | 1 өдөр өмнө |
PowerShell script to transfer files to an SFTP server with regex filtering, secure credential handling, and logging.
WinSCP .NET Assembly (WinSCPnet.dll) is required. Install using one of these methods:
| Method | Steps |
|---|---|
| Drop-in | Download the .NET assembly package, extract WinSCPnet.dll next to the script |
| NuGet | Install-Package WinSCP -Source nuget.org |
| WinSCP Installer | Install WinSCP and check the ".NET assembly" option during setup |
The script auto-searches these locations in order:
-WinScpDllPath parameter (if provided)lib\ subdirectory of the script folderC:\Program Files (x86)\WinSCP\C:\Program Files\WinSCP\~\.nuget\packages\winscp)# Basic usage — prompted for password interactively
.\Send-FilesToSftp.ps1 -LocalPath "C:\exports" -RemotePath "/incoming" `
-HostName "sftp.example.com" -UserName "uploader"
| Parameter | Required | Default | Description |
|---|---|---|---|
-LocalPath |
Yes | — | Local source folder to scan |
-RemotePath |
Yes | — | Remote SFTP destination folder |
-HostName |
Yes | — | SFTP server hostname or IP |
-UserName |
Yes | — | SFTP username |
-FileFilter |
No | .* |
Regex pattern to match filenames |
-Port |
No | 22 |
SFTP port |
-Credential |
No | — | PSCredential object |
-CredentialFile |
No | — | Path to saved credential XML (see below) |
-KeyFilePath |
No | — | Path to SSH private key (.ppk) |
-SshHostKeyFingerprint |
No | — | SSH host key fingerprint for verification |
-Recurse |
No | false |
Scan subdirectories |
-DeleteAfterTransfer |
No | false |
Delete local files after successful upload |
-DryRun |
No | false |
Preview transfers without uploading |
-LogFile |
No | — | Path to log file (logs to console if omitted) |
-WinScpDllPath |
No | — | Explicit path to WinSCPnet.dll |
The script supports three auth methods, checked in this order:
$cred = Get-Credential
.\Send-FilesToSftp.ps1 -LocalPath "C:\data" -RemotePath "/uploads" `
-HostName "sftp.example.com" -UserName "brad" -Credential $cred
# One-time setup — run as the same user that will run the scheduled task
Get-Credential | Export-Clixml -Path "C:\secure\sftp_cred.xml"
# Use in script
.\Send-FilesToSftp.ps1 -LocalPath "C:\data" -RemotePath "/uploads" `
-HostName "sftp.example.com" -UserName "svc_upload" `
-CredentialFile "C:\secure\sftp_cred.xml"
Note:
Export-Clixmlencrypts credentials using Windows DPAPI, tied to the user account and machine that created the file. Only that same user on that same machine can decrypt it.
.\Send-FilesToSftp.ps1 -LocalPath "C:\data" -RemotePath "/uploads" `
-HostName "sftp.example.com" -UserName "svc_upload" `
-KeyFilePath "C:\keys\id_rsa.ppk"
If none of the above are provided and no key file is specified, you'll be prompted for a password at runtime.
The -FileFilter parameter uses PowerShell regex (case-insensitive by default).
| Filter | Matches |
|---|---|
'\.csv$' |
All CSV files |
'\.xlsx?$' |
.xls and .xlsx files |
'^report_\d{8}' |
Files starting with report_ + 8 digits (e.g. report_20260415.csv) |
'(?-i)^Data' |
Files starting with Data (case-sensitive) |
'badge.*\.xlsx$' |
Excel files with badge anywhere in the name |
'\.(csv\|txt)$' |
CSV or TXT files |
'.*' |
Everything (default) |
.\Send-FilesToSftp.ps1 -LocalPath "C:\exports" -RemotePath "/incoming" `
-HostName "sftp.example.com" -UserName "uploader" -FileFilter '\.csv$'
.\Send-FilesToSftp.ps1 -LocalPath "C:\exports" -RemotePath "/incoming" `
-HostName "sftp.example.com" -UserName "svc_upload" `
-CredentialFile "C:\secure\cred.xml" `
-DeleteAfterTransfer -LogFile "C:\logs\sftp_transfer.log"
.\Send-FilesToSftp.ps1 -LocalPath "C:\exports" -RemotePath "/incoming" `
-HostName "sftp.example.com" -UserName "uploader" -DryRun
.\Send-FilesToSftp.ps1 -LocalPath "C:\data\projects" -RemotePath "/archive" `
-HostName "sftp.example.com" -UserName "uploader" `
-Recurse -FileFilter '\.pdf$'
For production use, always provide the host key fingerprint to prevent MITM attacks:
# Get the fingerprint from the server
ssh-keyscan sftp.example.com | ssh-keygen -lf -
# Use it in the script
.\Send-FilesToSftp.ps1 -LocalPath "C:\data" -RemotePath "/uploads" `
-HostName "sftp.example.com" -UserName "uploader" `
-SshHostKeyFingerprint "ssh-rsa 2048 aa:bb:cc:dd:ee:ff:00:11:22:33:44:55:66:77:88:99"
Pass "*" to accept any key (development/testing only — not recommended for production).
To run unattended via Windows Task Scheduler:
Save credentials as the service account user:
Get-Credential | Export-Clixml -Path "C:\secure\sftp_cred.xml"
Create the scheduled task:
$action = New-ScheduledTaskAction `
-Execute "powershell.exe" `
-Argument '-NoProfile -ExecutionPolicy Bypass -File "C:\scripts\Send-FilesToSftp.ps1" -LocalPath "C:\exports" -RemotePath "/incoming" -HostName "sftp.example.com" -UserName "svc_upload" -CredentialFile "C:\secure\sftp_cred.xml" -FileFilter "\.csv$" -DeleteAfterTransfer -LogFile "C:\logs\sftp.log"'
$trigger = New-ScheduledTaskTrigger -Daily -At "2:00AM"
Register-ScheduledTask -TaskName "SFTP Upload" `
-Action $action -Trigger $trigger `
-User "DOMAIN\svc_upload" -Password "****" `
-RunLevel Highest
| Code | Meaning |
|---|---|
0 |
All files transferred (or no files matched filter) |
1 |
One or more failures occurred |
Logs include timestamps and severity levels. Sample output:
[2026-04-16 14:30:01] [INFO] ═══ SFTP Transfer Starting ═══
[2026-04-16 14:30:01] [INFO] Local path : C:\exports
[2026-04-16 14:30:01] [INFO] Remote path : /incoming
[2026-04-16 14:30:01] [INFO] File filter : \.csv$
[2026-04-16 14:30:01] [INFO] Found 3 file(s) matching filter
[2026-04-16 14:30:02] [SUCCESS] Connected to sftp.example.com
[2026-04-16 14:30:03] [SUCCESS] Transferred: report_20260415.csv → /incoming/report_20260415.csv (42.3 KB)
[2026-04-16 14:30:03] [SUCCESS] Transferred: badges_export.csv → /incoming/badges_export.csv (18.1 KB)
[2026-04-16 14:30:04] [SUCCESS] Transferred: access_log.csv → /incoming/access_log.csv (7.8 KB)
[2026-04-16 14:30:04] [INFO] ═══ Transfer Complete ═══
[2026-04-16 14:30:04] [INFO] Succeeded : 3
[2026-04-16 14:30:04] [INFO] Mode : COPY (source files retained)