In the following script the main part that gets the directory (I got this code from the web) works but I can't seem to do anything with the string it returns. The directory is retrieved as a single string named
$outputBuffer with each filename separated by a newline character. I split the string into an array and send each array entry to
Func-FtpDownLoad with the following result.
Exception calling "DownloadFile" with "2" argument(s): "An exception occurred during a WebClient request."
At \\nasserver\IT\RichardK\Powershell\FTP - Download files.ps1:6 char:25
+ $webclient.DownloadFile <<<< ("ftp://Rich:123456@owserver/$fn", "C:\New folder\$fn")
+ CategoryInfo : NotSpecified: (:) [], MethodInvocationException
+ FullyQualifiedErrorId : DotNetMethodException
In the code I've called Func-FtpDownLoad twice - the first uses the strings piped from $listArray and causes the exception. The second call uses explicit filenames and works OK.
Also if I change the second argument in DownloadFile to directly name a destination file it also works
$webclient.DownloadFile("ftp://Rich:123456@owserver/$fn", "C:\New folder\TEST.TXT")
But everything gets downloaded as TEST.TXT which isn't much use! - So the problem seems to be something to do with that argument.
Cls function Func-FtpDownLoad($fn) { $webclient = New-Object System.Net.WebClient $webclient.DownloadFile("ftp://Rich:123456@owserver/$fn", "C:\New folder\$fn") } # ------------------------- Get FTP directory ------------------------- # $ftp = [System.Net.WebRequest]::Create("ftp://owserver/") $ftp.Credentials = New-Object System.Net.NetworkCredential("Rich","123456") #::ListDirectory will just list the filenames $ftp.Method = [System.Net.WebRequestMethods+FTP]::ListDirectory #Details $response = $ftp.getresponse() $stream = $response.getresponsestream() $buffer = new-object System.Byte[] 1024 $encoding = new-object System.Text.ASCIIEncoding $outputBuffer = "" $foundMore = $false ## Read all the data available from the stream, writing it to the ## output buffer when done. do { ## Allow data to buffer for a bit start-sleep -m 1000 ## Read what data is available $foundmore = $false $stream.ReadTimeout = 1000 do { try { $read = $stream.Read($buffer, 0, 1024) if($read -gt 0) { $foundmore = $true $outputBuffer += ($encoding.GetString($buffer, 0, $read)) } } catch { $foundMore = $false; $read = 0 } } while($read -gt 0) } while($foundmore) # at this point $outputBuffer is a string with newline separators # so it looks like this if I display it # sbserverdns.evt # sbserverds.evt # outlook error.JPG $listArray = $outputBuffer.Split("`n") # $listArray contains 3 string objects "sbserverdns.evt" "sbserverds.evt" "outlook error.JPG" # this call fails $listArray | ForEach-Object { Func-FtpDownLoad($_) } # this call works using the same filenames as in $listArray "sbserverdns.evt","sbserverds.evt","outlook error.JPG" | ForEach-Object { Func-FtpDownLoad($_) }