How to Build PowerShell Tools to Setup SFTP

When you use multiple machines running Windows, you may need to access shared resources by using different protocols. When a file share is created on a Windows machine, the SMB protocol is usually used. However, files can be shared on non-Windows machines by using NFS, FTP, SFTP, FTPS, SCP, and other protocols. If you’re using only PowerShell, for example, on Windows Server without a graphical interface, connecting to the SFTP share for the first time can seem difficult. This blog post explains how to use SFTP in Windows with PowerShell.

What is SFTP?

SFTP stands for SSH File Transfer Protocol or Secure File Transfer Protocol. SFTP is the secure alternative to the traditional File Transfer Protocol (FTP) with similar functionality. SFTP works on the application layer of the OSI model (layer 7), uses the SSH connection, and is especially popular on Linux machines that usually have a built-in command-line SFTP client. If you use Windows, install a free SSH client such as WinSCP, which has a GUI and supports more than just SFTP, or configure PowerShell tools if you need to use the command line. Windows and PowerShell don’t support SFTP natively, so additional components will need to be installed.

When using an SSH connection, data transfers over the network are encrypted and the connection is secure, unlike the traditional unencrypted FTP protocol where data can be intercepted by attackers. SSH is used for authentication, and if you have Linux user credentials, you can access files on a target Linux machine after passing authentication from your command line SFTP client or a GUI client. It also allows you to copy files from/to a remote Linux machine to your local Linux or Windows machine. Configuring the SFTP server on Linux is not difficult – you install the SSH server, create users, and grant the needed permissions for users and files/directories.

Don’t confuse SFTP and FTPS. These two protocols are used for similar purposes. However, SFTP uses one port number for a connection and FTPS uses multiple port numbers for control and data channels (which can be more difficult to configure from a security perspective including firewalls). FTPS is FTP with SSL (Secure Socket Layer). I don’t go into how to set up SFTP server in this blog post. Read about installing and configuring Linux (including the SSH server) on Hyper-V in here.

Installing the Posh-SSH Module

In order to perform operations with files (copying files, deleting files) on remote machines by using SFTP and SCP in PowerShell, you have to install the Posh-SSH module in PowerShell. Installing this module also allows you to run remote commands on a remote computer by using the SSH session. PowerShell 3.0 and .NET Framework 4.0 are required to install and use Posh-SSH. Thus, you can install this module on Windows 8 or newer Windows versions. You can also manually update PowerShell and .NET Framework on Windows 7 SP1. Run this command to install the PowerShell SFTP module (Posh-SSH):

install-module posh-ssh

Posh PowerShell – installing the PowerShell SFTP module

As an alternative, you can use this command to install the Posh-SSH module for PowerShell:

