Created
September 23, 2019 12:02
-
-
Save f-steff/67cf974a8ac65dee3153569e10d790b8 to your computer and use it in GitHub Desktop.
Download all files in a folder on an FTP-server to the DestinationFolder. Source and destination must be specified. UrlPort, UserName and Password can be specified. Defaults to access a hardcoded URL.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# DownloadFtpFolder.ps1 created by f-steff, Sept.12 2019. | |
# This is a modified version of DownloadFtpDirectory() by Martin Prikryl. | |
# usage: DownloadFtpFolder.ps1 SourceFolder Destination folder [UrlPort Username Password] | |
function EnsureTargetDirectory ($localPath) | |
{ | |
# Ensure to return a full qualified path. | |
# Will create the folder(s) if needed. | |
try | |
{ | |
$VerifiedDirectory = New-Item -ItemType Directory -Path $localPath -ErrorAction stop -Force | |
} | |
catch | |
{ | |
write-host "Error: Destination path could not be created: '$localPath'" | |
throw "$_" | |
} | |
return $VerifiedDirectory.ToString() | |
} | |
function DownloadFtpDirectory($url, $credentials, [string]$localPath) | |
{ | |
# This function is a slightly modified version of Martin Prikryl answer on StackOverflow: https://stackoverflow.com/questions/37080506/powershell-ftp-download-files-and-subfolders | |
write-debug "localPath = $localPath" | |
If (!(Test-Path -Path $localPath)) | |
{ | |
throw "Error: Path does not exist: $localPath" | |
} | |
write-debug "Source = $url" | |
write-debug "Destination = $localPath" | |
$listRequest = [Net.WebRequest]::Create($url) | |
$listRequest.Method = [System.Net.WebRequestMethods+Ftp]::ListDirectoryDetails | |
$listRequest.UsePassive = 1 | |
$listRequest.Credentials = $credentials | |
$lines = New-Object System.Collections.ArrayList | |
try | |
{ | |
$listResponse = $listRequest.GetResponse() | |
} | |
catch | |
{ | |
write-host "Error: Can not access server" | |
throw ("$_") | |
} | |
$listStream = $listResponse.GetResponseStream() | |
$listReader = New-Object System.IO.StreamReader($listStream) | |
while (!$listReader.EndOfStream) | |
{ | |
$line = $listReader.ReadLine() | |
$lines.Add($line) | Out-Null | |
} | |
if ($listReader.PSobject.Properties.Name -contains "Dispose") { $listReader.Dispose() } | |
if ($listStream.PSobject.Properties.Name -contains "Dispose") { $listStream.Dispose() } | |
if ($listResponse.PSobject.Properties.Name -contains "Dispose") { $listResponse.Dispose() } | |
foreach ($line in $lines) | |
{ | |
$tokens = $line.Split(" ", 9, [StringSplitOptions]::RemoveEmptyEntries) | |
$name = $tokens[8] | |
$permissions = $tokens[0] | |
$localFilePath = Join-Path $localPath $name | |
$fileUrl = ($url + $name) | |
if ($permissions[0] -eq 'd') | |
{ | |
if (!(Test-Path $localFilePath -PathType container)) | |
{ | |
Write-Host "Creating directory $localFilePath" | |
New-Item $localFilePath -Type directory | Out-Null | |
} | |
DownloadFtpDirectory ($fileUrl + "/") $credentials $localFilePath | |
} | |
else | |
{ | |
Write-Host "Downloading $fileUrl to $localFilePath" | |
$downloadRequest = [Net.WebRequest]::Create($fileUrl) | |
$downloadRequest.Method = [System.Net.WebRequestMethods+Ftp]::DownloadFile | |
$downloadRequest.Credentials = $credentials | |
$downloadResponse = $downloadRequest.GetResponse() | |
$sourceStream = $downloadResponse.GetResponseStream() | |
$targetStream = [System.IO.File]::Create($localFilePath) | |
$buffer = New-Object byte[] 10240 | |
while (($read = $sourceStream.Read($buffer, 0, $buffer.Length)) -gt 0) | |
{ | |
$targetStream.Write($buffer, 0, $read); | |
} | |
if ($targetStream.PSobject.Properties.Name -contains "Dispose") { $targetStream.Dispose() } | |
if ($sourceStream.PSobject.Properties.Name -contains "Dispose") { $sourceStream.Dispose() } | |
if ($downloadResponse.PSobject.Properties.Name -contains "Dispose") { $downloadResponse.Dispose() } | |
} | |
} | |
} | |
# Main | |
$DebugPreference = "Continue" # Display debug | |
$DebugPreference = "SilentlyContinue" # Suppress debug | |
try | |
{ | |
$SourceFolder = If ($($args[0])) { $($args[0]) } Else { throw 'Error: Source folder not specified' } # Opt. Comment during Debugging. | |
$DestinationFolder = If ($($args[1])) { $($args[1]) } Else { throw 'Error: Destination folder not specified' } # Opt. Comment during Debugging. | |
# $SourceFolder = '/pub/hvsc/C64Music/DEMOS/Commodore//' # Debug | |
# $DestinationFolder = 'c:\Work\DownloadFtpFolder\test\' # Debug | |
$UrlPort = If ($($args[2])) { $($args[2]) } Else { 'arnold.c64.org:21' } | |
$Username = If ($($args[3])) { $($args[3]) } Else { 'anonymous' } | |
$PassWord = If ($($args[4])) { $($args[4]) } Else { '[email protected]' } | |
if ($SourceFolder[-1] -ne "/") { $SourceFolder += "/" } | |
Write-Host "" | |
Write-Host "Downloading FTP directory using DownloadFtpFolder.ps1" | |
write-Host "Src = ftp://$UrlPort$SourceFolder" | |
write-debug "Dst = $DestinationFolder" | |
write-debug "UrlPort = $UrlPort" | |
write-debug "Username = $Username" | |
write-debug "PassWord = $PassWord" | |
$credentials = New-Object System.Net.NetworkCredential($UserName, $Password) | |
$url = "ftp://$UrlPort/$SourceFolder" | |
$VerifiedFolder = EnsureTargetDirectory $DestinationFolder # Ensure we have a full working path. | |
Write-Host "Dst = $VerifiedFolder" | |
DownloadFtpDirectory $url $credentials $VerifiedFolder | |
Write-Host "" | |
Exit 0 | |
} | |
catch | |
{ | |
$line = $_.InvocationInfo.ScriptLineNumber | |
Write-Host -ForegroundColor Red "ERROR:" | |
Write-Host -ForegroundColor Red "An exception occurred at line $line" | |
Write-Host -ForegroundColor Red '$_ = ' $_ | |
Write-Host -ForegroundColor Red '$_.Exception.Message = ' $_.Exception.Message | |
Write-Host -ForegroundColor Red '$_.GetType().FullName = ' $_.GetType().FullName | |
Write-Host -ForegroundColor Red '$_.Exception.GetType().FullName = ' $_.Exception.GetType().FullName | |
Write-Host -ForegroundColor Red '$_.Exception = ' $_.Exception | |
Write-Host "" | |
Exit 1 | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Download files from a specified folder loacted an an FTP server.
Requires Jenkins Managed Configuration plugin and the Powershell plugin.
FTP URL and port, as well as username and password are hardcoded in the script, but can be overwritten during invocation.
Instructions for uploading the script.
Instructions for using the script.
Once executed, the files will be downloaded.