我在 WINSCP 网站上读到,您可以使用 Session.PutFile 方法在远程 FTP 服务器上创建文件,并使用内存流在远程目录上创建对象。
但是显示的语法似乎缺少一些东西。
https://winscp.net/eng/docs/library_session_putfile
它提到创建内存流,然后传递远程目录路径和文件名的参数。
我在我创建的名为 SFTPCreatetrigger 的函数中使用它,因为名称表明重点是当每个文件上传到另一个文件时,使用它在单独的目录上创建具有相同名称的等效触发器文件。
但是,我不断收到错误 New-Object :无法将 'System.Object[]' 转换为参数 'ComObject' 所需的类型 'System.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
),那么问题在于您使用三个参数调用 Session.PutFile
的语法不正确。应该是:
$session.PutFile(
(New-Object System.IO.MemoryStream),
($FtpTriggerDirectory + $file.fullname),
$transferOptions)
另请注意,
Session.PutFile
不会返回任何内容。因此,所有分配 $transferResult
并使用它的代码都会失败。