From 32b265876c75897d3b7fce66004b703c064ae571 Mon Sep 17 00:00:00 2001 From: blance Date: Thu, 23 Apr 2026 20:44:29 -0500 Subject: [PATCH] Add -AppendDate and -DateFormat parameters MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Appends today's date to the remote filename before the extension (e.g. export.txt → export_20260423.txt). Applies after -RenamePattern if both are used. Works with -DryRun for preview. --- README.md | 26 ++++++++++++++++++++++++++ Send-FilesToSftp.ps1 | 31 +++++++++++++++++++++++++++++-- 2 files changed, 55 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index fa7ac97..961b686 100644 --- a/README.md +++ b/README.md @@ -49,6 +49,8 @@ The script auto-searches these locations in order: | `-LocalRenameReplacement` | No | — | Replacement string for `-LocalRenamePattern` (supports capture groups like `$1`) | | `-Recurse` | No | `false` | Scan subdirectories | | `-DeleteAfterTransfer` | No | `false` | Delete local files after successful upload. Cannot combine with `-ArchivePath` | +| `-AppendDate` | No | `false` | Append today's date to the remote filename before the extension (e.g. `export.txt` → `export_20260423.txt`) | +| `-DateFormat` | No | `yyyyMMdd` | Date format string used with `-AppendDate`. Any valid `Get-Date` format accepted | | `-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` | @@ -158,6 +160,30 @@ After a successful upload you can archive or rename the local source file. These > `-LocalRenamePattern`/`-LocalRenameReplacement` only rename the local file — the remote name is controlled by `-RenamePattern`/`-RenameReplacement`. You can use both together. +## Appending the Date to Filenames + +Use `-AppendDate` to automatically insert today's date before the file extension on the remote side. The local file is not modified. + +```powershell +# Upload every export.txt in all subfolders, renamed with today's date +.\Send-FilesToSftp.ps1 -LocalPath "C:\jobs" -RemotePath "/incoming" ` + -HostName "sftp.example.com" -UserName "uploader" ` + -FileFilter '^export\.txt$' -Recurse -AppendDate +``` + +Result: `export.txt` → `export_20260423.txt` + +Use `-DateFormat` to change the format: + +```powershell +# Use dashes instead: export_2026-04-23.txt +.\Send-FilesToSftp.ps1 -LocalPath "C:\jobs" -RemotePath "/incoming" ` + -HostName "sftp.example.com" -UserName "uploader" ` + -FileFilter '^export\.txt$' -Recurse -AppendDate -DateFormat 'yyyy-MM-dd' +``` + +`-AppendDate` applies after `-RenamePattern` if both are used, and works with `-DryRun` so you can preview the result first. + ## Renaming Files on the Remote Side Use `-RenamePattern` (regex) and `-RenameReplacement` together to rename files on the remote side without touching the local files. diff --git a/Send-FilesToSftp.ps1 b/Send-FilesToSftp.ps1 index f93f610..6eb4d10 100644 --- a/Send-FilesToSftp.ps1 +++ b/Send-FilesToSftp.ps1 @@ -75,6 +75,14 @@ .PARAMETER LogFile Path to a log file. If omitted, logs to console only. +.PARAMETER AppendDate + Append the current date to the remote filename before the extension (e.g. export.txt → export_20260423.txt). + Applied after -RenamePattern if both are used. Use -DateFormat to change the date format. + +.PARAMETER DateFormat + Date format string used with -AppendDate. Default: 'yyyyMMdd' (e.g. 20260423). + Any valid PowerShell Get-Date format string is accepted (e.g. 'yyyy-MM-dd'). + .PARAMETER WinScpDllPath Path to WinSCPnet.dll. Default: looks in script directory, then common install paths. @@ -131,6 +139,12 @@ .\Send-FilesToSftp.ps1 -LocalPath "C:\data" -RemotePath "/archive" ` -HostName "sftp.example.com" -UserName "svcaccount" ` -KeyFilePath "C:\keys\id_rsa.ppk" -Recurse + +.EXAMPLE + # Upload every export.txt found in subfolders, renamed with today's date + .\Send-FilesToSftp.ps1 -LocalPath "C:\jobs" -RemotePath "/incoming" ` + -HostName "sftp.example.com" -UserName "uploader" ` + -FileFilter '^export\.txt$' -Recurse -AppendDate #> [CmdletBinding(SupportsShouldProcess)] @@ -174,6 +188,10 @@ param( [switch]$DeleteAfterTransfer, + [switch]$AppendDate, + + [string]$DateFormat = 'yyyyMMdd', + [switch]$DryRun, [string]$LogFile, @@ -260,6 +278,7 @@ try { Write-Log "Host : ${HostName}:${Port}" if ($RenamePattern) { Write-Log "Remote rename : '$RenamePattern' → '$RenameReplacement'" } if ($LocalRenamePattern) { Write-Log "Local rename : '$LocalRenamePattern' → '$LocalRenameReplacement'" } + if ($AppendDate) { Write-Log "Append date : enabled (format: $DateFormat)" } if ($ArchivePath) { Write-Log "Archive to : $ArchivePath" } if ($DryRun) { Write-Log "*** DRY RUN MODE - No files will be transferred ***" -Level WARN } @@ -316,11 +335,15 @@ try { Write-Log "Files that would be transferred:" -Level INFO foreach ($f in $allFiles) { $destName = if ($RenamePattern) { $f.Name -replace $RenamePattern, $RenameReplacement } else { $f.Name } + if ($AppendDate) { + $dateStr = Get-Date -Format $DateFormat + $destName = [System.IO.Path]::GetFileNameWithoutExtension($destName) + "_$dateStr" + [System.IO.Path]::GetExtension($destName) + } $localFinalName = if ($LocalRenamePattern) { $f.Name -replace $LocalRenamePattern, $LocalRenameReplacement } else { $f.Name } $remoteDir = $RemotePath.TrimEnd('/') + ($f.DirectoryName.Substring($LocalPath.TrimEnd('\').Length) -replace '\\', '/') $remoteDest = "$remoteDir/$destName" $sizeKB = [math]::Round($f.Length / 1KB, 1) - $remoteRenameNote = if ($RenamePattern -and $destName -ne $f.Name) { " [remote name: $destName]" } else { '' } + $remoteRenameNote = if ($destName -ne $f.Name) { " [remote name: $destName]" } else { '' } Write-Log " UPLOAD : $($f.FullName) → $remoteDest (${sizeKB} KB)$remoteRenameNote" if ($DeleteAfterTransfer) { @@ -398,10 +421,14 @@ try { } $destName = if ($RenamePattern) { $file.Name -replace $RenamePattern, $RenameReplacement } else { $file.Name } + if ($AppendDate) { + $dateStr = Get-Date -Format $DateFormat + $destName = [System.IO.Path]::GetFileNameWithoutExtension($destName) + "_$dateStr" + [System.IO.Path]::GetExtension($destName) + } $targetDir = $RemotePath.TrimEnd('/') + $relativePath $targetPath = "$targetDir/$destName" - if ($RenamePattern -and $destName -ne $file.Name) { + if ($destName -ne $file.Name) { Write-Log "Renaming: $($file.Name) → $destName" }