Search code examples
.netpowershellftpwebclient

PowerShell Script to upload an entire folder to FTP


I'm working on a PowerShell script to upload the contents of an entire folder to an FTP location. I'm pretty new to PowerShell with only an hour or two of experience. I can get one file to upload fine but can't find a good solution to do it for all files in the folder. I'm assuming a foreach loop, but maybe there's a better option?

$source = "c:\test"
$destination = "ftp://localhost:21/New Directory/"
$username = "test"
$password = "test"
# $cred = Get-Credential
$wc = New-Object System.Net.WebClient
$wc.Credentials = New-Object System.Net.NetworkCredential($username, $password)

$files = get-childitem $source -recurse -force
foreach ($file in $files)
{
    $localfile = $file.fullname
    # ??????????
}
$wc.UploadFile($destination, $source)
$wc.Dispose()

Solution

  • The loop (or even better a recursion) is the only way to do this natively in PowerShell (or .NET in general).

    $source = "c:\source"
    $destination = "ftp://username:password@example.com/destination"
    
    $webclient = New-Object -TypeName System.Net.WebClient
    
    $files = Get-ChildItem $source
    
    foreach ($file in $files)
    {
        Write-Host "Uploading $file"
        $webclient.UploadFile("$destination/$file", $file.FullName)
    } 
    
    $webclient.Dispose()
    

    Note that the above code does not recurse into subdirectories.


    If you need a simpler solution, you have to use a 3rd party library.

    For example with WinSCP .NET assembly:

    Add-Type -Path "WinSCPnet.dll"
    $sessionOptions = New-Object WinSCP.SessionOptions
    $sessionOptions.ParseUrl("ftp://username:password@example.com/")
    
    $session = New-Object WinSCP.Session
    $session.Open($sessionOptions)
    
    $session.PutFiles("c:\source\*", "/destination/").Check()
    
    $session.Dispose()
    

    The above code does recurse.

    See https://winscp.net/eng/docs/library_session_putfiles

    (I'm the author of WinSCP)