【问题标题】:Delete files older than X days from FTP server with PowerShell or batch file使用 PowerShell 或批处理文件从 FTP 服务器删除超过 X 天的文件
【发布时间】:2016-12-01 16:51:22
【问题描述】:

我必须编写一个访问 FTP 服务器的脚本,然后删除所有早于 X 天的 *.zip 文件。

澄清:该脚本无法在 FTP 服务器上运行。

这是我目前所拥有的:

$ftpServer = "RandomFTPServer"
$ftpUser = "Username"
$ftpPassword = Read-Host "Password" -AsSecureString

$credentials = New-ObjectSystem.Net.NetworkCredential($ftpUser, $ftpPassword)

function Get-FtpRequest($ftpPath) {
    $ftpRequest = [System.Net.FtpWebRequest]::Create("$ftpServer/$ftpPath")
    $ftpRequest.Credentials = $credentials
    $ftpRequest.UseBinary = $true 
    $ftpRequest.KeepAlive = $true
    $ftpRequest.UsePassive = $true
    return $ftpRequest
}

关于我接下来需要做什么的任何提示?

【问题讨论】:

    标签: .net powershell batch-file ftp ftpwebrequest


    【解决方案1】:

    您必须检索远程文件的时间戳才能选择旧文件。

    不幸的是,没有真正可靠和有效的方法来使用 .NET 框架/PowerShell 提供的功能来检索时间戳,因为它不支持 FTP MLSD 命令。

    所以要么你使用:

    • ListDirectoryDetails 方法(FTP LIST 命令)检索目录中所有文件的详细信息,然后处理 FTP 服务器特定格式的详细信息(*nix 格式类似于ls *nix 命令是最常见的,缺点是格式可能会随着时间而改变,因为新文件使用“May 8 17:48”格式,而旧文件使用“Oct 18 2009”格式)
    • GetDateTimestamp 方法(FTP MDTM 命令)单独检索每个文件的时间戳。优点是响应由RFC 3659 标准化为YYYYMMDDHHMMSS[.sss]。缺点是您必须为每个文件发送单独的请求,这可能效率很低。

    一些参考资料:

    尽管Microsoft does not recommend FtpWebRequest for a new development 无论如何。


    或者,您可以使用支持现代 MLSD 命令和/或内置支持解析不同格式的 LIST 命令的第 3 方 FTP 客户端实现。

    例如,WinSCP .NET assembly 支持两者。

    # Load WinSCP .NET assembly
    Add-Type -Path "WinSCPnet.dll"
    
    # Setup session options
    $sessionOptions = New-Object WinSCP.SessionOptions -Property @{
        Protocol = [WinSCP.Protocol]::Ftp
        HostName = "ftp.example.com"
        UserName = "username"
        Password = "password"
    }
    
    try
    {
        # Connect
        $session = New-Object WinSCP.Session
        $session.Open($sessionOptions)
    
        # List files
        $remotePath = "/remote/path"
        $directoryInfo = $session.ListDirectory($remotePath)
    
        # Find old files
        $limit = (Get-Date).AddDays(-15)
    
        $oldFiles =
            $directoryInfo.Files |
            Where-Object { -Not $_.IsDirectory } | 
            Where-Object { $_.LastWriteTime -lt $limit }
    
        # Delete them
        foreach ($oldFileInfo in $oldFiles)
        {
            $session.RemoveFile($oldFileInfo.FullName).Check()
        } 
    
        Write-Host "Done"
    }
    finally
    {
        # Disconnect, clean up
        $session.Dispose()
    }
    

    如果您可以使用普通的批处理文件,那么使用WinSCP scripting 实际上会更容易:

    winscp.com /ini=nul /log=delete.log /command ^
        "open ftp://username:password@ftp.example.com/" ^
        "rm /remote/path/*<15D" ^
        "exit"
    

    file masks with time constraints

    (我是 WinSCP 的作者)


    请注意,WinSCP 不需要任何安装。因此,您可以将其二进制文件与您的批处理文件或 PowerShell 脚本一起复制。

    【讨论】:

      【解决方案2】:

      我目前正在使用FTPUSE 执行此操作,这是一个免费的命令行工具,可将 FTP 文件夹映射到 Windows 驱动器号,以及以下方式的批处理文件:

      : delete files older than 7 days from ftp://my.ftpsite.net/folder/subfolder
      ftpuse F: my.ftpsite.net password /USER:username
      timeout /t 5
      forfiles -p "F:\folder\subfolder" -s -m *.* -d -7 -c "cmd /C DEL @File /Q"
      ftpuse F: /DELETE
      

      该软件兼容所有主要版本的 Windows:Windows XP、Vista、7、Server 2003、Server 2008、Windows 8、Server 2012 和 Windows 10(32 位、64 位)。

      有关更多信息,您还可以阅读this post我写的关于 FTPUSE 的文章(无论如何我都不是作者,我只是觉得它对这类任务非常有用)。

      【讨论】:

        猜你喜欢
        • 2012-03-26
        • 2010-09-08
        • 2018-09-15
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-05-26
        相关资源
        最近更新 更多