如何在 PowerShell 中查询 FTP 服务器上的文件以确定是否需要上传?

How do I query a file on FTP server in PowerShell to determine if an upload is required?

该项目是使用 VS2017 和(本地)TFS2017 编码和构建的 MVC 网站。生成定义当前正在运行并在签入时发布到暂存位置。

正在使用下面派生自 David Kittle's website 的 PowerShell 脚本,但它每次都会上传所有文件。我使用注释简化了列表,以专注于我想要请求 help/guidance.

的脚本部分
# Setup the FTP connection, destination URL and local source directory
# Put the folders and files to upload into $Srcfolders and $SrcFiles
# Create destination folders as required

# start file uploads
foreach($entry in $SrcFiles)
{
    #Create full destination filename from $entry and put it into $DesFile
    $uri = New-Object System.Uri($DesFile) 

    #NEED TO GET THE REMOTE FILE DATA HERE TO TEST AGAINST THE LOCAL FILE
    If (#perform a test to see if the file needs to be uploaded)
        { $webclient.UploadFile($uri, $SrcFullname) }
}

在上面脚本的最后几行中,我需要确定源文件是否需要上传。我假设我可以检查时间戳来确定这一点。所以;

如果我的假设有误,请告知检查所需上传的最佳方法。

如果我的假设是正确的,我该如何 (1) 从远程服务器检索时间戳,然后 (2) 对本地文件进行检查?

您可以使用 FtpWebRequest class with its GetDateTimestamp FTP "method" and parse the UTC timestamp string it returns. The format is specified by RFC 3659YYYYMMDDHHMMSS[.sss]

仅当 FTP 服务器支持该方法在幕后使用的 MDTM 命令时才有效(大多数服务器支持,但不是全部)。

$url = "ftp://ftp.example.com/remote/folder/file.txt"
$ftprequest = [System.Net.FtpWebRequest]::Create($url)

$ftprequest.Method = [System.Net.WebRequestMethods+Ftp]::GetDateTimestamp

$response = $ftprequest.GetResponse().StatusDescription

$tokens = $response.Split(" ")

$code = $tokens[0]

if ($code -eq 213)
{
    Write-Host "Timestamp is $($tokens[1])"
}
else
{
    Write-Host "Error $response"
}

它会输出如下内容:

Timestamp is 20171019230712

现在解析它,并与本地文件的 UTC 时间戳进行比较:

(Get-Item "file.txt").LastWriteTimeUtc

或者节省一些时间,使用可以为您完成此操作的 FTP library/tool。

例如WinSCP .NET assembly, you can synchronize whole local folder with a remote folder with one call to the Session.SynchronizeDirectories。或者您可以将同步限制为仅一组文件。

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

# Setup session options
$sessionOptions = New-Object WinSCP.SessionOptions
$sessionOptions.Protocol = [WinSCP.Protocol]::Ftp
$sessionOptions.HostName = "ftpsite.com"

$session = New-Object WinSCP.Session

# Connect
$session.Open($sessionOptions)

$result = $session.SynchronizeDirectories(
    [WinSCP.SynchronizationMode]::Remote, "C:\local\folder", "/remote/folder")
$result.Check()

要使用程序集,只需将 .NET assembly package 的内容提取到您的脚本文件夹中。无需其他安装。

程序集不仅支持 MDTM,还支持其他检索时间戳的替代方法。

(我是WinSCP的作者)