21

I need to write a script that transfers files from a folder onto another server (Linux), but the script that's transferring files is on windows, and I was wondering if there was an alternative to scp for PowerShell (or if there was another way of doing this)

Martin Prikryl
  • 188,800
  • 56
  • 490
  • 992
Saad
  • 26,316
  • 15
  • 48
  • 69
  • For anyone that is using PowerShell version 3 or later, https://github.com/darkoperator/Posh-SSH is an option. – Don Cruickshank Jan 21 '15 at 12:48
  • 2
    honestly its freaking ridiculous this task is so hard in MS still. This is the very basic task of server administrating.. – Gewure Jul 04 '19 at 16:53

5 Answers5

23

There is a handy little tool that comes with Putty called pscp.exe that will do this and can be called in powershell easily.

Example below copies from windows to a CentOS box (logging in as the usercode "bill") and you use the -pw switch in pscp to pass in a password (otherwise the command window that is spawned will prompt for the Linux password):

Start-Process 'C:\Program Files (x86)\PuTTY\pscp.exe' -ArgumentList ("-scp -pw password C:\Document.rtf bill@192.168.0.28:/home/bill/")  

PuTTY Secure Copy client
Release 0.62
Usage: pscp [options] [user@]host:source target
       pscp [options] source [source...] [user@]host:target
       pscp [options] -ls [user@]host:filespec
Options:
  -V        print version information and exit
  -pgpfp    print PGP key fingerprints and exit
  -p        preserve file attributes
  -q        quiet, don't show statistics
  -r        copy directories recursively
  -v        show verbose messages
  -load sessname  Load settings from saved session
  -P port   connect to specified port
  -l user   connect with specified username
  -pw passw login with specified password
  -1 -2     force use of particular SSH protocol version
  -4 -6     force use of IPv4 or IPv6
  -C        enable compression
  -i key    private key file for authentication
  -noagent  disable use of Pageant
  -agent    enable use of Pageant
  -batch    disable all interactive prompts
  -unsafe   allow server-side wildcards (DANGEROUS)
  -sftp     force use of SFTP protocol
  -scp      force use of SCP protocol
Martin Prikryl
  • 188,800
  • 56
  • 490
  • 992
Graham Gold
  • 2,435
  • 2
  • 25
  • 34
  • 3
    Use key based auth instead of putting the password in your script. – slestak Nov 18 '13 at 19:01
  • Fair point, this was just a quick example to show that PSCP could do the job requested :-) – Graham Gold Nov 20 '13 at 13:37
  • 1
    Windows noob here. When I do this, I just get a blank console window that disappears after about 10 seconds, and the SCP transfer does not appear to have occurred. Any ideas as to what might be going on? – jayhendren Oct 19 '17 at 21:41
  • I was able to figure out that there was a firewall issue by running the command from Command Prompt instead of Powershell, but it would be nice if there were some way of getting output from running the command in Powershell :) – jayhendren Oct 19 '17 at 21:49
  • @jayhendren from the doc at https://the.earth.li/~sgtatham/putty/0.60/htmldoc/Chapter5.html - pscp returns an error code. So immediately after the started process completes, check the value of $lastexitcode or put the result of your start-process statement into a variable then check that - e.g $result = Start-Process – Graham Gold Oct 20 '17 at 02:04
  • @jayhendren $result=start-process ‘C:\Program Files (x86)\PuTTY\pscp.exe’ -argumentlist ... – Graham Gold Oct 20 '17 at 02:11
  • @jayhendren you could also try the -v switch in your pscp argumentlist and also the -sshlog option - it is available in plink.exe so May be in pscp also – Graham Gold Oct 20 '17 at 02:22
10

pscp.exe is a viable option, but I have been using a library from Rebex for a couple years now for SFTP and FTPS transfers in both C# apps and PowerShell scripts with great success. Their package also includes an SCP object but I haven't personally used it.

It does cost money vs. pscp being free. Before selecting the Rebex package, I had considered going the PuTTY route but my team decided that having a library we could easily roll into any app/script was worthwhile in the long term.

alroc
  • 27,574
  • 6
  • 51
  • 97
6

You can use WinSCP .NET assembly from PowerShell for SCP transfers.

For example see http://winscp.net/eng/docs/library_powershell#example

The example uses SFTP protocol. To use SCP, just modify it to:

$sessionOptions.Protocol = [WinSCP.Protocol]::Scp

Though if your server support SCP protocol, it's likely it also supports SFTP. SFTP is better choice, if you have the option.

Martin Prikryl
  • 188,800
  • 56
  • 490
  • 992
slestak
  • 153
  • 1
  • 8
3

Why use an alternative to SCP when you can use SCP?

Windows has OpenSSH (which includes SCP) as an optional component these days, so you could just use that. It first appeared in the Autumn 2018 version of Windows 10. It's nearly identical to the command you find in most Linux distributions, as it's derived from the same code base. Microsoft just made one or two minor tweaks to make it work on windows.

It is simple to install just go to Start->Settings->Apps->Optional Features->View Features enter in OpenSSH in the search box and check the OpenSSH client and click next. See OpenSSH in Windows for more detailed instructions on how to set it up. For a more PowerShell way of installing it run this from an elevated PowerShell prompt:

Add-WindowsCapability -Online -Name OpenSSH.Client~~~~0.0.1.0

You can use this command to check if there is a newer version and whether you already have it installed:

Get-WindowsCapability -Online | Where Name -Like '*ssh*'

Once installed, you call scp from PowerShell just like you would any other executable command.

scp file.dat user.name@example.com:/target/path

If you really don't want to use SCP use Copy-Item

This requires PowerShell to be installed on your server. Yes you can install PowerShell on Linux. Just call Copy-Item with the -ToSession parameter passed an SSH connected session, I've never actually tried it though. It requires a recent version of PowerShell and some setting up see PowerShell remoting over SSH. Something like this:

Copy-Item C:\localPath\*.* ~\remotePath\ -ToSession (New-PSSession -HostName UserA@LinuxServer01:22 -KeyFilePath c:\\userAKey_rsa)

If both machines are Windows machines you can use the same -ToSession parameter to copy files over WinRM. But both machines have to be domain joined or there is the possibility of security issues.

Martin Brown
  • 24,692
  • 14
  • 77
  • 122
1

There is also a ".NET friendly" way:

you can use the SharpSSH dll to execute ssh commands, and do scp/sftp tranfers.

For example:

[Reflection.Assembly]::LoadFrom((Resolve-Path .\Tamir.SharpSSH.dll))

$ssh = New-Object Tamir.SharpSsh.Sftp("server","user","password")

$ssh.Connect()

$ssh.Put("C:\localfile","distantfile")

$ssh.Close()

There is the SSH.Net library, too, it does approximatively the same things.

Dzmitry Lahoda
  • 939
  • 1
  • 13
  • 34
plunkets
  • 510
  • 1
  • 6
  • 13