使用 Memory Stream WinScp/Powershell 在远程目录上创建文件

问题描述 投票:0回答:1

我在 WINSCP 网站上读到,您可以使用 Session.PutFile 方法在远程 FTP 服务器上创建文件,并使用内存流在远程目录上创建对象。

但是显示的语法似乎缺少一些东西。

https://winscp.net/eng/docs/library_session_putfile

它提到创建内存流,然后传递远程目录路径和文件名的参数。

我在我创建的名为 SFTPCreatetrigger 的函数中使用它,因为名称表明重点是当每个文件上传到另一个文件时,使用它在单独的目录上创建具有相同名称的等效触发器文件。

但是,我不断收到错误 New-Object :无法将 'System.Object[]' 转换为参数 'ComObject' 所需的类型 'System.String'。不支持指定的方法。

Error sys object vs sys string

    ## ---------------------------------------------------------
    ## Function to Create file on Remote Directory
    ## ---------------------------------------------------------
    Function SftpCreateTriggerFile
        {
        param
        (
        [string]$FtpServer,
        [string]$FtpTriggerDirectory,
        [string]$FtpUsername,
        [string]$FtpPassword,
        [string]$FtpSshHostKeyFingerprint
        
        
        )   

        [hashtable]$Return = @{}

        ## Get initial time
        $dt = Get-Date
        $StartTime = Get-Date $dt -f "MMddyy HH:mm:ss"
        $StartTimeUtc = $dt.ToUniversalTime().ToString("MMddyy HH:mm:ss")

        ## 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.PortNumber = 22
        $sessionOptions.SshHostKeyFingerprint = $FtpSshHostKeyFingerprint

        $session = New-Object WinSCP.Session

        try
        {
            # Connect
            $session.Open($sessionOptions)
     
            # Upload files
            $transferOptions = New-Object WinSCP.TransferOptions
            $transferOptions.TransferMode = [WinSCP.TransferMode]::Automatic
            $transferOptions.FilePermissions = $null
            $transferOptions.PreserveTimestamp = $false
            $transferOptions.ResumeSupport.State = [WinSCP.TransferResumeSupportState]::Off

            $transferResult = $session.PutFile((New-Object System.IO.MemoryStream, ($FtpTriggerDirectory + $file.fullname)), $transferOptions)
     
            # Throw on any error
            $transferResult.Check()
     
        if ($transferResult.Transfers.Count -gt 0)
            {
            $Return.IsSuccess = $true
            $Return.StandardOutput = "Success"
            }
        else
            {
            $Return.IsSuccess = $false
            $Return.StandardOutput = "Issue occurred creating trigger file on remote directory $FtpTriggerDirectory. No file created."
            }

            ## Calculate time elapsed
            $ExecTime = [math]::Round(([datetime]::Now - ([datetime]::ParseExact($StartTime,'MMddyy HH:mm:ss',$null))).TotalSeconds)
        }

        catch [Exception]
        {
            $Return.IsSuccess = $false
            $Return.StandardOutput = $_.Exception.Message
            ## Calculate time elapsed
            $ExecTime = [math]::Round(([datetime]::Now - ([datetime]::ParseExact($StartTime,'MMddyy HH:mm:ss',$null))).TotalSeconds)
        }   

        finally
        {
            $Return.StartTime = $StartTime
            $Return.StartTimeUtc = $StartTimeUtc            
            $Return.ExecTime = $ExecTime        
        
            ## Disconnect and cleanup
            $session.Dispose()
        }
        
        Return $Return
    }

上面是函数,下面是我要执行的

## Set up wildcards to download files
        $arrFiles = @(Get-ChildItem $LocalDirectory -Filter "*.txt")

        
            foreach ($file in $arrFiles)
                {
                $arrReturnResults = SftpUploadWithWildcards -FtpServer $FtpServer -ftpdirectory $FtpDirectory -FtpUsername $FtpUsername -FtpPassword $FtpPassword -FtpSshHostKeyFingerprint $FtpSshHostKeyFingerprint -LocalDirectory $LocalDirectory -FileNameWildcards $file.Name
                $ProcessName = "Upload($FtpServer):FromDir($LocalDirectory):Files("+$file.Name+")"

                If ($arrReturnResults.IsSuccess)
                    {$arrResults += New-Object Psobject -property @{Time = $arrReturnResults.StartTime; Task = $ProcessName; Status = "Success"; Details = ""; ExecTime = $arrReturnResults.ExecTime; TimeUtc = $arrReturnResults.StartTimeUtc}
                     ## File Archive
                   # Move-Item ($LocalDirectory+$file.Name) ($LocalDirectory+"Archive") -Force -ErrorAction Stop
                    ## Create 0 byte file with the same name to the trigger folder on remote server
                    
                    $arrReturnResults = SftpCreateTriggerFile -FtpServer $FtpServer -ftpTriggerdirectory $FtpTriggerDirectory -FtpUsername $FtpUsername -FtpPassword $FtpPassword -FtpSshHostKeyFingerprint $FtpSshHostKeyFingerprint
                    $ProcessName = "Upload($FtpServer):FromDir($LocalDirectory):TriggerFiles("+$file.Name+")"

                    If ($arrReturnResults.IsSuccess)
                        {$arrResults += New-Object Psobject -property @{Time = $arrReturnResults.StartTime; Task = $ProcessName; Status = "Success"; Details = ""; ExecTime = $arrReturnResults.ExecTime; TimeUtc = $arrReturnResults.StartTimeUtc}
                        
                        }
                    Else
                        {$arrResults += New-Object Psobject -property @{Time = $arrReturnResults.StartTime; Task = $ProcessName; Status = "Failed"; Details = $arrReturnResults.StandardOutput; ExecTime = $arrReturnResults.ExecTime; TimeUtc = $arrReturnResults.StartTimeUtc}}
                   }
              
                Else
                    {$arrResults += New-Object Psobject -property @{Time = $arrReturnResults.StartTime; Task = $ProcessName; Status = "Failed"; Details = $arrReturnResults.StandardOutput; ExecTime = $arrReturnResults.ExecTime; TimeUtc = $arrReturnResults.StartTimeUtc}}
        
                  }

我的所有变量($ftpserver、$ftpusername、$ftptriggerdirectory 等)均设置为正确的值。似乎只是在呼唤

New-Object System.IO.MemoryStream 单独创建一个新的 Memorystream 对象

可以阅读:正确 可以寻求:正确 可以写:正确 容量:0 长度:0 职位:0 可以超时:假 读取超时: 写入超时:

但是我无法为其分配我想要的名称(这实际上是经过 foreach 循环的最后一个 $file)

我已经阅读了 MemoryStream 使用并发现您需要引用“字节”数组?然而,我只是希望它在远程目录上创建一个对象,如我在 Martin Prikryl 本人找到的示例中所述。

memorystream winscp
1个回答
0
投票

如果您的目标是创建一个空文件(从新的空

MemoryStream
),那么问题在于您使用三个参数调用
Session.PutFile
的语法不正确。应该是:

$session.PutFile(
    (New-Object System.IO.MemoryStream),
    ($FtpTriggerDirectory + $file.fullname),
    $transferOptions)

另请注意,

Session.PutFile
不会返回任何内容。因此,所有分配
$transferResult
并使用它的代码都会失败。

© www.soinside.com 2019 - 2024. All rights reserved.