PowerShell How-To
How To Transfer Files via SCP with PowerShell
- By Adam Bertram
- 07/19/2018
Native support for Secure Copy Protocol (SCP) isn't in PowerShell, but that doesn't mean it's not capable. By using a free community module called Posh-SSH, we can transfer files via SCP just as quickly as we can with Copy-Item.
The module we need to use is called Posh-SSH. This module is available on the PowerShell Gallery and can be installed by running Install-Module -Name Posh-SSH. Once installed, you should have a few dozen different commands available around SSH, SCP and SFTP. In this article, we're going to stick with SCP.
The best use case for using SCP and PowerShell is when you have a remote Linux host that you need to transfer files to and from. Since most Linux distributions have native SSH support and SCP usually just works, SCP is an easy-to-use method to transfer files back and forth.
To use SCP with the Posh-SSH module, we first need to save the user name and password as a PSCredential in PowerShell. We'll use this to authenticate to the remote host.
$credential = Get-Credential
Once you have a credential saved, and perhaps you have an entire folder of files you'd like to download, you can use the Get-SCPFolder command specifying the local folder to transfer all of the files from the remote folder into.
Get-SCPFolder -ComputerName 'SCPSERVERHERE' -Credential $credential -LocalFolder 'C:\MyFolder' -RemoteFolder '/someLinuxFolder'
Perhaps you just want to download a single file from the remote host. In that case, you can use the Get-ScpFile command, and instead of using folder parameters, you can use file parameters instead.
Get-SCPFile -ComputerName 'SCPSERVERHERE' -Credential $credential -RemoteFile "/someLinuxFolder/file" -LocalFile 'C:\MyFolder\file'
One item to note, though, is if you're going to be transferring text files from a Windows host to a Linux host, you may run into a situation where the encoding on the file gets screwed up. The text is stored differently on a Linux versus Windows system. If you find the text looks changed when the file is downloaded onto a Windows host, you can create a duplicate copy of the text using the Out-File PowerShell command using the Encoding parameter.
Get-Content -Path 'C:\MyFolder\file' | Out-File -Encoding utf8 -Path 'C:\MyFolder\fileWindows'
As with downloading, we can also go the other way and upload files to a remote Linux host, as well, via SCP. For these duties, we can use Set-ScpFolder and Set-ScpFile. These commands work the same as the Get commands but merely send files rather than retrieving them.
Here are some examples of sending a folder or a single file to a remote host via SCP. You can see that the parameters are nearly identical, which makes it easy to switch back and forth between downloading and uploading.
Set-SCPFile -ComputerName 'SCPSERVERHERE' -Credential $credential -RemotePath '/someLinuxFolder/file' -LocalFile 'C:\MyFolder\file'
Set-SCPFolder -ComputerName 'SCPSERVERHERE' -Credential $credential -LocalFolder 'C:\MyFolder' -RemoteFolder '/someLinuxFolder'
Even if PowerShell doesn't have the native ability to perform a task, always look at the community modules via the PowerShell Gallery. Chances are, you'll be able to find a module that's already been built that does everything you need. For SCP, I recommend taking a look at the Posh-SSH module.
About the Author
Adam Bertram is a 20-year veteran of IT. He's an automation engineer, blogger, consultant, freelance writer, Pluralsight course author and content marketing advisor to multiple technology companies. Adam also founded the popular TechSnips e-learning platform. He mainly focuses on DevOps, system management and automation technologies, as well as various cloud platforms mostly in the Microsoft space. He is a Microsoft Cloud and Datacenter Management MVP who absorbs knowledge from the IT field and explains it in an easy-to-understand fashion. Catch up on Adam's articles at adamtheautomator.com, connect on LinkedIn or follow him on Twitter at @adbertram or the TechSnips Twitter account @techsnips_io.