If you want to use SFTP or SCP to download files with PowerShell, you need third-party software such as Posh-SSH or the WinSCP PowerShell module.

In a previous post I demonstrated how you can download files with the Invoke-WebRequest cmdlet. This method is fine if you only have to download a single file from a webserver. However, if you often want to securely transfer a large number of files through the Internet, SFTP and SCP are better options. I tested two third-party PowerShell modules for this purpose: Posh-SSH and WinSCP.

Download with SFTP and SCP using the Posh-SSH module ^

Posh-SSH is a free module that provides basic SSH functionality in PowerShell. Among other things, you can use it to download files through SFTP and SCP. To install the module, we can use Invoke-WebRequest to download the install script that we pipe to Invoke-Expression:

wget https://gist.github.com/darkoperator/6152630/raw/c67de4f7cd780ba367cccbc2593f38d18ce6df89/instposhsshdev | iex

Installing Posh-SSH

Installing Posh-SSH

This downloads all the necessary files from the GitHub repository to your Windows PowerShell modules folders in your Documents directory. The module comes with a variety of cmdlets that enable you to deal with SSH connections using PowerShell.

The Get-SFTPFile cmdlet allows you to download via SFTP. To do so, you first have to establish an SFTP session with the module’s New-SFTPSession cmdlet:

$Credentials = Get-Credential
$Session = New-SFTPSession -ComputerName "mySFTPserver" -Credential $Credentials 
Get-SFTPFile -SFTPSession $Session -RemoteFile "/path/file" -LocalPath "C:\path\"

Unlike Invoke-WebRequest, you can’t just pass the user name with the -Credential parameter. You first have to create a PSCredential object with Get-Credential.

To download an entire folder with its subfolders, you need the Get-SCPFolder cmdlet. In this case, you don’t have to create an SFTP session first:

$Credentials = Get-Credential
Get-SCPFolder -ComputerName "mySFTPserver" -Credential $Credentials -LocalFolder "C:\path\" -RemoteFolder "/folder"

Posh-SSH also supports public key authentication. I will demonstrate this with the Get-SCPFile cmdlet that allows you to download files via the SCP protocol:

Get-SCPFile -ComputerName "mySSHserver" -Credential $Credentials -Key "myPrivateKeyFile"-RemoteFile "/path/file" -LocalFile "C:\path\file"

The private key is an OpenSSH key. On a Linux machine, you would generate the corresponding key pair with ssh-keygen -t rsa. The public key has to be stored on the host in the authorized_keys file in the user’s .ssh folder.

Note that you have to specify the local file name. Otherwise, Get-SCPFile will throw this error:

Get-SCPFile : Could not find a part of the path

If you secured the private key with a passphrase, you have to store the passphrase in the password property of the PSCredential object. If the private key has no passphrase, you simply leave the password field empty in the credentials dialog window and only enter the user name.

A downside of Get-SCPFile compared to Get-SFTPFile is that it doesn’t automatically convert text files from the UNIX format to the Windows format. Thus, if you download a text file from a Linux machine and open it in a text editor in Windows, all line breaks will be missing.

You can convert from the UNIX format to the Windows format with this command:

Get-Content "UnixFile" | Out-File -Encoding utf8 "WindowsFile"

But that’s a bit cumbersome. If you want to work with SCP in PowerShell, the WinSCP module might be a better option than Posh-SSH.

Download via SCP using the WinSCP module ^

WinSCP is a popular, free, GUI-based SFTP and SCP tool for Windows. The corresponding PowerShell module uses the WinSCP assemblies to provide SCP functionality in PowerShell. Note that the PowerShell cmdlets were created by different developers.

To install the module, I recommend that you first install PsGet with this command:

wget http://psget.net/GetPsGet.ps1 | iex

Then, you can install the WinSCP module from GitHub with this command:

Install-Module -ModuleUrl "https://github.com/dotps1/WinSCP/raw/master/WinSCP.zip" -ModuleName WinSCP -Type ZIP

Installing the WinSCP PowerShell module

Installing the WinSCP PowerShell module

This will also install the required assemblies. After you install the module, it will be automatically imported into your PowerShell session. However, because the WinSCP module doesn’t support module autoloading, you have to import the module manually with Import-Module WinSCP whenever you launch PowerShell. Alternatively, you can import the module into your PowerShell profile.

The following lines demonstrate how to download via SCP:

$Options = New-WinSCPSessionOptions -Hostname "mySSHserver" -UserName "User" -Password "Password" -GiveUpSecurityAndAcceptAnySshHostKey
$Session = Open-WinSCPSession -SessionOptions $Options
Receive-WinSCPItem -WinSCPSession $Session -RemotePath "/path/file" -LocalPath "C:\path\"
Close-WinSCPSession -WinSCPSession $Session

