Modules.Download.Files.psm1
#Requires -Modules Microsoft.PowerShell.ThreadJob function Invoke-FileDownload { [CmdletBinding()] param( [Parameter(ValueFromPipeline = $true, Mandatory, Position = 0)] # Provide all links, from which you want to Download files. These must be direct File links. [array]$link, [Parameter(Mandatory, Position = 1)] # Provide the Folder to which you want to Download you files. [string]$DownloadDirectory, [switch]$UnZip, # If this Parameter is Specified, .Zip Files will be automatically unzipped [array]$DownloadFile ) Import-Module Microsoft.PowerShell.ThreadJob # Import the ThreadJob Module to ensure Execution class DownloadFile { # Class which contains Download Methods static [object] ZipDownload([string]$uri, [string]$DownloadPath) { # Method used, when -UnZip Parameter is used return Start-ThreadJob { # Initialize a thread job and return it $uri = $Using:uri # Make Method Parameters usable in Job. $DownloadPath = $Using:DownloadPath Invoke-WebRequest -Uri $uri -OutFile $DownloadPath # Start the Web Request and send it to the Specified Path, then Expand-Archive -Path $DownloadPath -DestinationPath $DownloadPath.Replace(".zip", '') # Extract the Archive to a Folder, which is derived from the File Name [System.IO.File]::Delete("$DownloadPath") # And remove the downloaded Zip File and only leave the new Folder } } static [object] FileDownload([string]$uri, [string]$DownloadPath) { # Method used, by Default return Start-ThreadJob { # Initialize a thread job and return it $uri = $Using:uri # Make Method Parameters usable in Job. $DownloadPath = $Using:DownloadPath Invoke-WebRequest -Uri $uri -OutFile $DownloadPath # Start the Web Request and send it to the Specified Path } } } [System.Console]::WriteLine("Downloading files, from specified links...") # Write this string to the Console $Jobs = foreach ($uri in $link) { # Send all "Job-Objects, created by the Loop to this variable" Write-Verbose "Attempt to download from '$uri'" if ($null -ne $DownloadFile[$link.IndexOf("$uri")]) { # If a Name exist at the current Link index if (-not [System.IO.File]::Exists("$DownloadDirectory\$($DownloadFile[$link.IndexOf("$uri")])")) { # And if a File with the specified File Name, at the current index, does not already Exist $FileName = $DownloadFile[$link.IndexOf("$uri")] # use this, instead of trying to extract a name from the link } } else { # If an Index match could not be found (i.e. no further Name is given) $FileName = ($uri -split "/")[(($uri -split "/").Length -1)] # Get the File Name, from the link. if ($FileName -match ".7z\?") { # If a File Link matches the Pattern ".7z?", then $FileName = ($FileName -split "\?")[0] # Split the File at the QuestionMark and Select only the First Part of this } } Write-Verbose "Downloading to file '$FileName'" $DownloadPath = $DownloadDirectory, $FileName -join "\" # Create a useable Download Path from the Extracted File Name and the Download Directory if (($FileName -match ".zip$") -and $UnZip) { # When the File-Extension matches .zip, then try { [DownloadFile]::ZipDownload($uri, $DownloadPath) # Use the ZipDownload() Method of the [DownloadFile] class with the Provided Parameters. } catch { throw $Error # if an error occurs (which should never happen), end the Script and show all Errors that have since occured } } else { try { [DownloadFile]::FileDownload($uri, $DownloadPath) # Use the FileDownload() Method of the [DownloadFile] class with the Provided Parameters } catch { throw $Error # if an error occurs (which should never happen), end the Script and show all Errors that have since occured } } } $null = $Jobs | Wait-Job # Wait for all Jobs to finish Downloading. This is not strictly necessary, but will stop you from using the Files in other Scripts [System.Console]::WriteLine("`nAll files have been downloaded. Please checkout '$DownloadDirectory' ...") # Please check if the File Download was successfull } |