Nenhuma descrição

Blance b2fed6c373 Initial commit: Send-FilesToSftp.ps1 and README 1 dia atrás
README.md b2fed6c373 Initial commit: Send-FilesToSftp.ps1 and README 1 dia atrás
Send-FilesToSftp.ps1 b2fed6c373 Initial commit: Send-FilesToSftp.ps1 and README 1 dia atrás

README.md

Send-FilesToSftp.ps1

PowerShell script to transfer files to an SFTP server with regex filtering, secure credential handling, and logging.

Prerequisites

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:

  1. -WinScpDllPath parameter (if provided)
  2. Same directory as the script
  3. lib\ subdirectory of the script folder
  4. C:\Program Files (x86)\WinSCP\
  5. C:\Program Files\WinSCP\
  6. NuGet package cache (~\.nuget\packages\winscp)

Quick Start

# Basic usage — prompted for password interactively
.\Send-FilesToSftp.ps1 -LocalPath "C:\exports" -RemotePath "/incoming" `
    -HostName "sftp.example.com" -UserName "uploader"

Parameters

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

Authentication

The script supports three auth methods, checked in this order:

1. Credential Object (interactive or pipeline)

$cred = Get-Credential
.\Send-FilesToSftp.ps1 -LocalPath "C:\data" -RemotePath "/uploads" `
    -HostName "sftp.example.com" -UserName "brad" -Credential $cred

2. Saved Credential File (unattended / scheduled tasks)

# 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-Clixml encrypts 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.

3. SSH Private Key

.\Send-FilesToSftp.ps1 -LocalPath "C:\data" -RemotePath "/uploads" `
    -HostName "sftp.example.com" -UserName "svc_upload" `
    -KeyFilePath "C:\keys\id_rsa.ppk"

4. Interactive Prompt

If none of the above are provided and no key file is specified, you'll be prompted for a password at runtime.

File Filtering (Regex)

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)

Usage Examples

Transfer all CSVs

.\Send-FilesToSftp.ps1 -LocalPath "C:\exports" -RemotePath "/incoming" `
    -HostName "sftp.example.com" -UserName "uploader" -FileFilter '\.csv$'

Move files (delete after upload) with logging

.\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"

Dry run — preview without transferring

.\Send-FilesToSftp.ps1 -LocalPath "C:\exports" -RemotePath "/incoming" `
    -HostName "sftp.example.com" -UserName "uploader" -DryRun

Recursive with subdirectories

.\Send-FilesToSftp.ps1 -LocalPath "C:\data\projects" -RemotePath "/archive" `
    -HostName "sftp.example.com" -UserName "uploader" `
    -Recurse -FileFilter '\.pdf$'

SSH Host Key Fingerprint

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).

Scheduled Task Setup

To run unattended via Windows Task Scheduler:

  1. Save credentials as the service account user:

    Get-Credential | Export-Clixml -Path "C:\secure\sftp_cred.xml"
    
  2. 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
    

Exit Codes

Code Meaning
0 All files transferred (or no files matched filter)
1 One or more failures occurred

Log Output

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)