各位 Reddit 用户大家好,如果这不是正确的地方,我们深表歉意。我很欣赏这可能更适合 WINSCP 论坛,但是这里有人可能可以告诉我我做错了什么。
我正在尝试创建一个函数,调用该函数时将列出远程目录中的对象。我基于我创建的一个下载文件的函数,但我没有调用 GetFiles 方法,而是调用 ListDirectory 方法。
问题是当我运行此函数时(变量已包含相关的 Ftp 服务器主机名、UN/PW、SSHhostkeyfingerprint 和 FTP 目录),它不会出错,但什么也没有发生
Function SFTPSessionOpen {
param
(
[string]$FtpServer,
[string]$FtpDirectory,
[string]$FtpUsername,
[string]$FtpPassword,
[string]$FtpSshHostKeyFingerprint
)
## Load WinSCP .NET assembly
[Reflection.Assembly]::LoadFrom("C:\Program Files (x86)\WinSCP\WinSCPnet.dll") | Out-Null
## Setup session options
$sessionOptions = New-Object WinSCP.SessionOptions
$sessionOptions.Protocol = [WinSCP.Protocol]::Sftp
$sessionOptions.HostName = $FtpServer
$sessionOptions.UserName = $FtpUsername
$sessionOptions.Password = $FtpPassword
$sessionOptions.SshHostKeyFingerprint = $FtpSshHostKeyFingerprint
$session = New-Object WinSCP.Session
$mycollection = @()
try {
## Connect
$session.Open($sessionOptions)
$mycollection = $session.ListDirectory($FtpDirectory).Files
}
finally {
$session.Dispose()
}
}
我希望它在调用时将目录列表拉入 $mycollection 变量中,但它仍然为空。如果我单独运行部分功能(建立会话然后使用 $session.ListDirectory 它将列出文件)
如有任何帮助,我们将不胜感激!
##Prod
$FtpServer = "clientftp.rimbees.com"
$FtpUsername = "Username"
$Ftppassword = "Password"
$FtpSshHostKeyFingerprint = "ssh-rsa 2048 Wi2ZFNQvI6xvklKznGlZ1Cv5vGB3tV0dtAPH6TFMrJk"
$FtpDirectory = "./"
$mycollection = SFTPSessionOpen -FtpServer $FtpServer -FtpUsername $FtpUsername -FtpPassword $Ftppassword -FtpSshHostKeyFingerprint $FtpSshHostKeyFingerprint -FtpDirectory $FtpDirectory
我使用预定义的变量调用该函数,并期望它至少建立一个会话。最终目标是我运行它并显示远程目录(在本例中为根文件夹)上的所有文件
当我在单独的块中运行该部分时,它可以工作,但是作为一个函数(我尝试使用断点和调试),它似乎永远不会建立连接/打开会话。
尽管听起来很愚蠢,但您无法一步完成所有工作。您必须分两步完成。例如:
$session.Open($sessionOptions)
$directory = $session.ListDirectory($FtpDirectory)
foreach ($fileInfo in $directory.Files)
{
Write-Host ("$($fileInfo.Name) with size $($fileInfo.Length), " +
"permissions $($fileInfo.FilePermissions) and " +
"last modification at $($fileInfo.LastWriteTime)")
}
您首先必须调用
Session.ListDirectory()
方法。这将返回一个 RemoteDirectoryInfo
对象。
(推测)我相信,由于 WinSCP、.NET 和 COM 的工作方式,要返回只读属性,需要首先执行
ListDirectory()
方法才能创建要返回的 RemoteDirectoryInfo
对象,否则,您实际上正在访问一个空的类定义,例如空的,而不是“填充”的 RemoteDirectoryInfo
对象。
但是,这里的另一个关键问题是
ListDirectory()
方法可能会抛出与简单的空 RemoteDirectoryInfo
对象不同的异常。它是一个投掷,例如 SessionRemoteException
,例如列出远程目录失败。这是一条错误消息,您可能希望在 try..catch
块中捕获该消息,以指示 连接存在问题,而不是列出“0 个文件”。 第二步是获取目录列表并根据需要枚举它。
更多信息请参见:
Session.ListDirectory 方法Session.EnumerateRemoteFiles Method