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($_)
}