Post a reply

Options
Add an Attachment

If you do not want to add an Attachment to your Post, please leave the Fields blank.

(maximum 10 MB; please compress large files; only common media, archive, text and programming file formats are allowed)

Options

Topic review

martin

Re: Upload multiple files from source directory through Powershell

You have to at least replace the GetFiles with PutFiles.
jeroenbudding

Upload multiple files from source directory through Powershell

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:
#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
}   
jeroenbudding

Upload multiple files from source directory through Powershell

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.

#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]