PowerShell能否使用FTP在一次传输中检索远程文件夹和子文件夹目录数据?

PowerShell能否使用FTP在一次传输中检索远程文件夹和子文件夹目录数据?,powershell,ftp,ftpwebrequest,Powershell,Ftp,Ftpwebrequest,我有一个PowerShell脚本,用于检查远程位置文件的现有时间戳数据,以便与本地文件进行比较 使用以下代码段检索本地信息: $SrcEntries = Get-ChildItem $FolderLocation -Recurse 然后,我可以通过以下代码片段获得有关文件夹和文件的特定信息: $Srcfolders = $SrcEntries | Where-Object{$_.PSIsContainer} $SrcFiles = $SrcEntries | Where-Object{!$_.

我有一个PowerShell脚本,用于检查远程位置文件的现有时间戳数据,以便与本地文件进行比较

使用以下代码段检索本地信息:

$SrcEntries = Get-ChildItem $FolderLocation -Recurse
然后,我可以通过以下代码片段获得有关文件夹和文件的特定信息:

$Srcfolders = $SrcEntries | Where-Object{$_.PSIsContainer}
$SrcFiles = $SrcEntries | Where-Object{!$_.PSIsContainer}
远程信息当前使用此代码段检索,该代码段针对每个文件分别执行:

$Credentials = New-Object System.Net.NetworkCredential($FTPUser,$FTPPassword)
$FTPrequest = [System.Net.FtpWebRequest]::Create($RemoteFilePath)
$FTPrequest.Method = [System.Net.WebRequestMethods+FTP]::GetDateTimestamp
$FTPrequest.Credentials = $Credentials
$response = $FTPrequest.GetResponse().StatusDescription
然后解析
$response
,以检索远程文件的时间戳

检索远程数据的方式似乎与检索本地数据的方式相同,也就是说,与上面的第一个代码片段一样,在单个操作中检索远程数据会更好,以避免多次往返到远程服务器


是否可以使用PowerShell在单个快速FTP操作中递归获取文件夹和文件目录数据?我该怎么做呢?

如果没有任何外部库,要实现这一点并不容易。不幸的是,.NET Framework和PowerShell都不明确支持在FTP文件夹中递归列出文件

你必须自己实现这一点:

  • 列出远程文件夹
  • 迭代条目,递归到子文件夹中-再次列出它们,等等
第一个棘手的部分是从子文件夹中识别文件。使用.NET framework(
FtpWebRequest
)无法以可移植的方式实现这一点。不幸的是.NET framework不支持
MLSD
命令,这是在FTP协议中检索带有文件属性的目录列表的唯一可移植方法。另见

你的选择是:

  • 对文件名执行一个操作,该操作对于文件名肯定会失败,而对于目录则会成功(反之亦然)。即,您可以尝试下载“名称”
  • 您可能很幸运,在您的特定情况下,您可以通过文件名从目录中区分文件(即,您的所有文件都有扩展名,而子目录没有扩展名)
  • 使用长目录列表(
    LIST
    command=
    ListDirectoryDetails
    method)并尝试解析特定于服务器的列表。许多FTP服务器使用*nix样式的列表,您可以通过条目开头的
    d
    来标识目录。但许多服务器使用不同的格式。下面的示例使用这种方法(假设*nix格式)
使用以下功能:

$credentials = New-Object System.Net.NetworkCredential("user", "mypassword") 
$url = "ftp://ftp.example.com/directory/to/list/"
ListFtpDirectory $url $credentials

尽管上面的代码将只列出名称。因为您也需要时间戳,所以即使是这些时间戳,您也必须解析出来。这和确定条目是文件夹还是文件一样复杂

我没有这方面的PowerShell代码,但看到了我对其他类似问题的回答,其中显示了C#代码。它应该很容易转换为PowerShell:


如果要避免解析特定于服务器的目录列表格式时出现问题,请使用支持
MLSD
命令和/或解析各种
LIST
列表格式的第三方库

例如,通过调用,您可以递归地列出整个目录:

不仅代码更简单,而且更rubust和平台独立。它还使所有其他文件属性(大小、修改时间、权限、所有权)可以通过

在内部,如果服务器支持,WinSCP使用
MLSD
命令。如果没有,它将使用
LIST
命令并支持几十种不同的列表格式


虽然您的目标似乎是比较本地和远程时间戳以同步文件夹

WinSCP.NET程序集可以通过使用的单个调用来实现这一点

您也可能会发现这些问题(由我回答)很有用:

(我是WinSCP的作者)

$credentials = New-Object System.Net.NetworkCredential("user", "mypassword") 
$url = "ftp://ftp.example.com/directory/to/list/"
ListFtpDirectory $url $credentials
# 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 = "user"
    Password = "mypassword"
}

$session = New-Object WinSCP.Session

try
{
    # Connect
    $session.Open($sessionOptions)

    # Download files
    $options =
        [WinSCP.EnumerationOptions]::EnumerateDirectories -bor
        [WinSCP.EnumerationOptions]::AllDirectories
    $fileInfos = $session.EnumerateRemoteFiles(
        "/directory/to/list", $Null, $options)
    foreach ($fileInfo in $fileInfos)
    {
        Write-Host $fileInfo.FullName
    }
}
finally
{
    # Disconnect, clean up
    $session.Dispose()
}