In the example, the password appears in clear text, which is not nice. To improve security, the New-WinSCPSessionOptions cmdlet also allows you to pass the password as a secure string:

$SecureString = Read-Host -AsSecureString
$Options = New-WinSCPSessionOptions -Hostname "mySSHserver" -UserName "User" -SecurePassword $SecureString -GiveUpSecurityAndAcceptAnySshHostKey
$Session = Open-WinSCPSession -SessionOptions $Options
Receive-WinSCPItem -WinSCPSession $Session -RemotePath "/path/file" -LocalPath "C:\path\"
Close-WinSCPSession -WinSCPSession $Session

The first command prompts you to enter the password and creates a SecureString object. If you want to avoid being prompted for the password and also don’t want to store the password in clear text in your script, you should read my article about the credentials in PowerShell or, better yet, work with public key authentication (see below).

I like the name of the -GiveUpSecurityAndAcceptAnySshHostKey parameter. It seems the developer is equipped with a good sense of humor. If you don’t want to “give up security,” you have to use the ‑SshHostKeyFingerprint parameter instead of -GiveUpSecurityAndAcceptAnySshHostKey.

Providing the SSH public key fingerprint of the host ensures that your scripts connect to the right server and prevents man-in-the-middle attacks. The administrator of the remote host should be able to give you the key. If you are the admin, you can get the key on most Linux machines with this command:

ssh-keygen -l -f /etc/ssh/ssh_host_rsa_key

You then have to pass the fingerprint in this format: "ssh-rsa 2048 xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx".

By the way, this feature is another advantage of the WinSCP module compared to Posh-SSH. The latter prompts you to accept the fingerprint when you first connect to the remote host. This can cause problems in scripts.

The WinSCP module also supports SSH public key authentication, which is certainly the preferred method for connecting to an SSH server. However, you must configure the SSH server accordingly.

When I tried to authenticate with my key (that worked perfectly with Posh-SSH) using the WinSCP module, I received this error message:

Connection has been unexpectedly closed. Server sent command exit status 0.

On an SSH server that didn’t support password authentication (only public key authentication), Open-WinSCPSession returned an error message that was a little more revealing:

Disconnected: No supported authentication methods available (server sent: publickey)

It appeared that the SSH server didn’t like my private key. I then remembered that WinSCP uses the PuTTY format for the private key instead of the OpenSSH format. Of course, this also applies to the PowerShell module because it uses the same assemblies. To convert a private OpenSSH key to the PuTTY format, you can use PuTTYgen. The public key on the server doesn’t have to be modified.

The following example demonstrates how you can use public key authentication with the WinSCP PowerShell module:

$Options = New-WinSCPSessionOptions -Hostname "mySSHserver" -UserName "User" -SshPrivateKeyPath "PrivatePuTTYkey.ppk" -SshPrivateKeyPassphrase "Passphrase" -SshHostKeyFingerprint "ssh-rsa 2048 xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx"
$Session = Open-WinSCPSession -SessionOptions $Options
Receive-WinSCPItem -WinSCPSession $Session -RemotePath "/path/file" -LocalPath "C:\path\"
Close-WinSCPSession -WinSCPSession $Session

If you used a passphrase for the private key, you have to pass it in clear text. The WinSCP module doesn’t offer a parameter that would allow you to pass the passphrase as a secure string. So you have to “give up a little security” at this point.

Do you know of other PowerShell modules that allow you to download files with SFTP and SCP?

  1. jim blanford 7 years ago

    “Use” or “Using”

  2. Michael Pietroforte 7 years ago

    Corrected it. Thanks for the hint! 🙂

  3. dops1 7 years ago

    Just and FYI, i have majorly overhauled this module since the time of this writing. I have give hours of effort to follow best practices of the PSScriptAnalyzer community, and as such, cmdlet names/parameter names have changed. This module is still ‘Beta’ and i have not officially released it, so there is not any aliases created or backwards compatibility. You can still however get the orginal version from the PowerShell Gallery, the version is 5.7.4. but everything above that version ( at the time of this writing) will have the new framework. Some of the added functionality is things like ‘Get-WinSCPChildItem’ with mimics the native cmdlet ‘Get-ChildItem’. It also has a -Recurse switch as well as a -Filter switch. and, i am not done, there will be much more to come. Thanks!

  4. Michael Pietroforte 7 years ago

    Thanks for the hint. If you notify me once the new version ready, I might review it again.

  5. hemanth 2 years ago


    how to download directories from Unix server to local system in binary mode.

Leave a reply

Your email address will not be published.


© 4sysops 2006 - 2022


Please ask IT administration questions in the forums. Any other messages are welcome.


Log in with your credentials


Forgot your details?

Create Account