我在 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 对象
CanRead : True CanSeek : True CanWrite : True 容量 : 0 长度 : 0 位置 : 0 CanTimeout : False ReadTimeout : WriteTimeout :
但是我无法为它指定我想要的名称(这实际上是最后一个经过 foreach 循环的 $file)
我读过有关 MemoryStream 用法的文章,发现需要引用“字节”数组?但是,我只想让它在远程目录上创建一个对象,正如 Martin Prikryl 本人找到的示例中所述。