Topic "Upload multiple files from source directory through Powershell"

Author Message
jeroenbudding
[View user's profile]

Joined: 2016-03-07
Posts: 2
Location: Netherlands
So the problem is that I have 40 files in a directory. Add the moment if I use my Script which I will post below it will upload all the files but it takes ages.
So what I want is that the script downloads 6 or 8 files add the same time. Is this possible and if so how can I do it.

Code:
#Upload data to LivingStone SFTP
try
{
    # Load WinSCP .NET assembly Rember The folder must contain winscpnet.dl and WinSCP.exe
    Add-Type -Path "C:\Powershell\LivingStone_SFTP\WinSCPnet.dll"
 
    # Setup session options
    $sessionOptions = New-Object WinSCP.SessionOptions
    $sessionOptions.Protocol = [WinSCP.Protocol]::Sftp
    $sessionOptions.HostName =
    $sessionOptions.UserName =
    $sessionOptions.Password =
    $sessionOptions.SshHostKeyFingerprint =
 
    $session = New-Object WinSCP.Session
 
    try
    {
        # Connect
        $session.Open($sessionOptions)
 
        # Upload files
        $transferOptions = New-Object WinSCP.TransferOptions
        $transferOptions.TransferMode = [WinSCP.TransferMode]::Binary
        $TransferOptions.PreserveTimestamp = $false
        $TransferOptions.ResumeSupport.State = [WinSCP.TransferResumeSupportState]::on
       

       
        #here we define source and destination
        $transferResult = $session.PutFiles("D:\Backups\SCCM\*", "/inbox/", $False, $transferOptions)
 
        # Throw on any error       
        $transferResult.Check()
 
        # Print results
        foreach ($transfer in $transferResult.Transfers)
        {
            Write-Host ("Upload of {0} succeeded" -f $transfer.FileName)
        }
    }
    finally
    {
        # Disconnect, clean up
        $session.Dispose()
    }
 
    exit 0
}
catch [Exception]
{
    Write-Host $_.Exception.Message
    exit 1
}[/quote]
Advertisements
martin
[View user's profile]
Site Admin
Joined: 2002-12-10
Posts: 24530
Location: Prague, Czechia
See https://winscp.net/eng/docs/library_example_parallel_transfers
_________________
Martin Prikryl
jeroenbudding
[View user's profile]

Joined: 2016-03-07
Posts: 2
Location: Netherlands
Prikryl thanks for your help in the good direction only that script is downloading not uploading.
I adjusted the script but still get the following error when I run the script:
Downloading C:\Powershell\LivingStone_SFTP\Test\4.exe to /inbox/4.exe in 2
Can't get attributes of file 'C:\Powershell\LivingStone_SFTP\Test\4.exe'.
Script now is as followed:
Code:

#Powershell script to upload the SCCM SQL Database, Active Directory Computers and users
param (
$sessionUrl = "sftp://user:password;fingerprint=ssh-rsa-xx-xx-xx@example.com/",
$remotePath = "/inbox",
$localPath = "",
$batches = 3
)

#Upload data to LivingStone SFTP

try
{
    # Load WinSCP .NET assembly
    $dllPath = (Join-Path $PSScriptRoot "WinSCPnet.dll")
    # Load WinSCP .NET assembly
    Add-Type -Path $dllPath

 # Setup session options
    $sessionOptions = New-Object WinSCP.SessionOptions
    $sessionOptions.ParseUrl($sessionUrl)
 
    $started = Get-Date
 
    try
    {
        # Connect
        Write-Host "Connecting..."
        $session = New-Object WinSCP.Session
        $session.Open($sessionOptions)
       
        # Retrieve list of files and sort them from larges to smallest
        $files = Get-ChildItem $localPath | Sort-Object Length -Descending
 
        # Calculate total size of all files
        $total = ($files | Measure-Object -Property Length -Sum).Sum
       
        # And batch size
        $batch = [int]($total / $batches)
 
        Write-Host ("Will upload {0} files totaling {1} bytes in {2} parallel batches, {3} bytes on average in each" -f $files.Count, $total, $batches, $batch)
       
        $start = 0
        $sum = 0
        $no = 0
 
        for ($i = 0; $i -lt $files.Count; $i++)
        {
            $sum += $files[$i].Length
 
            # Found enough files for the next batch
            if (($sum -ge $batch) -or ($i -eq $files.Count - 1))
            {
                Write-Host ("Starting batch {0} to upload {1} files totaling {2}" -f $no, ($i - $start + 1), $sum)
               
                $fileList = $files[$start..$i] -join ";"
               
                # Start the background job for the batch
                Start-Job -Name "Batch $no" -ArgumentList $dllPath, $sessionUrl, $localPath, $remotePath, $no, $fileList {
                    param (
                        [Parameter(Position = 0)]
                        $dllPath,
                        [Parameter(Position = 1)]
                        $sessionUrl,
                        [Parameter(Position = 2)]
                        $localPath,
                        [Parameter(Position = 3)]
                        $remotePath,
                        [Parameter(Position = 4)]
                        $no,
                        [Parameter(Position = 5)]
                        $fileList
                    )
 
                    try
                    {
                        Write-Host ("Starting batch {0}" -f $no)
 
                        # Load WinSCP .NET assembly.
                        # Need to use an absolute path as the Job is started from user's documents folder.
                        Add-Type -Path $dllPath
 
                        # Setup session options
                        $sessionOptions = New-Object WinSCP.SessionOptions
                        $sessionOptions.ParseUrl($sessionUrl)
                       
                        try
                        {
                            Write-Host ("Connecting batch {0}..." -f $no)
                            $session = New-Object WinSCP.Session
 
                            $session.Open($sessionOptions)
                           
                            $files = $fileList -split ";"
 
                            # Download the files selected for this batch
                            foreach ($file in $files)
                            {
                                $localFilePath = "$localPath\$file"
                                $remoteFilePath = "$remotePath/$file"
                                Write-Host "Downloading $localFilePath to $remoteFilePath in $no"
 
                                $session.GetFiles($session.EscapeFileMask($localFilePath), $remoteFilePath).Check()
                            }
                        }
                        finally
                        {
                            # Disconnect, clean up
                            $session.Dispose()
                        }
                       
                        Write-Host ("Batch {0} done" -f $no)
                    }
                    catch [Exception]
                    {
                        Write-Host $_.Exception.Message
                        exit 1
                    }
                } | Out-Null
 
                # Reset for the next batch
                $no++
                $sum = 0
                $start = $i + 1
            }
        }
 
        Write-Host "Waiting for batches to complete"
        Get-Job | Receive-Job -Wait
 
        Write-Host "Done"
 
        $ended = Get-Date
        Write-Host ("Took {0}" -f (New-TimeSpan -Start $started -End $ended))
    }
    finally
    {
        # Disconnect, clean up
        $session.Dispose()
    }
 
    exit 0
}
catch [Exception]
{
    Write-Host $_.Exception.Message
    exit 1
}   
martin
[View user's profile]
Site Admin
Joined: 2002-12-10
Posts: 24530
Location: Prague, Czechia
You have to at least replace the GetFiles with PutFiles.
Advertisements

You can post new topics in this forum






Search Site

What is WinSCP?

It is award-winning SFTP client, SCP client, FTPS client and FTP client integrated into one software program for file transfer to FTP server or secure SFTP server. [More]

And it's free!

Donate

About donations

$9   $19   $49   $99

About donations

Recommend

WinSCP Privacy Policy

WinSCP License