PowerShell能否使用FTP在一次传输中检索远程文件夹和子文件夹目录数据?
我有一个PowerShell脚本,用于检查远程位置文件的现有时间戳数据,以便与本地文件进行比较 使用以下代码段检索本地信息:PowerShell能否使用FTP在一次传输中检索远程文件夹和子文件夹目录数据?,powershell,ftp,ftpwebrequest,Powershell,Ftp,Ftpwebrequest,我有一个PowerShell脚本,用于检查远程位置文件的现有时间戳数据,以便与本地文件进行比较 使用以下代码段检索本地信息: $SrcEntries = Get-ChildItem $FolderLocation -Recurse 然后,我可以通过以下代码片段获得有关文件夹和文件的特定信息: $Srcfolders = $SrcEntries | Where-Object{$_.PSIsContainer} $SrcFiles = $SrcEntries | Where-Object{!$_.
$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文件夹中递归列出文件 你必须自己实现这一点:
- 列出远程文件夹
- 迭代条目,递归到子文件夹中-再次列出它们,等等
FtpWebRequest
)无法以可移植的方式实现这一点。不幸的是.NET framework不支持MLSD
命令,这是在FTP协议中检索带有文件属性的目录列表的唯一可移植方法。另见
你的选择是:
- 对文件名执行一个操作,该操作对于文件名肯定会失败,而对于目录则会成功(反之亦然)。即,您可以尝试下载“名称”
- 您可能很幸运,在您的特定情况下,您可以通过文件名从目录中区分文件(即,您的所有文件都有扩展名,而子目录没有扩展名)
- 使用长目录列表(
command=LIST
method)并尝试解析特定于服务器的列表。许多FTP服务器使用*nix样式的列表,您可以通过条目开头的ListDirectoryDetails
来标识目录。但许多服务器使用不同的格式。下面的示例使用这种方法(假设*nix格式)d
$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程序集可以通过使用的单个调用来实现这一点 您也可能会发现这些问题(由我回答)很有用:
$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()
}