Powershell – Downloading and extracting Zip files from FTP
Recently I had the need to routinely check for zip files on a remote FTP server, if there were new files download them and extract them into a particular directory. Dreading the addition of yet another manual process I set out to build a Powershell script to accomplish this task for me. I had become quickly frustrated with the lack of native FTP support in the .Net framework, I know you could pass the ftp credentials as a parametrized URL and download single files. However, I needed to perform a directory listing to see which files existed and had not been downloaded previously. In my search I came across the Indy Project an Open Source group that wrote and maintains the Indy Sockets library which includes and FTP client socket among other things. I will also distribute the Indy.Sockets library with my script.
In this script the $workingPath refers to the location that you want to store the files after downloading and extracting them. This script provides some basic logging functionality, the log file will be written to C:\FTPUtil\FTPUtil.log.
# Downloads files from an FTP server and unzips them. # The script will only download new files that have not # been previously downloaded and extracted into the # working directory. This can be setup as a scheduled # task to automate script run-time. Basic logging is # is written into the FTPUtil.log text file in the # application directory. # # Created by Dustin Berube on 11/16/2010. # Requires Indy.Sockets.dll and Mono.Security.dll version=1.0.5000.0 # Base Location of Files to work with $workingPath = 'x:\path\to\your\file\location' # File Extension $fileExt = '.ZIP' # File extension of file you are downloading. # FTP Information $ftpDir = "/directory" # Directory path to folder on ftp server $ftpServer = "ftp.yourserver.com" # FTP Server address $ftpUser = "username" # FTP Username $ftpPass = "password" # FTP Password # Application Directory - Usually C:\FTPUtil unless installed to different directory $appDir = 'C:\FTPUtil' # # DO NOT CHANGE ANYTHING BELOW THIS LINE # set-location $workingPath $shell = new-object -com shell.application function unzip-Files { $location = $shell.namespace($workingPath) $zipFiles = get-childitem *.zip if (Test-Path ($workingPath + "\*$fileExt")) { foreach ($zipFile in $ZipFiles) { $destDirectory = ($workingPath + "\" + $zipFile.name.Trim($fileExt)) if (!(Test-Path -path $destDirectory)) { [IO.Directory]::CreateDirectory($destDirectory) | out-null $location = $shell.namespace($destDirectory) $zipFolder = $shell.namespace($zipFile.fullname) $location.copyhere($zipFolder.items()) ((get-date).ToString() + " --- " + $zipFile.name + " extracted to $destDirectory") | out-file "$appDir\FTPUtil.log" -append } } Remove-ZipFiles } else { ((get-date).ToString() + " --- NO FILES DOWNLOADED AND UNZIPPED") | out-file "$appDir\FTPUtil.log" -append } } function Remove-ZipFiles { set-location $workingPath $location = $shell.namespace($workingPath) remove-item "*$fileExt" } function Open-FTPConnection { # Load Indy Sockets Library [Reflection.Assembly]::LoadFrom("C:\ftputil\Indy.Sockets.dll") | Out-Null $ftp = new-object Indy.Sockets.FTP $ftp.Disconnect() # Connect to FTP Server $ftp.Host = $ftpServer $ftp.Username = $ftpUser $ftp.Password = $ftpPass $ftp.Connect() # Set PASV mode $ftp.Passive = $true return $ftp } function Close-FTPConnection($ftp) { $ftp.Disconnect() } function Download-FTPFile($ftp) { $ls = new-object System.Collections.Specialized.StringCollection $ftp.List($ls, $ftpDir, $false) foreach($file in $ls) { $fileName = $file.Trim("$ftpDir/") if (!(Test-Path -path ($workingPath + "\" + $fileName.Trim($fileExt)))) { $ftp.Get($file, ($workingPath + "\$fileName"), $true, $false) ((get-date).ToString() + " --- $fileName Downloaded and saved to $workingPath") | out-file "$appDir\FTPUtil.log" -append } } } $f = Open-FTPConnection Download-FTPFile $f Close-FTPConnection $f unzip-Files
After downloading this script, extract the contents to C:\FTPUtil. You can download the FTPUtil script from here http://www.dustinberube.com/files/FTPUtil.zip. As always I take no responsibility for any problems that arise from the use of this script, it has been tested and used in my development and production environments without issue.
Thanks Dustin! I’ve been trying to cobble a solution together for using powershell and FTP together for way too long. I’m so glad I found your solution!
Ty – glad it was able to help you piece together a solution.