使用PowerShell将文件上传到SFTP

49
我们被要求设置一个从我们的服务器自动上传到SFTP站点的功能。每个星期一早晨会从数据库导出一个文件到filer,他们希望在星期二将该文件上传到SFTP。我们目前使用的身份验证方法是用户名和密码(我相信还有使用密钥文件的选项,但选择了用户名/密码选项)。
我想象的方式是,在服务器上放置一个脚本,由Windows任务计划程序触发,在特定时间(星期二)运行该脚本将文件上传到SFTP,然后将其移动到另一个位置以备份目的。
例如:
本地目录:C:\FileDump
SFTP目录:/Outbox/
备份目录:C:\Backup 我尝试了几种方法,其中WinSCP是其中之一,SFTP PowerShell Snap-In 也是,但到目前为止都没有成功。
这将在Windows Server 2012R2上运行。 当我运行Get-Host时,我的控制台主机版本为4.0。
谢谢。
6个回答

115
你没有告诉我们你在WinSCP上遇到了什么具体的问题,所以我只能重复WinSCP文档中的内容。
  • 下载 WinSCP .NET 组件
    截至目前,最新的版本是 WinSCP-6.1.2-Automation.zip

  • .zip 压缩文件与您的脚本一起解压;

  • 使用类似以下代码(基于官方的 PowerShell 上传示例):

    # 加载 WinSCP .NET 组件
    Add-Type -Path "WinSCPnet.dll"
    
    # 设置会话选项
    $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
    {
        # 连接
        $session.Open($sessionOptions)
    
        # 上传
        $session.PutFiles("C:\FileDump\export.txt", "/Outbox/").Check()
    }
    finally
    {
        # 断开连接,清理资源
        $session.Dispose()
    }
    

你可以让WinSCP为你生成上传的PowerShell脚本:
  • 使用WinSCP GUI登录到你的服务器;
  • 在远程文件面板中导航到目标目录;
  • 在本地文件面板中选择要上传的文件;
  • 调用上传命令;
  • 传输选项对话框中,进入传输设置 > 生成代码
  • 在生成传输代码对话框中,选择.NET程序集代码选项卡
  • 选择PowerShell语言。

你将获得一个类似上面的代码,其中包含所有会话和传输设置。

Generate transfer code dialog

(我是WinSCP的作者)

8
昨天我在尝试理解这些东西时遇到了问题,然后我发现了你的帖子。这真的帮了很多!我只用了几分钟就让我的测试运行起来了,而且似乎一切都会很顺利。那是一个非常好用的功能,先生。有时候你只需要一个好的例子。 - Don Rolling

41

目前 PowerShell 没有内置的 SFTP 功能,需要使用类似 psftp.exe 或者 PowerShell 模块如 Posh-SSH。

以下是使用 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 等。

这应该会给你一个相当好的起点。


14

我可以使用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 Pro PowerShell。没有安装额外的模块。


希望这是一个很好的答案,只要我能确保我的计算机上没有安装自定义的PowerShell模块:D。问题在于我无法在此处将Get-Module的响应放入powershell中。它说评论太长了... - aayush singhal
在答案中添加了PowerShell模块列表。 - aayush singhal
2
你很可能正在使用Win32-OpenSSHsftp命令行客户端,它已经内置于最新版本的Windows 10中 - 所以与PowerShell本身无关。 - Martin Prikryl
9
如果您想让这个回答真正有用,您应该发布一个例子,展示如何在实际的自动脚本中使用sftp,而不是交互式地使用它。 - Martin Prikryl
如果您不想使用额外的模块,那么这很好。但是这并不是为PowerShell进行优化的。它甚至没有像路径建议这样的简单功能。只是一个内置于较新版本的Windows 10中的简单客户端。 - Missaka Iddamalgoda
当系统提示输入密码时,你是如何输入密码的? - undefined

8

使用PuTTY的pscp.exe(我已经放在$env:path目录中):

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

0
$FilePath = "C:\Backup\xxx.zip"
$SftpPath = '/Cloud_Deployment/Backup'
$SftpIp = 'mercury.xxx.xx.uk' #Or IP
$Password = 'password'
$userroot = 'username'


$Password = ConvertTo-SecureString $Password -AsPlainText -Force
$Credential = New-Object System.Management.Automation.PSCredential ($userroot, $Password)

Install-Module -Name Posh-SSH  #**rus as Admin** <br>
$SFTPSession = New-SFTPSession -ComputerName $SftpIp -Credential $Credential

#Download file<br>
#Get-SFTPItem -SessionId $SFTPSession.SessionId -Path $SftpPath/test.txt -Destination c:\temp

#Upload file<br>
Set-SFTPItem -SessionId $SFTPSession.SessionId -Path $FilePath -Destination $SftpPath

#Disconnect all SFTP Sessions<br>
Remove-SFTPSession -SFTPSession $SFTPSession<br>
#or <br>
Get-SFTPSession | % { Remove-SFTPSession -SessionId ($_.SessionId) }

Ref : [powershell-sftp][1]

如果你遇到错误 PackageManagement\Install-Package : 找不到指定搜索条件和模块名称 'Posh-SSH' 的匹配项

请访问这里


-1

嗯,使用 PowerShell 7,我们可以使用以下命令简单地使用 SFTP 上传文件

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

请确保添加这些双引号。


1
为什么选择PowerShell 7?这应该适用于任何版本的PowerShell。+ 这并未解决身份验证问题。 - Martin Prikryl
1
我认为可以通过这种方式实现,如果首先安装一些没有密码短语的密钥。然后身份验证将使用密钥文件而不是密码。有关详细信息,请参阅ssh-keygen和ssh-agent的文档。确保不输入密钥的密码短语(因为这样您每次都必须输入密码短语而不是密码 - 与密码相同的问题)。 - Michael W.
@MartinPrikryl 是的,它可以与所有版本的PowerShell一起使用。我提到PowerShell 7是因为我正在使用PS7。 至于自动身份验证,可以使用Michael W.提到的方法。 - Ahmed Kamal

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接