2

I have this script that downloads all .txt and .log files. But I need to move them to another directory on the server after the download.

So far I just keep getting errors like "cannot move "file" to "/file".

try
{
    # Load WinSCP .NET assembly
    Add-Type -Path "C:\Program Files (x86)\WinSCP\WinSCPnet.dll"

    # Setup session options
    $sessionOptions = New-Object WinSCP.SessionOptions
    $sessionOptions.Protocol = [WinSCP.Protocol]::ftp
    $sessionOptions.HostName = "host"
    $sessionOptions.PortNumber = "port"
    $sessionOptions.UserName = "user"
    $sessionOptions.Password = "pass"

    $session = New-Object WinSCP.Session

    try
    {
        # Connect
        $session.DisableVersionCheck = "true"
        $session.Open($sessionOptions)

        $localPath = "C:\users\user\desktop\file"
        $remotePath = "/"
        $fileName = "*.txt"
        $fileNamee = "*.log"
        $remotePath2 = "/completed"
        $directoryInfo = $session.ListDirectory($remotePath)
        $directoryInfo = $session.ListDirectory($remotePath2)

        # Download the file
        $session.GetFiles(($remotePath + $fileName), $localPath).Check()
        $session.GetFiles(($remotePath + $fileNamee), $localPath).Check()

        $session.MoveFile(($remotePath + $fileName, $remotePath2)).Check()
        $session.MoveFile(($remotePath + $fileNamee, $remotePath2)).Check() 

    }
    finally
    {
        # Disconnect, clean up
        $session.Dispose()
    }

    exit 0
}
catch [Exception]
{
    Write-Host $_.Exception.Message
    exit 1
}
4

3 回答 3

3

您的代码中有很多问题:


该方法的targetPath参数Session.MoveFile是移动/重命名文件的路径。

因此,如果您使用目标路径/complete,则您正在尝试将文件移动到根文件夹并将其重命名为complete. 虽然您可能希望将文件移动到文件夹中/complete,并保留其名称。为此使用目标路径/complete/(或/complete/*使其更明显)。

您当前的代码失败,因为您将文件重命名为现有文件夹的名称。


您实际上在.GetFiles. 您正在将所有文件(*.txt*.log)下载到文件夹C:\users\user\desktop并将它们全部保存为相同的名称file,相互覆盖。


您在两个参数周围都有括号错误,而不是仅在第一个参数周围。虽然我不是 PowerShell 专家,但实际上我会说您完全以这种方式省略了该方法的第二个参数。


此外,请注意该MoveFile方法不返回任何内容(与 相反GetFiles)。所以没有对象可以调用该.Check()方法。


MoveFile注意单数,与 相比GetFiles),只移动一个文件。所以你不应该使用文件掩码。实际上,目前的实现允许使用文件掩码,但这种使用是未记录的,并且可能在未来的版本中被弃用。

无论如何,最好的解决方案是迭代实际下载的文件列表,如返回的那样,GetFiles并一一移动文件。

通过这种方式,您可以避免竞争条件,即下载文件集、添加新文件(您没有下载)并且错误地将它们移动到“已完成”文件夹。


代码应如下所示(仅适用于第一组文件,即*.txt):

$remotePath2 = "/completed/"

...

$transferResult = $session.GetFiles(($remotePath + $fileName), $localPath)
$transferResult.Check()

foreach ($transfer in $transferResult.Transfers)
{
    $session.MoveFile($transfer.FileName, $remotePath2) 
}

请注意,这不包括对 的修复$localPath,因为我不确定路径的C:\users\user\desktop\file实际含义。


实际上有一个非常相似的示例代码可用:
成功上传后将本地文件移动到不同位置

于 2015-02-10T17:06:30.343 回答
1

您是否检查过以确保您的进程有权将文件移动到新目录?

于 2015-02-10T17:05:40.180 回答
0

我正在成功地按照 Martin 的建议进行操作。

但我有时会被卡住。

运行“session.MoveFile()”后,源文件夹中的文件消失了,但它没有显示在目标文件夹中。

在一段时间后(我猜大约 30 分钟)自动处理“会话”后,文件将显示到目的地。

为避免这种混淆,请处置会话。像这样 :

session.Dispose();

我知道这是微不足道的,但我希望你不会遇到同样的问题。

于 2021-03-09T10:51:57.080 回答