VBScript / PowerShell – Automating FTP / SFTP using WinSCP .Net Assembly COM Server

When you want to automate WinSCP using a VBScript it is not so straight forward ? Sad smile

First of all you can find the script here :

https://winscp.net/eng/docs/library_session_listdirectory#vbscript

But when you look carefully you will notice that this is not really a VBS Script but a WSH Script ?

What is the difference ? See here

WSH  is a very COM scripting technique, that has been replaced over time by .NET and PowerShell.

But is still available even on Windows 10  Winking smile

Prerequisites :

Download the WinSCPnet.dll Assembly from here

And register the .Net Assembly to expose the COM component.

‘ 32 Bit => %WINDIR%\Microsoft.NET\Framework\v2.0.50727\RegAsm.exe WinSCPnet.dll /codebase /tlb:WinSCPnet32.tlb
‘ 64 bit => %WINDIR%\Microsoft.NET\Framework64\v4.0.30319\RegAsm.exe WinSCPnet.dll /codebase /tlb:WinSCPnet64.tlb

PS :

Keep in mind that you also need the WinSCP.exe (from the same version as the WinSCPnet.dll !

So make sure you download both of them to guarantee the compatibility between the 2

Solution :

This is the original WSH Code

<job>                                                               
<reference object="WinSCP.Session"/>
<script language="VBScript">
Option Explicit
 
' Setup session options
Dim sessionOptions
Set sessionOptions = CreateObject("WinSCP.SessionOptions")
With sessionOptions
    .Protocol = Protocol_Sftp
    .HostName = "example.com"
    .UserName = "user"
    .Password = "mypassword"
    .SshHostKeyFingerprint = "ssh-rsa 1024 xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx"
End With
 
Dim session
Set session = WScript.CreateObject("WinSCP.Session")
 
' Connect
session.Open sessionOptions
 
' Upload files
Dim transferOptions
Set transferOptions = WScript.CreateObject("WinSCP.TransferOptions")
transferOptions.TransferMode = TransferMode_Binary
 
Dim transferResult
Set transferResult = session.PutFiles("d:\toupload\*", "/home/user/", False, transferOptions)
 
' Throw on any error
transferResult.Check
 
' Print results
Dim transfer
For Each transfer In transferResult.Transfers
    WScript.Echo "Upload of " & transfer.FileName & " succeeded"
Next
 
' Disconnect, clean up
session.Dispose
 
</script>
</job>

Convert WHS it to a real VBS Script like this :

Option Explicit
 
' Setup session options
Const Protocol_Ftp = 2 ' 0 = SFTP

Dim sessionOptions

Set sessionOptions = CreateObject("WinSCP.SessionOptions")

With sessionOptions
    .Protocol = Protocol_Ftp
    .HostName = "194.78.245.62"
    .UserName = "hkcxxxx"
    .Password = "pxxxx"
    '.SshHostKeyFingerprint = "ssh-rsa 2048 xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx"
End With
 
Dim session
Set session = CreateObject("WinSCP.Session")
 
' Connect
session.Open sessionOptions
 
Dim directoryInfo
Set directoryInfo = session.ListDirectory("/")
 
Dim fileInfo
For Each fileInfo In directoryInfo.Files

' To avoid Variable uses an Automation type not supported in VBScript 800A01CA Error
' https://support.microsoft.com/en-us/help/306916/prb-vbscript-type-mismatch-error-when-field-type-is-adnumeric

    WScript.Echo fileInfo.Name  & " with size " & CDbl(fileInfo.Length) & _
        ", permissions " & fileInfo.FilePermissions & _
        " and last modification at " & fileInfo.LastWriteTime
Next
 
' Disconnect, clean up
session.Dispose

If you want to use FTP using TLS encryption you need to use these Session Options

Option Explicit
 
' Setup session options
Const Protocol_Ftp = 2
Const Protocol_SFtp = 0

Const Implicit = 0
Const ExplicitTls = 3
Const ExplicitSsl = 2

Dim sessionOptions

Set sessionOptions = CreateObject("WinSCP.SessionOptions")

With sessionOptions
    .HostName = "xxxxxxxxxx"
    .UserName = "xxxxxxxxxx"
    .Password = "xxxxxx"

    .Protocol = Protocol_Ftp
    .FTPSecure =  ExplicitSsl 
    .TlsHostCertificateFingerprint = "xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx"

    ' .Protocol = Protocol_SFtp 
    ' .FTPSecure =  ExplicitTls 
    '.SshHostKeyFingerprint = "xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx"

End With
Option Explicit
 
' Setup session options
Const Protocol_Ftp = 2
Const Protocol_SFtp = 0

Const Implicit = 0
Const ExplicitTls = 3
Const ExplicitSsl = 2

Dim sessionOptions

Set sessionOptions = CreateObject("WinSCP.SessionOptions")

With sessionOptions
    .HostName = "xxxxxxxxxx"
    .UserName = "xxxxxxxxxx"
    .Password = "xxxxxx"

    .Protocol = Protocol_Ftp
    .FTPSecure =  ExplicitSsl 
    .TlsHostCertificateFingerprint = "xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx"

    ' .Protocol = Protocol_SFtp 
    ' .FTPSecure =  ExplicitTls 
    '.SshHostKeyFingerprint = "c4:15:73:e2:3a:c9:7b:cd:9e:a4:f1:ed:00:d2:ff:d7:56:fb:58:58"

End With

To get access to the Protocol and KeyFingerPrint in WinSCP

Go to Sessions – Server/Protocol Information

image

Copy the FingerPrint Key to the keyboard to use in your script

image

Bonus :

The beauty of the WinSCPnet.dll Assembly is that it has 2 interfaces being a DotNet Assembly that is COM Compatible.

As shown above you can use it in any COM Compatible Client (like VBS Script or AutoIT) Smile

1. .Net Assembly – PowerShell

But as well in PowerShell or any other DotNet Compatible Client (like C# or VB .Net or AutoIT !)

Here is how to generate the script from within WinSCP GUI.

Go to Generate Session URL/Code

image

Select .Net Assembly Code / PowerShell

image

Copy to clipboard and you’re off …

2. Scripting : Batch – Commandline and more …

image

For the Batch you need to download the commandline version WinSCP.com

Or you can run the the /console commandline option using the WinSCP.exe

image

ISSUES :

1. File Encoding Windows to UNIX

I had issues sending files from a Windows server to a UNIX server.

All looked OK when inspecting the source files… But the receiving party alarmed me that the files where corrupt Confused smile

There are 3 strange characters preceding the data on the other end ?

image

After investigation these 3 character are an indication that file is a UTF-8 encoding including a BOM

clip_image001

While UNIX don’t these encoded files, but wants ANSI or ASCIIF encoded files.

You can fix it 2 ways :

A. GUI

image

Select Preference of the DESITINATION Site and SET the “remove BOM and EOF marksoption

B. Scripting

The scripting engine of WinSCP has not means of setting this option automatically Sad smile

PowerShell script to save the files before sending as ASCII encoded files

Use this script to inspect the encoding of the files

CLS

Get-Content -Encoding Byte -TotalCount 100 "YourFile.txt" |% {Write-Host ("{0:x2} " -f $_) -NoNewline}; Write-Host

If you see these 3 Bytes : ef bb bf appearing at the beginning of the file  you have a UTF-8 encoded file

image

Save the file using ASCII encoding fixes the issue :

Get-Content "YourFile.txt" | out-file -encoding ASCII "NewFile.txt

AutoIT script to save the file as ANSI encoding:

If you open the file in Binary Mode – 16

You can see the same 3 characters appearing

<!– HTML generated using hilite.me –>

$file = FileOpenDialog("Select test file", @DesktopDir, "CSV files (*.csv*)")

$hFileOpen = FileOpen ($file,16)
$out = FileRead ($hFileOpen)

image

To fix it save the file as ANSI Mode – 512

<!– HTML generated using hilite.me –>

$file = FileOpenDialog("Select test file", @DesktopDir, "CSV files (*.csv*)")

$hFileOpen = FileOpen ($file,512) ; ANSI Encoding
$out = FileRead ($hFileOpen)

2. Event ID Error 8 / 11 Crypt32

When running the GUI I did not have any issues but when running the cmdline options I could not get connected ?

It took me a long time to figger out what the problem was. In the event viewer I saw a lot of Crypt32 Errors ?

image

The reason was that the server did not have Internet Access …

image

Once I fixed it I could log connect … this means that the GUI behaves differently from the cmdline option.

The GUI could connect using port 22 or 21 while the cmdline option needed to have regular internet access to download so Certificate information

Once this was done I could disable the regular internet access again.

Conclusion :

Basically the WinSCP options are unlimited on a windows platform.

You just have to choose the right scripting environment, GUI / Command Line / COM / .Net

Test it against your FTP server or SFTP Server

Happy Scripting Smile

Enjoy

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.

%d bloggers like this: