3

The below PowerShell script connects to my SFTP sever and deletes all my files under the path /test/my_file/.

Is there a way where I can say only delete files that is five days old under the path /test/my_file/.

Add-Type -Path " WinSCPnet.dll"

$sessionOptions = New-Object WinSCP.SessionOptions -Property @{
    Protocol = [WinSCP.Protocol]::Sftp
    HostName = "example.test.com"
    UserName = "username"
    Password = "password"
    SshHostKeyFingerprint = "ssh-rsa 1234 xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx"
}

$sessionOptions.AddRawSettings("ProxyMethod", "0")
$sessionOptions.AddRawSettings("ProxyHost", "123.45.67.8")
$sessionOptions.AddRawSettings("ProxyPort", "8080")

$session = New-Object WinSCP.Session

try
{
    $session.Open($sessionOptions)

    # Remove files
    $session.RemoveFiles("/test/my_file/*").Check()
}
finally
{
    $session.Dispose()
} 

The files have names like:

Test_File_20180315.csv
Test_File_20180316.csv
Test_File_20180319.csv
Test_File_20180320.csv
Test_File_20180321.csv
Test_File_20180322.csv
Test_File_20180323.csv
Test_File_20180326.csv
Test_File_20180327.csv
Test_File_20180328.csv
Test_File_20180329.csv
Test_File_20180330.csv
Test_File_20180402.csv
Test_File_20180403.csv
Test_File_20180404.csv

Thank you in advance.

Martin Prikryl
  • 188,800
  • 56
  • 490
  • 992
rich dave
  • 57
  • 1
  • 7

2 Answers2

4

If you can use modification time of the files, it's easy. Just use a time constraint in the file mask:

$session.RemoveFiles("/test/my_file/*<5D").Check()

But if you need to select the files by the timestamp in their name, it's more difficult. Luckily your file names seem to have a nice fixed format Test_File_yyyymmdd.csv, so you can select those that sort before Test_File_yyyymmdd.csv where yyyymmdd is 5 days old:

$limit = [System.DateTime]::Today.AddDays(-5).ToString("yyyyMMdd")

$session.ListDirectory("/test/my_file").Files |
    Where-Object { !$_.IsDirectory } |
    Where-Object { $_.Name -lt ("Test_File_" + $limit) } |
    ForEach-Object { 
        Write-Host ("Deleting {0} ..." -f $_.Name)
        $session.RemoveFiles($_.FullName).Check()
    }

(of course, first do a dry test with the RemoveFiles call removed)

See also WinSCP article on formatting relative timestamps in PowerShell.

Martin Prikryl
  • 188,800
  • 56
  • 490
  • 992
  • This is the error im getting in the log file,< 2018-04-05 13:43:12.236 Script: No file matching '*<2D' found. > 2018-04-05 13:43:12.392 Script: exit . 2018-04-05 13:43:12.392 Script: Exit code: 0 . 2018-04-05 13:43:12.392 Closing connection. . 2018-04-05 13:43:12.392 Sending special code: 12 . 2018-04-05 13:43:12.392 Sent EOF message – rich dave Apr 05 '18 at 12:44
  • Sorry Martin, i have edit my original question and added the log file. i hope it helps. – rich dave Apr 05 '18 at 12:56
  • First, there some inconsistency in the log. Did you edit it? It says `* <2D` at the beginning, while `* <5D` at the end. - Anyway, all the files have timestamp `2018-04-05`, so there's indeed no file older than 5 days, not even 2 days. - I can see the the files have also timestamps in their names. So maybe you actually wanted to match the filename, not the (last modification) timestamp. But that's a completely different question. – Martin Prikryl Apr 05 '18 at 13:06
0

In one script I use, I have multiple operations to perform, but at the end I delete files older than a few days. So, I fetch all the files once at the beginning and then at the end remove them.

Minimal code would look like:

Add-Type -Path 'C:\Path\To\WinSCP\WinSCPnet.dll'

# Midnight 5 days ago
$DeletionDate = [System.DateTime]::Today.AddDays(-5)

$SessionOptions = New-Object WinSCP.SessionOptions -Property @{ ... }

$Session = New-Object WinSCP.Session
$Session.Open($SessionOptions)

$RemoteFiles = $Session.ListDirectory($RemotePath).Files | Where-Object { !$_.IsDirectory }

# My other processes are here

$RemoteFiles | 
    Where-Object LastWriteTime -lt $DeletionDate |
    ForEach-Object {
        $RemoveFilesResult = $Session.RemoveFiles($_.FullName)
        $RemoveFilesResult.Check()
    }
Bacon Bits
  • 30,782
  • 5
  • 59
  • 66
  • How do i use your code and link it with mine because i need to connect to a sftp and delete files form there? – rich dave Apr 05 '18 at 09:15