All posts

PowerShell: Implementing SFTP in a Script.

The idea for this simple project originates from a situation I encountered while creating a lab to implement a Cisco Firepower Threat Defense appliance on EVE-NG. The lab required me to upload the FTD image to the fil…

PowerShell: Implementing SFTP in a Script.

This article outlines how to perform a secure file transfer using PowerShell, which requires the use of the WinSCP module available from the PowerShell Gallery. I also wanted to cover SFTP and explain why I chose it over FTPS.

The idea for this simple project originates from a situation I encountered while creating a lab to implement a Cisco Firepower Threat Defense appliance on EVE-NG. The lab required me to upload the FTD image to the file location “/opt/unetlab/addons/qemu/firepower6-FTD_6.6.4” on the EVE-NG virtual machine, which is not a straightforward process. I am a Robocopy kind of guy, but that is only useful for moving files between Windows machines and shares. In this case, I wouldn’t be able to use it to copy the file to a Linux machine. The simple solution that I chose at the time was to install WinSCP and use its GUI to make the transfer. All I had to do was authenticate to the Linux box, and WinSCP did the rest. However, what if I wanted to implement similar functionality in a script I was developing? That’s how I arrived at this article.

To briefly summarize, the Secure File Transfer Protocol (SFTP) is a standardized networking protocol that extends from SSH and provides many file management features. One of the benefits of using SFTP is that it uses only one port/stream, eliminating the need for multiple connections like FTPS. Also its implementation in PowerShell is easy, as you’ll see now.

To start, we need to install the WinSCP module using the Install-Module cmdlet:

Install-Module -Name WinSCP

You may receive a warning stating “You are installing the modules from an untrusted repository. If you trust this repository, change its InstallationPolicy value by running the Set-PSRepository cmdlet. Are you sure you want to install the modules from ‘PSGallery’?” As long as the repository states PSGallery, you can press Y or A to continue.

Next, we will build the script. For this script, we want to prompt for the full file paths for the source file and destination directory. We will then prompt for credentials and securely handle them before performing the file transfer. The WinSCP module allows us to implement SFTP, and that is what we will do.

First, we will import the module and prompt for some options, as shown below.

# Import the WinSCP Module
Import-Module WinSCP

# Prompt for source file path
$SourceFilePath = Read-Host -Prompt "Source File Path (Ex: C:\Windows\explorer.exe): "

# Prompt for destination directory path
$DestinationDirectoryPath = Read-Host -Prompt "Destination Directory Path (Ex: /var/opt): "

# Prompt for server/host IP
$DestinationHost = Read-Host -Prompt "Destination IP: "

Next, we will get the credentials to authenticate securely using the Get-Credentials cmdlet, which will keep our username and password in a secure object. This is the easiest and safest method for handling credentials.

# Prompt for credentials, these will be stored securely
$Credentials = Get-Credential

Now, we get to the WinSCP section.

WinSCP supports five different protocols: SFTP, SCP, FTP, WebDAV, and S3. For our script, we will use SFTP.

We first need to create a session options object, which will allow us to specify options such as the protocol and the hostname/IP we will reach out to. We will also pass in the secured credentials and set the option to auto-accept the SSH certificate. Although this is generally not recommended, it is fine since this script will be used internally. If you were reaching out over the internet, you could use another option and specify the fingerprint.

Our session options object should look something like this:

# Set WinSCP options, specify protocol, host and credentials to be used, we also specify the GiveUpSecurityAndAcceptAnySshHostKey option to auto accept the SSH key, you can secify one if you would like.
$Options = New-WinSCPSessionOption -HostName $DestinationHost -Protocol Sftp -Credential $Credentials -GiveUpSecurityAndAcceptAnySshHostKey

Once we have specified our options, we can create the session:

# Create SFTP session
New-WinSCPSession -SessionOption $Options

The following code block demonstrates how to transfer a file using the Send-WinSCPItem cmdlet:

# Send File Now
Send-WinSCPItem -Path $SourceFilePath -Destination $DestinationDirectoryPath

Finally, you can end the session using the Remove-WinSCPSession cmdlet, as shown below:

# Discard the session
Remove-WinSCPSession

If the file transfer was successful, you will see a message indicating such in the PowerShell shell. This is how you can implement SFTP in a PowerShell script in a simple manner.

Here is the full script:

# Import the WinSCP Module
Import-Module WinSCP

# Prompt for source file path
$SourceFilePath = Read-Host -Prompt "Source File Path (Ex: C:\Windows\explorer.exe): "

# Prompt for destination directory path
$DestinationDirectoryPath = Read-Host -Prompt "Destination Directory Path (Ex: /var/opt): "

# Prompt for server/host IP
$DestinationHost = Read-Host -Prompt "Destination IP: "

# Prompt for credentials, these will be stored in a secure fashion
$Credentials = Get-Credential

# Set WinSCP options, specify protocol, host and credentials to be used, we also specify the GiveUpSecurityAndAcceptAnySshHostKey option to auto accept the SSH key, you can secify one if you would like.
$Options = New-WinSCPSessionOption -HostName $DestinationHost -Protocol Sftp -Credential $Credentials -GiveUpSecurityAndAcceptAnySshHostKey

# Create SFTP session
New-WinSCPSession -SessionOption $Options

# Send File Now
Send-WinSCPItem -Path $SourceFilePath -Destination $DestinationDirectoryPath

# Discard the session
Remove-WinSCPSession

Discussion

No comments yet