Post a reply

Options
Add an Attachment

If you do not want to add an Attachment to your Post, please leave the Fields blank.

(maximum 10 MB; please compress large files; only common media, archive, text and programming file formats are allowed)

Options

Topic review

martin

Re: Scripts for effectively Moving Files between SFTP/Local directory, but with directory masks

First, if you want to move files, use Session.GetFiles and Sessiopn.PutFiles (or Session.GetFilesToDirectory/Session.PutFilesToDirectory) with remove parameter set to true, instead of Session.SynchronizeDirectories.
https://winscp.net/eng/docs/library_session_getfilestodirectory

To limit the transfer to files in specific subfolders, use path filemask like */FromDMZ/* and use "Exclude empty directories" to avoid "transferring" folders with no relevant files.
https://winscp.net/eng/docs/file_mask#path
https://winscp.net/eng/docs/rawtransfersettings#excludeemptydirectories

$transferOptions = New-Object WinSCP.TransferOptions
$transferOptions.FileMask = "*/FromDMZ/*"
$transferOptions.AddRawSettings("ExcludeEmptyDirectories", "1")
$session.GetFilesToDirectory($remotePath, $localPath, $Null, $True, $transferOptions).Check()

(untested)
mrb783

Scripts for effectively Moving Files between SFTP/Local directory, but with directory masks

Hey all,

I'm a little new to both PowerShell scripting and WinSCP both, but have gotten a bit of this to work...just not fully what I'm wanting it to do. Here's the synopsis:

I have a SFTP landing zone that was created for me (henceforth referred to as DMZ). Within this is a large number of folders, each with subfolders that are used for bidirectional file transfers: "*/FromDMZ" and "*/ToDMZ".

This DMZ directory is used for moving files between subnets that cannot otherwise communicate with one another directly, so we use it as a sort of staging area for file transfers. Effectively, one side will push files to the DMZ SFTP directory, at which point the other side will retrieve them for use, then push files back as needed. We don't want this staging area to fill up, so we want to purge any collected files once we retrieve them.

As such, what I want to do is two-fold, and will likely require separate scripts running in tandem (also, I'm only responsible for one-side of this operation, in case you're wondering why only half of the above description is detailed below):
1. [[Remote->Local]] Transfer any files from any SFTP "*/FromDMZ" subfolder down to my local folders
2. [[Remote]] Delete the version of the file on the "*/FromDMZ" subfolder after successful transfer (aka: complete the Move operation)
3. [[Local->Remote]] Transfer any files from any local "*/ToDMZ" subfolder up to the SFTP remote directory
4. [[Local]] Delete the version of the file on the local "*/ToDMZ" subfolder after successful transfer (aka: complete the Move operation)

I currently have it working to copy EVERYTHING from the SFTP down and then EVERYTHING up...but I want to add in the subfolder masks/filters to only allow items from those specific subfolders to work. I can obviously do this in the GUI, but since I want this to be a scheduled task within Windows, I want to use PowerShell scripts to perform it. I've been searching the WinSCP site for the correct syntax for this, but I'm having a difficult time finding what I'm after. I feel it should be a simple matter of using something like TransferOptions.FileMask... but I'm not really sure how to use this as there aren't that many examples. I think the delete option can be as simple as adding a $True to my SynchronizationMode statement in the below...but not really sure how this works. Any suggestions would be greatly appreciated.

Current code for transferring files to my local directory (identical for the push...just using a ::Remote instead of the ::Local for WinSCP.SynchronizationMode)
$sessionOptions = New-Object WinSCP.SessionOptions -Property @{
   Protocol = [WinSCP.Protocol]::Sftp
   HostName = "*****"
   UserName = "*****"
   SshHostKeyFingerprint = "ssh-rsa 2048 "*****""
   SshPrivateKeyPath = ""*****""
}
 
$sessionOptions.AddRawSettings("ProxyMethod", ""*****"")
$sessionOptions.AddRawSettings("ProxyHost", ""*****"")
$sessionOptions.AddRawSettings("ProxyPort", ""*****"")
 
$session = New-Object WinSCP.Session
try
{
   # Sets the log file output
   $session.SessionLogPath = $logFilePath
   
   # Will continuously report progress of synchronization
   $session.add_FileTransferred( { FileTransferred($_) } )
 
   # Connect
   $session.Open($sessionOptions)
 
   # Synchronize files
   $synchronizationResult = $session.SynchronizeDirectories(
      [WinSCP.SynchronizationMode]::Local, $localPath, $remotePath, $False)
 
   # Throw on any error
   $synchronizationResult.Check()
}