使用 PowerShell 将文件上传到 SFTP

Posted

技术标签:

【中文标题】使用 PowerShell 将文件上传到 SFTP【英文标题】:Upload file to SFTP using PowerShell 【发布时间】:2016-12-08 11:48:55 【问题描述】:

我们被要求设置从我们的一台服务器到 SFTP 站点的自动上传。每个星期一早上都会有一个文件从数据库导出到文件管理器,他们希望文件在星期二上传到 SFTP。我们当前使用的身份验证方法是用户名和密码(我相信还有一个选项可以拥有密钥文件,但选择了用户名/密码选项)。

我设想的方式是在服务器上放置一个脚本,该脚本将由 Windows 任务调度程序触发,在特定时间(星期二)运行,该脚本将抓取有问题的文件,将其上传到 SFTP,然后移动备份到不同的位置。

例如:

本地目录:C:\FileDump

SFTP 目录:/Outbox/

备份目录:C:\Backup

此时我尝试了一些方法,WinSCP 和SFTP PowerShell Snap-In 都是其中之一,但到目前为止没有任何东西对我有用。

这将在 Windows Server 2012R2 上运行。 当我运行 Get-Host 时,我的控制台主机版本是 4.0。

谢谢。

【问题讨论】:

【参考方案1】:

您没有告诉我们 WinSCP 有什么特殊问题,所以我真的只能重复 WinSCP 文档中的内容。

Download WinSCP .NET assembly. 目前最新的包是WinSCP-5.19.5-Automation.zip;

Extract .zip 归档在您的脚本中;

使用这样的代码(基于官方PowerShell upload example):

# Load WinSCP .NET assembly
Add-Type -Path "WinSCPnet.dll"

# Setup session options
$sessionOptions = New-Object WinSCP.SessionOptions -Property @
    Protocol = [WinSCP.Protocol]::Sftp
    HostName = "example.com"
    UserName = "user"
    Password = "mypassword"
    SshHostKeyFingerprint = "ssh-rsa 2048 xxxxxxxxxxx...="


$session = New-Object WinSCP.Session

try

    # Connect
    $session.Open($sessionOptions)

    # Upload
    $session.PutFiles("C:\FileDump\export.txt", "/Outbox/").Check()

finally

    # Disconnect, clean up
    $session.Dispose()


您可以让 WinSCP 为您生成上传的 PowerShell 脚本:

使用 WinSCP GUI 登录您的服务器; 在远程文件面板中导航到目标目录; 在本地文件面板中选择要上传的文件; 调用上传命令; 在Transfer options dialog 上,转到传输设置> 生成代码; 在“生成传输代码”对话框中,选择.NET assembly code tab; 选择 PowerShell 语言。

您将得到一个类似上面的代码,其中填写了所有会话和传输设置。

(我是 WinSCP 的作者)

【讨论】:

我昨天在试图弄清楚这些东西时遇到了问题。然后我找到了你的帖子。这帮助了很多!我在短短几分钟内就完成了我的测试,这一切似乎都会奏效。先生,这是一个非常漂亮的功能。有时你需要的只是一个好例子。【参考方案2】:

目前没有用于执行 SFTP 部分的内置 PowerShell 方法。您必须使用类似 psftp.exe 或类似 Posh-SSH 的 PowerShell 模块。

这里是一个使用Posh-SSH的例子:

# Set the credentials
$Password = ConvertTo-SecureString 'Password1' -AsPlainText -Force
$Credential = New-Object System.Management.Automation.PSCredential ('root', $Password)

# Set local file path, SFTP path, and the backup location path which I assume is an SMB path
$FilePath = "C:\FileDump\test.txt"
$SftpPath = '/Outbox'
$SmbPath = '\\filer01\Backup'

# Set the IP of the SFTP server
$SftpIp = '10.209.26.105'

# Load the Posh-SSH module
Import-Module C:\Temp\Posh-SSH

# Establish the SFTP connection
$ThisSession = New-SFTPSession -ComputerName $SftpIp -Credential $Credential

