The File Transfer Protocol (FTP) is a common service used to transfer files between clients and servers. It’s often useful to automate these file transfers, and PowerShell scripts can come in handy to speed up this process.
How To Use FTP in PowerShell
There are a few different ways to make FTP transfers in PowerShell.
The simplest is to use WebClient.UploadFile. PowerShell is an object-oriented scripting language, and you have full access to .NET standard libraries with New-Object. With this, you can create a new WebClient, set the credentials for it, and upload a file.
This will work fine, but won’t be able to handle TLS/SSL encrypted requests, or make “active” FTP transfers. Using FtpWebRequest, covered below, will solve this problem.
It isn’t best practice to store your username and password in a script however, especially if that script is being committed to a shared Git repository. You can instead set environment variables like FtpUsername and access them in the script.
Making this into a function will also let you easily make multiple transfers by calling the function with different parameters.
Advanced FTP Transfers with PowerShell
If you need more control, you should use FtpWebRequest. This will support TLS transfers, and also allow you to turn passive mode off. The easiest way to use it is to open a file stream and copy it to the FTP stream.
Since it’s using file streams, and not reading all the bytes, this has the benefit of working better with huge file transfers.
Sending SFTP Transfers with Posh-SSH
SFTP is an alternate FTP protocol that operates over SSH. It’s a bit more complicated to use than regular FTP, since you can’t just send a username and password, and it’s not supported by native PowerShell.
You’ll need to install the Posh-SSH package to communicate over SFTP:
Then you’ll be able to start a new session, using a new credential object. This works in the same way as web request transfers, except you’ll also need to close the session at the end.
Sending Huge Files with a Progress Bar in PowerShell
Using the file stream’s CopyTo is simple, but for long transfers, you may want some kind of progress monitoring. This is a little complicated to add, since you’ll have to copy the streams yourself, but works well with the following script: