36

We were asked to set up an automated upload from one of our servers to an SFTP site. There will be a file that is exported from a database to a filer every Monday morning and they want the file to be uploaded to SFTP on Tuesday. The current authentication method we are using is username and password (I believe there was an option to have key file as well but username/password option was chosen).

The way I am envisioning this is to have a script sitting on a server that will be triggered by Windows Task scheduler to run at a specific time (Tuesday) that will grab the file in question upload it to the SFTP and then move it to a different location for backup purposes.

For example:

  • Local Directory: C:\FileDump

  • SFTP Directory: /Outbox/

  • Backup Directory: C:\Backup

I tried few things at this point WinSCP being one of them as well as SFTP PowerShell Snap-In but nothing has worked for me so far.

This will be running on Windows Server 2012R2.
When I run Get-Host my console host version is 4.0.

Thanks.

Martin Prikryl
  • 147,050
  • 42
  • 335
  • 704
Konstantin V
  • 403
  • 1
  • 4
  • 9

5 Answers5

88

You didn't tell us what particular problem do you have with the WinSCP, so I can really only repeat what's in WinSCP documentation.

  • Download WinSCP .NET assembly.
    The latest package as of now is WinSCP-5.17.10-Automation.zip;

  • Extract the .zip archive along your script;

  • Use a code like this (based on the official 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()
      }
    

You can have WinSCP generate the PowerShell script for the upload for you:

  • Login to your server with WinSCP GUI;
  • Navigate to the target directory in the remote file panel;
  • Select the file for upload in the local file panel;
  • Invoke the Upload command;
  • On the Transfer options dialog, go to Transfer Settings > Generate Code;
  • On the Generate transfer code dialog, select the .NET assembly code tab;
  • Choose PowerShell language.

You will get a code like above with all session and transfer settings filled in.

Generate transfer code dialog

(I'm the author of WinSCP)

Martin Prikryl
  • 147,050
  • 42
  • 335
  • 704
  • 6
    I was having issues trying to figure this stuff out yesterday. Then I found your post. This helped A LOT! I got my test working in just a few minutes and it all seems like it will work. That is a super nifty feature there, sir. Sometimes all you need is a good example. – Don Rolling Oct 20 '16 at 15:42
35

There isn't currently a built-in PowerShell method for doing the SFTP part. You'll have to use something like psftp.exe or a PowerShell module like Posh-SSH.

Here is an example using 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

Some additional notes:

  • You'll have to download the Posh-SSH module which you can install to your user module directory (e.g. C:\Users\jon_dechiro\Documents\WindowsPowerShell\Modules) and just load using the name or put it anywhere and load it like I have in the code above.
  • If having the credentials in the script is not acceptable you'll have to use a credential file. If you need help with that I can update with some details or point you to some links.
  • Change the paths, IPs, etc. as needed.

That should give you a decent starting point.

User4.159
  • 3
  • 4
Jon Dechiro
  • 1,256
  • 9
  • 6
8

Using PuTTY's pscp.exe (which I have in an $env:path directory):

pscp -sftp -pw passwd c:\filedump\* user@host:/Outbox/
mv c:\filedump\* c:\backup\*
TessellatingHeckler
  • 21,327
  • 3
  • 37
  • 74
7

I am able to sftp using PowerShell as below:

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>

I do not have installed Posh-SSH or anything like that. I am using Windows 10 Pro PowerShell. No additional modules installed.

Martin Prikryl
  • 147,050
  • 42
  • 335
  • 704
aayush singhal
  • 141
  • 1
  • 5
  • Probably a great answer I hope, if I can make sure that there was no custom PowerShell modules installed on my machine :D. It's just that I am not able to put the response of Get-Module in powershell here. It says the comment is too long... – aayush singhal Feb 16 '20 at 19:21
  • Added the list of Powershell modules in the answer. – aayush singhal Feb 16 '20 at 19:46
  • 1
    You most probably using [Win32-OpenSSH](https://github.com/PowerShell/Win32-OpenSSH) `sftp` command-line client, which is built into the latest versions of Windows 10 – So nothing to do with PowerShell as such. – Martin Prikryl Feb 17 '20 at 06:43
  • 3
    If you want to make this a true useful answer, you should post an example, how to use `sftp` in real automatic script, not interactively. – Martin Prikryl Feb 17 '20 at 06:46
  • This is good if you don't want to use additional modules. But this isn't optimized for PowerShell. This does not have even simple features like path suggestions. Just a simple client that comes built into newer versions of Windows 10 – Missaka Iddamalgoda Jun 11 '20 at 08:38
-2

Well, while using powershell 7, we can simply upload files using sftp with following command

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

make sure to add these double quotes.

  • Why PowerShell 7? This should work in any version of PowerShell. + This does not solve authentication. – Martin Prikryl Apr 10 '21 at 16:12
  • I think one can actually do it this way, if you install some keys first without a passphrase. Then the authentification will use the key files instead of a password. See the documentation of ssh-keygen and ssh-agent for that. Make sure to not enter a passphrase for the key (Because then you have to enter the passphrase instead of a password every time - same problem as with the password). – Michael W. Apr 12 '21 at 08:14
  • @MartinPrikryl yeah it works with all version of powershell. i mentioned Powershell 7 because i was working with PS7. and for auto authentication, method mentioned by Michael W. can be used. – Ahmed Kamal Apr 12 '21 at 09:08