Thursday, February 28, 2013

SFTP in PowerShell

Hi All,

A while ago we where migrating customers from our old FTP server to our brand new SFTP server :-)
But one of those customers had an automated script(PowerShell) in place uploading files during the night.
So we where searching for an solution to script SFTP uploads(which wasn't easy).
There are a few payed solutions for implementing SFTP capability`s in PowerShell and you can also use application like WinSCP to "fake" SFTP capability`s.
But i thought it would be nice if someone created an free PowerShell Snap-In that implements SFTP capability`s.

At this point I went in search for an open-source SFTP implementation for C#, I came across an open-source library that I used before(SharpSSH).
This library was the perfect candidate to embed in the PowerShell Snap-In.
So after some coding this was what i came up with : Download SFTP PowerShell Snap-In

I can present this Snap-In to you with many thanks to Tamir Gal and Will Fitch, these two guy`s created the great SharpSSH library on which the Snap-In is based !

Kind Regards,
Kevin

P.S.
Sample scripts to show you how the Snap-In works are included in the zip file. ;-)


==== UPDATE-2 16-4-2012 =====
Hi All,


I`m now in the testing phase of version 2 of the Snap-In.
Who would like to help and test it ?
You can download the v2-beta here !
There now is an extra CmdLet named Open-SFTPServerWithPublicKey which as the obvious name states allows you to authenticate with a public private key pair :-)
Please note that the private key must be in OpenSSH format and you must provide the full path to the file!

==== UPDATE 16-4-2012 =====
Hi All,

I uploaded a new version of the Snap-In, lets call it uhmmm v1.3 :-)
It includes port selection and PowerShell 3 support.
To get PowerShell 3 support i had to update the installer to include the right InstallUtil(With thanks to Rich Harrington).


==== UPDATE 15-4-2012 =====
Hi All,

I`m currently working on version 2 of the snap-in.
It`s going to include support for public-key authentication.
If there are any other feature requests please leave a comment.

32 comments:

  1. HA! I was just looking for something like this. I thought "I should leave a comment thanking this guy, but its probably old and he doesn't even pay attention." Then I looked at the date it was posted, TODAY! Thanks a bunch dude!!!

    ReplyDelete
    Replies
    1. Im glad i could be of some help!
      If you have issues or suggestions i will help where ever ik can

      Delete
    2. Kevin,
      Thanks for the example, but I am getting the following error: "Method invocation failed because [Tamir.SharpSsh.jsch.JSchException] doesn't contain a method named 'Close'.
      At R:\software-share-ftp\Powershell SFTP Snap-in\Sample Scripts\SFTP Check Connection Sample.ps1:22 char:12
      + $sftp.Close <<<< ()
      + CategoryInfo : InvalidOperation: (Close:String) [], RuntimeException
      + FullyQualifiedErrorId : MethodNotFound"

      I see that you have the same $sft5p.close() in each of your examples. I am not sure what I need to change.
      Thanks,
      John

      Delete
    3. Hi John,

      I've checked the sources i put online and ran the script myself but i don`t get the exception you`re describing.
      Can you confirm that the assembly`s are installed correctly ?
      If so can you tell me what the systems configuration looks like ?

      Kind Regards,
      Kevin

      Delete
    4. By system configuration i meant PowerShell version, .Net Framework version, OS version, etc.

      Thanks in advance :)

      Delete
    5. Thanks for your quick reply,
      At the Powershell prompt, when I type the following: "get-pssnapin -name ktools.powershell.sftp"; it shows the Name, PSVersion, and Description as I would expect.

      I am running on Powershell v2, .Net Framework 2.0., Windows 7, 64 bit.

      Delete
    6. That's strange. The Function you're calling is in the assembly that I put online. Could you please check if you by any chance have another version of the Tamir.SharpSSH.dll in your GAC ? (%WINDIR%\assembly)

      Delete
    7. Hello Kevin,

      I am getting the same error when I use the check connection template and I think this may have something to do with the Server. Could it be the error comes up when the FTP Server is not an SFTP Server ? :

      Method invocation failed because [Tamir.SharpSsh.jsch.JSchException] doesn't contain a method named 'Close'.
      At line:19 char:12
      + $sftp.Close <<<< ()
      + CategoryInfo : InvalidOperation: (Close:String) [], RuntimeException
      + FullyQualifiedErrorId : MethodNotFound

      Delete
    8. Hi Mosquito,

      The Snap-In does not support FTP but windows already has native support for that via ftp.exe
      But FTP support will be available in the RC1 release of v2 soon(within 2 weeks) along with other bug fixes and feature requests.

      Regards,
      Kevin

      Delete
  2. Hi.
    First of all, great work! Would it be possible to make a script that can upload an file to multiple sftp hosts at the same time?
    What would that look like?

    ReplyDelete
    Replies
    1. Hi,

      I guess you could do it something like this :

      #Add the SFTP snap-in
      Add-PSSnapin KTools.PowerShell.SFTP

      #Define some variables
      $sftpHost1 = "sftp.server1.com"
      $userName1 = "yourUserName1"
      $userPassword1 = "yourPassword1"

      $sftpHost2 = "sftp.server2.com"
      $userName2 = "yourUserName2"
      $userPassword2 = "yourPassword2"

      $localFile = "C:\The\File\You\Have.txt"

      #Open the SFTP connections
      $sftp1 = Open-SFTPServer -serverAddress $sftpHost1 -userName $userName1 -userPassword $userPassword1
      $sftp2 = Open-SFTPServer -serverAddress $sftpHost2 -userName $userName2 -userPassword $userPassword2

      #Upload the local file to the root folder on the SFTP server
      $sftp1.Put($localFile)
      $sftp2.Put($localFile)

      #Close the SFTP connection
      $sftp1.Close()
      $sftp2.Close()

      But I don`t know if this is what you meant :-)

      Regards,
      Kevin

      Delete
  3. Hi Kevin

    Great script but under Windows 8 it spits out this error:

    PS C:\Users\me> Add-PSSnapin KTools.PowerShell.SFTP
    Add-PSSnapin : Cannot load Windows PowerShell Snap-In KTools.PowerShell.SFTP because of the following error: Could not load file or assembly 'file:///C:\Program
    Files\KTools\KTools.PowerShell.SFTP\bin\KTools.PowerShell.SFTP.dll' or one of its dependencies. Operation is not supported. (Exception from HRESULT: 0x80131515)
    At line:1 char:1
    + Add-PSSnapin KTools.PowerShell.SFTP
    + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo : InvalidData: (KTools.PowerShell.SFTP:String) [Add-PSSnapin], PSSnapInException
    + FullyQualifiedErrorId : AddPSSnapInRead,Microsoft.PowerShell.Commands.AddPSSnapinCommand



    However it works fine in Windows 2008R2 / PS2.0. Any ideas?


    Many thanks

    James

    ReplyDelete
    Replies
    1. Hi James,

      Thats odd. Can you confirm that all the assebly`s are present under "C:\Program
      Files\KTools\KTools.PowerShell.SFTP\bin" ?
      The following files should be there :

      DiffieHellman.dll
      KTools.PowerShell.SFTP.dll
      Org.Mentalis.Security.dll
      Tamir.SharpSSH.dll

      If that is not the issue could you try to start powershell with admin priveliges or you could try to start powershell with the "-version 2" parameter.

      To start powershell that way you can go into the command prompt and run "powershell -version 2"

      Kind Regards,
      Kevin

      Delete
    2. Having the same issue (win7 x64)
      Files:
      DiffieHellman.dll
      KTools.PowerShell.SFTP.dll
      KTools.PowerShell.SFTP.InstallLog
      KTools.PowerShell.SFTP.InstallState
      Org.Mentalis.Security.dll
      Tamir.SharpSSH.dll

      Logs:
      KTools.PowerShell.SFTP.InstallLog
      Installing assembly 'C:\Program Files\KTools\KTools.PowerShell.SFTP\bin\KTools.PowerShell.SFTP.dll'.
      Affected parameters are:
      assemblypath = C:\Program Files\KTools\KTools.PowerShell.SFTP\bin\KTools.PowerShell.SFTP.dll
      logfile = C:\Program Files\KTools\KTools.PowerShell.SFTP\bin\KTools.PowerShell.SFTP.InstallLog
      logtoconsole =
      Committing assembly 'C:\Program Files\KTools\KTools.PowerShell.SFTP\bin\KTools.PowerShell.SFTP.dll'.
      Affected parameters are:
      assemblypath = C:\Program Files\KTools\KTools.PowerShell.SFTP\bin\KTools.PowerShell.SFTP.dll
      logfile = C:\Program Files\KTools\KTools.PowerShell.SFTP\bin\KTools.PowerShell.SFTP.InstallLog
      logtoconsole =
      Installing assembly 'C:\Program Files\KTools\KTools.PowerShell.SFTP\bin\KTools.PowerShell.SFTP.dll'.
      Affected parameters are:
      logtoconsole =
      assemblypath = C:\Program Files\KTools\KTools.PowerShell.SFTP\bin\KTools.PowerShell.SFTP.dll
      logfile = C:\Program Files\KTools\KTools.PowerShell.SFTP\bin\KTools.PowerShell.SFTP.InstallLog
      Committing assembly 'C:\Program Files\KTools\KTools.PowerShell.SFTP\bin\KTools.PowerShell.SFTP.dll'.
      Affected parameters are:
      logtoconsole =
      assemblypath = C:\Program Files\KTools\KTools.PowerShell.SFTP\bin\KTools.PowerShell.SFTP.dll
      logfile = C:\Program Files\KTools\KTools.PowerShell.SFTP\bin\KTools.PowerShell.SFTP.InstallLog
      ------------EOF-------------
      KTools.PowerShell.SFTP.InstallState



      0.72
      2


      11




      _reserved_nestedSavedStates
      _reserved_lastInstallerAttempted



      0





      0.72
      2


      11









      -1





      --------EOF-----------------


      Delete
    3. Kevin.. looks like it may be an issue with PowerGUI

      PS C:\> Get-Command -Module KTools.PowerShell.SFTP

      CommandType Name Definition
      ----------- ---- ----------
      Cmdlet Open-SFTPServer Open-SFTPServer [-serverAddress] [-user...

      Delete
    4. Hi David,

      I didn't test the Snap-In with PowerGUI yet.
      But i know it does work with the Powershell IDE.
      I'll put it on the investigation list.
      Thanks for reporting the bug!

      Kind Regards,
      Kevin

      Delete
  4. Kevin,

    Thanks for the Snap-In! Does this by chance support publickey auth instead of username/password?

    Thanks,
    Scott

    ReplyDelete
    Replies
    1. Hi Scott,

      I`ve added the public key authentication to the version 2-beta of the Snap-In. Maybe you would like to try it out ?

      Kind Regards,
      Kevin

      Delete
  5. Hi Scott,

    I'll put it on the feature request list for version 2.0 ;-)

    Regards,
    Kevin

    ReplyDelete
  6. This is awesome! I ran in to the same problem as someone above: I have powershell 3, so I am having to start a powershell -version 2 shell to use this.

    I created a little front end script to make this work a lot like sftp works on unix type machines.
    It gives you a prompt that lets you type some commands to move around in and view files on the remote computer and local computer.

    Is there any way you can get a Powershell 3 version of this up? I can try to help in any way if it's needed.

    Thanks again. I have been looking for both ssh and sftp in powershell. one down one to go!

    ReplyDelete
    Replies
    1. Hi Jordan,

      I`ll look in to making the library compatible with PowerShell V3.
      I`m also working on making the Snap-In work with public key authentication.
      So I`ll update this post soon with the v2 release of this Snap-In :-)

      P.S.
      If you have any other suggestions please tell me !

      Kind Regards,
      Kevin

      Delete
  7. Kevin - thanks for all the hard work on this.

    I was also having trouble getting the snap-in recognized but playing around with it I found it could be registered in PowerShell 3.0 by changing the 'installPSSnapin.bat' to point to the most recent 'InstallUtil.exe' version. On my machine the expanded registration command is:

    C:\Windows\Microsoft.NET\Framework64\v4.0.30319\InstallUtil.exe "C:\Program Files\KTools\KTools.PowerShell.SFTP\bin\KTools.PowerShell.SFTP.dll"

    I'm still testing for functionality but at least it's being loaded and referenced.

    Rich Harrington
    Saint Xavier University



    ReplyDelete
  8. On more item Kevin - does your wrapper provide an argument to change to an arbitrary port number from the default port of 22? The server I wanted to use this library for requires that I use a specific number, but none of the examples showed this functionality although the error I got back from the $sftp object indicates that the underlying assembly does allow the port to be specified.

    ReplyDelete
    Replies
    1. Hi Rich,

      Thanks for the advice! And i adjusted the Snap-In to include the selection of a port number.

      Kind Regards,
      Kevin

      Delete
    2. Wooo hoooo! I downloaded the latest build and the new installer ran fine. I was able to set the port and had complete success connecting and transferring the files - this is running Windows8/PowerShell 3.0.

      Thanks man! Lifesaver!

      I'm going to test install and execute on our Windows Server 2008 R2/ PowerShell 3.0 and will report back if I have any issues.

      Beauty!

      Delete
    3. I ran the v2.0 installer on our Windows Server 2008 R2 SP2 box (with Microsoft Windows Management Framework 3.0 installed) and both the install and script execution proceeded without a hitch.

      We have another application that currently does a public-key transfer - I'll see if I can get that ported over to PowerShell and let you know how goes it.

      Again - nice job Kevin!

      Delete
    4. Thanks man for testing the new build !
      i'm glad it all works as expected.
      If you have any trouble please let me know.

      Delete
  9. Hi Kevin,

    Great tool!

    I have a small problem in that I cant upload more than I file without getting the below error? 1 file works great.

    Exception calling "Put" with "2" argument(s): "The given path's format is not supported."
    At C:\Scripts\Ryan\SFTP\SFTP\Sample Scripts\SFTP Upload Samples.ps1:28 char:10
    + $sftp.Put <<<< ($localfilelist, "/test")
    + CategoryInfo : NotSpecified: (:) [], MethodInvocationException
    + FullyQualifiedErrorId : DotNetMethodException

    Script below..

    cls
    #Add the SFTP snap-in
    Add-PSSnapin KTools.PowerShell.SFTP -ErrorAction SilentlyContinue

    #Define some variables
    $sftpHost = "******"
    $userName = "******"
    $userPassword = "******"
    #$localFile = "******"
    $localFileList = "******", "******" , "******"

    #Open the SFTP connection
    $sftp = Open-SFTPServer -serverPort 8022 -serverAddress $sftpHost -userName $userName -userPassword $userPassword

    #Upload the local file to the root folder on the SFTP server
    #$sftp.Put($localFile)
    #
    #Upload the local file to another folder on the SFTP server
    #$sftp.Put($localFile, "/test")
    #
    ##Upload the local file to the root folder on the SFTP server with a specific filename
    #$sftp.Put($localFile, "/downloadedFile.txt")
    #
    ##Upload a list of local files to the root folder on the SFTP server
    #$sftp.Put($localFileList)
    #
    #Upload a list of local files to another folder on the SFTP server
    $sftp.Put($localfilelist, "/test")

    #
    #Close the SFTP connection
    $sftp.Close()

    Any help would be much appreciated!

    ReplyDelete
    Replies
    1. Hi,

      Thanks for reporting the bug I'll look in to this!
      For now you can work arround the problem like this :

      #Add the SFTP snap-in
      Add-PSSnapin KTools.PowerShell.SFTP

      #Define some variables
      $sftpHost = "******"
      $userName = "******"
      $userPassword = "******"
      $localFileList = "******", "******", "******"

      #Open the SFTP connection
      $sftp = Open-SFTPServer -serverAddress $sftpHost -userName $userName -userPassword $userPassword

      #Upload a list of local files to another folder on the SFTP server
      foreach($file in $localFileList)
      {
      $sftp.Put($file, "/Temp")
      }

      #Close the SFTP connection
      $sftp.Close()

      Delete
    2. yes that will work thank you Sir!

      Delete
  10. hi kevin ,

    above script works fine. many thanks man

    ReplyDelete
  11. Thanks for the great impl...I was given a requirement after the fact of moving files via sftp and you hooked me up! Thanks again!

    ReplyDelete