Home > Enterprise >  WinSCP: PowerShell .NET - Multi-functional Get-Files?
WinSCP: PowerShell .NET - Multi-functional Get-Files?

Time:10-29

Goal: I'm trying to get all files that are 1 day old or newer. The remote directory has a lot of directories as well as files on the root directory.

I need to look in each directory, get any files 1 day old, as well as any file on the root directory 1 day old, and transfer all of those to 1 single directory. I'd like to not copy any empty directories, or any directories with files older than 1 day old.

The current code just keeps running and doesn't transfer any files. I'm not sure if I set up the ForEach correctly, as well as the GetFiles section.

  • What does the GetFiles section need to say to meet the file requirements listed above?

Here is an example of what it looks like:

enter image description here

Code:

# Load WinSCP .NET assembly
Add-Type -Path "WinSCPnet.dll"

# Set up session options
$sessionOptions = New-Object WinSCP.SessionOptions -Property @{
    Protocol              = [WinSCP.Protocol]::ftp
    HostName              = "ftp site"
    UserName              = "UserName"
    Password              = "Password"
    SshHostKeyFingerprint = "stuff"
}

$sessionOptions.AddRawSettings("FSProtocol", "2")

$session = New-Object WinSCP.Session
$session.SessionLogPath = $log
try {
    # Connect
    $session.Open($sessionOptions)

    # Set up transfer options
    $transferOptions = New-Object WinSCP.TransferOptions -Property @{
        TransferMode = [WinSCP.TransferMode]::Ascii
    }
    $lcdPath = 'Filepath\'
    $time = (Get-Date).AddDays(-1)   
    $files = @(Get-ChildItem -Path $lcdPath -Attributes !Directory -Recurse | Where-Object { $_.LastWriteTime -gt $time })    
    
    # Transfer files
    foreach ($file in $files) {
    $session.GetFiles($files, "LocalFilePath", $False, $transferOptions).Check()
}
}
finally {
$session.Dispose()
}
exit 0
catch
{
Write-Host "Error: $($_.Exception.Message)"
exit 1
}

CodePudding user response:

You have a couple of issues, and your code will require some re-working but your close.

Your biggest issue is your looking for new files in Filepath\ in the current directory on your local file system, not on the FTP server:

$files = @(Get-ChildItem -Path $lcdPath -Attributes !Directory -Recurse | Where-Object { $_.LastWriteTime -gt $time })

I think you want to list the remote files on the FTP server and build your $files list from this data instead. (example below taken from winscp.net)

        $session.Open($sessionOptions)
 
        $directory = $session.ListDirectory("/home/martin/public_html")
 
        foreach ($fileInfo in $directory.Files)
        {
            Write-Host ("$($fileInfo.Name) with size $($fileInfo.Length), "  
                "permissions $($fileInfo.FilePermissions) and "  
                "last modification at $($fileInfo.LastWriteTime)")
        }

You can adapt this code to populate your $files array based on $fileinfo.LastWriteTime of the remote files, then pass this to your "Transfer files" foreach loop.

Also you have some syntax problems with your try/catch/finally code, it should look like this:

catch
{
  Write-Host "Error: $($_.Exception.Message)"
  exit 1
}
finally {
  $session.Dispose()
}
exit 0

CodePudding user response:

In case it's helpful, this is what I ended up doing to make it work.

$transferOptions = New-Object WinSCP.TransferOptions
$transferOptions.ResumeSupport.State = [WinSCP.TransferResumeSupportState]::On
$file_mask = "*>=1D"
$transferOptions.FileMask = $file_mask

# Transfer files
$session.GetFilesToDirectory("/", "LocalPath", "*>=1D", $False, $null)
$synchronizationResult.Check()
  • Related