# Upload the file to the SFTP path
Set-SFTPFile -SessionId ($ThisSession).SessionId -LocalFile $FilePath -RemotePath $SftpPath

#Disconnect all SFTP Sessions
Get-SFTPSession | %  Remove-SFTPSession -SessionId ($_.SessionId) 

# Copy the file to the SMB location
Copy-Item -Path $FilePath -Destination $SmbPath

一些补充说明:

您必须下载 Posh-SSH 模块,您可以将其安装到您的用户模块目录(例如 C:\Users\jon_dechiro\Documents\WindowsPowerShell\Modules),然后使用名称加载或将其放在任何地方并加载就像我在上面的代码中一样。 如果不能接受脚本中的凭据,则必须使用凭据文件。如果您需要这方面的帮助,我可以更新一些详细信息或指向一些链接。 根据需要更改路径、IP 等。

这应该会给你一个不错的起点。

【讨论】:

【参考方案3】:

我可以使用 PowerShell 进行 sftp,如下所示:

PS C:\Users\user\Desktop> sftp user@aa.bb.cc.dd                                                     
user@aa.bb.cc.dd's password:
Connected to user@aa.bb.cc.dd.
sftp> ls
testFolder
sftp> cd testFolder
sftp> ls
taj_mahal.jpeg
sftp> put taj_mahal_1.jpeg
Uploading taj_mahal_1.jpeg to /home/user/testFolder/taj_mahal_1.jpeg
taj_mahal_1.jpeg                                                                      100%   11KB  35.6KB/s   00:00
sftp> ls
taj_mahal.jpeg      taj_mahal_1.jpeg
sftp>

我没有安装 Posh-SSH 或类似的东西。我正在使用 Windows 10 专业版 PowerShell。没有安装其他模块。

【讨论】:

如果我能确保我的机器上没有安装自定义 PowerShell 模块,我希望这可能是一个很好的答案:D。只是我无法将 Get-Module 的响应放在 powershell 中。它说评论太长了... 在答案中添加了 Powershell 模块列表。 您很可能使用的是Win32-OpenSSH sftp 命令行客户端,它内置于最新版本的 Windows 10 中——因此与 PowerShell 本身无关。 如果你想让它成为一个真正有用的答案,你应该发布一个例子,如何在真正的自动脚本中使用sftp,而不是交互。 如果您不想使用其他模块,这很好。但这并未针对 PowerShell 进行优化。这甚至没有像路径建议这样的简单功能。只是一个内置在较新版本的 Windows 10 中的简单客户端【参考方案4】:

使用PuTTY's pscp.exe(我在$env:path 目录中):

pscp -sftp -pw passwd c:\filedump\* user@host:/Outbox/
mv c:\filedump\* c:\backup\*

【讨论】:

【参考方案5】:

好吧,在使用 powershell 7 时,我们可以使用 sftp 使用以下命令简单地上传文件

echo "put localpath/file.txt destinationpath/file.txt" | sftp username@server

确保添加这些双引号。

【讨论】:

为什么选择 PowerShell 7?这应该适用于任何版本的 PowerShell。 + 这并不能解决身份验证问题。 我认为实际上可以这样做,如果您先安装一些没有密码的密钥。然后身份验证将使用密钥文件而不是密码。请参阅 ssh-keygen 和 ssh-agent 的文档。确保不要为密钥输入密码(因为这样您每次都必须输入密码而不是密码 - 与密码相同的问题)。 @MartinPrikryl 是的,它适用于所有版本的 powershell。我提到了 Powershell 7,因为我正在使用 PS7。对于自动身份验证,可以使用 Michael W. 提到的方法。

以上是关于使用 PowerShell 将文件上传到 SFTP的主要内容,如果未能解决你的问题,请参考以下文章

如何制作 PowerShell FTPS 脚本 (SSL) 来上传单个文件?

在 Express Node js 中使用 multer sftp 将文件上传到远程服务器?

直接将文件上传到SFTP而不将其存储到本地系统[重复]

从 SFTP 服务器将文件上传到 Azure 存储 Blob

使用 SFTP 上传文件

为啥使用 sftp 上传文件后文件权限发生变化?