iex (New-Object Net.WebClient).DownloadString(“https://gist.github.com/darkoperator/6152630/raw/c67de4f7cd780ba367cccbc2593f38d18ce6df89/instposhsshdev”)

An Internet connection is required to install Posh-SSH with the above commands. In my case, I have installed the Posh-SSH module in PowerShell and can move to the next configuration steps.

Connecting to a Remote Host in PowerShell

In this blog post, I’m using an environment with a local Windows machine and remote Linux machine, which are connected to the same network:

  • 192.168.101.210 is a local Windows machine with Windows 10 version 20H2 installed
  • 192.168.101.209 is a remote Linux machine on which the SSH (SFTP) server is running
  • user1 is the name of the Linux user

These IP addresses are used in my examples. Enter your IP addresses and credentials in the appropriate commands and configuration files.

Let’s check our SFTP share by connecting to the Linux server via SFTP by using WinSCP, the free SFTP client for Windows. Connecting to an SFTP server is straightforward. Enter the IP address of the target host, port number (TCP 22 is the default port number but you can configure an SSH server to use a custom port number), user name, and password to connect. Don’t forget to select the SFTP protocol.

How to use SFTP – connecting to a remote machine in WinSCP

SFTP connection works in my case. We have copied two files to the shared folder (the location of the files is /home/user1/shared/ on the remote Linux machine). Let’s look at how to connect to the shared folder from Windows and how to use SFTP with Posh-SSH in PowerShell.

How to use SFTP in Windows

To work with files via SFTP, you should establish a session first. In order to do this, run this command in PowerShell:

New-SFTPSession -Computername 192.168.101.209

The authentication window is displayed after running the command. Enter a username and password to access the remote Linux machine with the files you need to access via SFTP. If you have entered the correct credentials, you should see the PowerShell output with the information about the SFTP session number, IP address of the remote host, and connection status. Once a session is created, an index number is assigned to the session.

How to use SFTP in PowerShell – connecting to a server and creating a new session

You can always enter the help command with the appropriate arguments to display the short help info about the syntax for using PowerShell commands:

help New-SFTPSession

List all available posh PowerShell commands:

Get-Command -Module Posh-SSH

or

Get-command -Name * -module *posh-ssh

Here is the method to create an SSH session that allows you to run a command on a remote host, for example, to list files in the directory:

Import-Module Posh-SSH

$SSHSession = New-SSHSession -ComputerName 192.168.101.209 -Credential $(Get-Credential) -Verbose

$SSH = $SSHSession | New-SSHShellStream

Invoke-SSHCommand -Index 0 -Command “ls -l /home/user1/shared”

PowerShell SFTP – listing files in a directory of an SFTP server

Creating a PowerShell Script

Let’s create a test script to explore the basic operations that you can perform in PowerShell when working with SFTP resources. This is not an SFTP script, this is a PowerShell script to work with SFTP. This test script should copy the .NET Framework installer file from a remote Linux machine to a local Windows machine.

Create a test-PS.ps1 script file with the content displayed below.

#Creating a folder to store files downloaded from the SFTP share

New-item -itemtype directory -force -path c:\temp\ps

#Setting credentials for the user account

$password = ConvertTo-SecureString “My_Password000” -AsPlainText -Force

$creds = New-Object System.Management.Automation.PSCredential (“user1”, $password)

#Establishing an SFTP session

$Session = New-SFTPSession -Computername 192.168.101.209 -credential $creds

#Downloading the .NET installer file by using the established SFTP session

Get-SFTPFile -SessionId $session.SessionID -RemoteFile /home/user1/shared/NetFrameworkNDP462.exe -LocalPath c:\temp\ps

Open PowerShell on a Windows machine, go to the folder where this test script is stored, and run the script

.\test-PS.ps1

The NetFrameworkNDP462.exe file should be copied from /home/user1/shared/ (on a remote Linux machine) to C:\temp\ps\ (on a local Windows machine). As you can see on the screenshot below, the file is copied successfully in my case.

PowerShell SFTP – copying a file from an SFTP server in PowerShell

In order to list files in a directory in the SFTP resource, you can create a PowerShell script with the following content:

$passwordTest = “Your_Password000”

$securePasswordTest = ConvertTo-SecureString $passwordTest -AsPlainText -Force

$credentialsTest = New-Object System.Management.Automation.PSCredential (“user1”, $securePasswordTest)

$sessionTest = New-SFTPSession -ComputerName 192.168.101.209 -Credential $credentialsTest -AcceptKey

$sourceTest = “/home/user1/shared/”

$destinationTest= “c:\temp\ps\”

Get-SFTPChildItem -Recursive $sessionTest -Path $sourceTest | ForEach-Object{

   if ($_.Fullname -like ‘*.csv’)

   {

      Get-SFTPFile $sessionTest -RemoteFile $_.FullName -LocalPath $destinationTest -Overwrite

   }

   write-output $_.FullName

}

Remove-SFTPSession $sessionTest -Verbose

Where:

Your_Password000 is the password for the user account used to connect via SSH to the SFTP share;

user1 is the name of the user;

192.168.101.209 is the IP address of the remote host to which we connect to access files via SFTP.

Save the script as list-files.ps1 and run this script in PowerShell on your local machine from a folder where this script file is stored.

.\list-files.ps1

Pay attention to the -Recursive parameter defined in the test script. On the screenshot below you can see the results for using the -Recursive parameter and without this parameter.

How to use SFTP in PowerShell – checking contents of a directory on a remote server

One of the disadvantages of running scripts such as those shown in the examples above is that credentials are stored in the plain text of a script, which is not secure. A user who can open a script (even with read-only permissions) can see a password and use this password for unauthorized access.

There is a method to improve the level of security and store a password in the encrypted view in a file. Windows Data Protection API is used to encrypt a password, which can only be accessed from the user account and computer used to create this password file.

(get-credential).password | ConvertFrom-SecureString | set-content “C:\temp\password.txt”

How to use SFTP in PowerShell – saving an encrypted password to a file

Then the password is saved in the encrypted form in the text file. If somebody sees the content of this file, the password is not displayed as plain text.

A password for an SFTP user account is encrypted and saved in the text file

When you need to enter the password, define the file with a saved encrypted password (C:\temp\password.txt in our case).

$password = Get-Content “C:\temp\password.txt” | ConvertTo-SecureString

$credential = New-Object System.Management.Automation.PsCredential(“user1”,$password)

This method of defining a password is more secure. You can modify your script in which you defined the password. As an alternative to opening a script in a text editor, you can right-click the ps1 file and in the context menu click Edit.

PowerShell SFTP automation – editing a script file

Windows PowerShell ISE is opened. This is a native Windows tool that colorizes syntax for more convenience and displays the available PowerShell commands in the right pane.

SFTP script editing for running in PowerShell

Commands in the test script are now as follows:

New-item -itemtype directory -force -path c:\temp\ps

$password = Get-Content “C:\temp\password.txt” | ConvertTo-SecureString

$creds = $credential = New-Object System.Management.Automation.PsCredential(“user1”,$password)

$Session = New-SFTPSession -Computername 192.168.101.209 -credential $creds

Get-SFTPFile -SessionId $session.SessionID -RemoteFile /home/user1/shared/NetFrameworkNDP462.exe -LocalPath c:\temp\ps

You can modify your script again and set it to execute the downloaded installer file on the Windows machine. The command to install .NET Framework in the quiet mode (from the directory where the installer file is located) is:

.\NetFrameworkNDP462.exe /q /norestart

Enter the name of your installation file if the name is different.

Add the line at the end of the script:

Start-process “C:\temp\ps\NetFrameworkNDP462.exe” -argumentlist /q /norestart

If you want to delete the installation file after installation finishes, consider adding this line at the end of the script:

remove-item -path “C:\temp\ps\NetFrameworkNDP462.exe” -recurse -force

Using PowerShell and Posh-SSH allows you to automate operations in PowerShell using the SFTP protocol to copy files between hosts in the network. You can create a script for downloading files and executing them to save time when you need to perform mass installation of software on a large number of computers.

Conclusion

Now you can copy files to/from Linux machines via SFTP if an SSH server is configured on Linux machines. Posh-SSH is a PowerShell module that is required to use SFTP on Windows machines from which you want to access remote SFTP servers and perform SFTP automation tasks. PowerShell and SFTP can be used by managed service providers and system administrators in organizations.

PowerShell is often used to manage Hyper-V virtual machines and VMware virtual machines (in PowerCLI). Remember to back up Hyper-V virtual machines. Just as PowerShell is used to automate running commands, NAKIVO Backup & Replication automates VM backup and provides many additional data protection features. Moreover, the product supports installation in multi-tenant mode, which is especially useful for managed service providers. Download the Free Edition of NAKIVO Backup & Replication and start protecting your virtual and physical machines today.

People also read