Thursday, September 13, 2007

FTP transfers automation

 

Sapien technologies just released a com DLL to support simple FTP transfers. It supports the get/put FTP verbs, and I already tested them successfully. Its free to use and can be downloaded from Sapien's website. Thanks Sapien!

The download file includes two VBScripts files, one for upload and one for downloads. Here's a simple conversion to PowerShell.

 

Before starting using the functions, read the readme file, copy the DLL to system32 directory and register it:

regsvr32.exe ftp.dll

 

Cool, lets start

 

###############3

 

function Get-FTPFile{
    param(
        [string]$url,
        [string]$port=21,
        [string]$user,
        [string]$pass,
        [string]$RemoteFilePath,
        [string]$localPath
    )

    $ftp = new-object -com Primalscript.FTPTransfer;
    $ftp.Passive = 1;
    $ftp.port = $port;

    if($ftp.Connect($url,$user,$pass) -eq 0){
        "Can't connect. " + $ftp.Status;
    } else {
        "Starting download"
        If($ftp.Get($RemoteFilePath,$localPath) -eq 0){
            "Error downloading file " + $ftp.Status;
        } Else {
            "Download complete";
        }
        $ftp.Disconnect();
    }
}

 

Usage:

Get-FTPFile <ftpUrl> <port> <username> <password> <RemoteFilePath> <localDonloadPath>

 

############################

 

function Put-FTPFile{
    param(
        [string]$url,
        [string]$port=21,
        [string]$user,
        [string]$pass,
        [string]$localFile,
        [string]$RemotePath
    )

    $ftp = new-object -com Primalscript.FTPTransfer;
    $ftp.Passive = 1;
    $ftp.port = $port;

    if($ftp.Connect($url,$user,$pass) -eq 0){
        "Can't connect. " + $ftp.Status;
    } else {
        if($ftp.Put($RemotePath,$localFile) -eq 1){
            "success upload";           
        } else {
            "Error uploading file. " +$ftp.Status;
        }
        $ftp.Disconnect();
    }
}

 

Usage:

Get-FTPFile <ftpUrl> <port> <username> <password> <localUploadFile> <RemoteUploadPath>

 ##############

 

I'm maybe missing something, but I noticed when using the Put-FTPFile that even if the upload was successful, Put() returns 1 (error???) instead of 0. I commented about it in Spain's website FTP tool page.

 

UPDATE 09/19/2007:

Here's Don Jones reply:

0 is bad, 1 is good news.

1 = success (C++ TRUE)
0 = failure (C++ FALSE)

 

After all, I did miss something :-)

Thanks Don.

13 comments:

Anonymous said...

If you're going to be doing network communications tasks like ftp, you might be better off with NetCmdlets.

Anonymous said...

Hey $shay just have aquick question, im kind of new to powershell and wondering if you could give me advice, i want to access two log files on a remote server using powershell so i can see what the current state of a program is. would you recomend using ftp to copy the logs then view them on the local machine its copied to?, i think ftp may be disabled on the server which contains the log files.

Many many thanks.

Sean.

Shay Levy said...

Hi Sean,

Can you connect to the remote server via UNC? If you would like to take this conversation offline than email me to scriptologATgoogleDOTcom

Shay

Dus said...

Shay, thanks for the post, very helpful indeed. Is there a way to download files from a directory on an ftp server? Kinda like
$ftppath = FTP://ftp@ftp/Stuff
$files = gci $ftppath
foreach($file in $files){
$ftp.Get($ftppath, C:\Stuff)
}
Thanks.

Shay Levy said...

Try this FTP module:

http://poshcode.org/2316

Dus said...

Yeah buddy! Thanks.

Unknown said...

hello shay,

you mention for ftp upload this cmdlet http://poshcode.org/2316

on line 10 there is an include "Import-Module (Join-Path (Get-ScriptPath) common.psm1) -Force" but i dont find these file on poshcode or any reference to this file.

do you know something about this file?

thanks for any help!

kind regards,
subhead

Shay Levy said...

Save the content (starting from line 12 to the end) to a file (e.g c:\ftp.psm1) and load it:

Import-Module C:\ftp.psm1

Now you can use the commands from the module. To get a list of commands from the module:

Get-Command -Module ftp

Unknown said...

hello shay,

thanks for you help. it works like a charm.

have a nice day!

kind regards,
subhead

Lothar said...

Hey Shay,
i just have a question:
is it work with a proxy server.
How to setup?
Thanks!
Regards
Lothar

Shay Levy said...
This comment has been removed by the author.
Shay Levy said...

@Lothar, found the tool, looks like it doesn't offer any support to work with a proxy.

arnold said...

Hello, Shalom
Please, I am looking for your help.

I can no longer use the ftp.
How should I add the few lines to my scripts?

Now i have to us STPES protocole:

[Net.ServicePointManager] :: SecurityProtocol = [Net.SecurityProtocolType] :: Tls -bor [Net.SecurityProtocolType] :: Tls11 -bor [Net.SecurityProtocolType] :: Tls12

Fashion passive
Porte 21
Exlicite TLs

Here is the old scripts that was always a big help for me:

$Xftp = "ftp://perso-ftp.orange/"

# ??????
# $Xftp.UsePassive = $true
# $Xftp.EnableTls = $true

$XlocalDirectory = Get-Content "c:\studio\"
$Xuser = "........."
$Xpass = "........."

$Xwebclient = New-Object System.Net.WebClient
$Xwebclient.Credentials = New-Object System.Net.NetworkCredential($Xuser,$Xpass)
$XFiles = Get-ChildItem -Path "c:\studio\*" -Rec -For | ? {$_.LastWriteTime -gt (Get-Date).AddHours(-1)} | where { ! $_.PSIsContainer } | Select-Object FullName
$Xnombre = $XFiles.Count
foreach ($XFile in $XFiles)
{
$XLocalFile = $XFile.FullName

$XRemoveDirectory = $XLocalFile.Replace("C:\studio\","")
$XChangeSlashes = $XRemoveDirectory.Replace('\','/')
$XRemoveSpaces = $XChangeSlashes.Trim()
$XRemoteFile = $Xftp+$XRemoveSpaces
$Xuri = New-Object System.Uri("$XRemoteFile")
$Xwebclient.UploadFile($Xuri, $XLocalFile)

Write-Host "Getting $XFile from $XlocalDirectory" -Foreground "Red" -BackgroundColor DarkBlue
Write-Host "Puting $XFile to $Xftp" -Foreground "Yellow" -BackgroundColor DarkBlue
}
""
Write-Host "Finished Sync to $Xftp" -Foreground "Green" -BackgroundColor DarkBlue

Many Thanks for your help
Arnold

in France