简体   繁体   中英

Deleting file from FTP server using PowerShell

I wrote a PowerShell script to download files using FTPto my local machine.

After the file is downloaded, I want to delete it from the FTP server. I wrote this code too. But unfortunately it's not working.

Can anyone help me to point out what is wrong with my code? Any clues will be helpful ...

Here is my code

function Delete-File($Source,$Target,$UserName,$Password)
{

    $ftprequest = [System.Net.FtpWebRequest]::create($Source)
    $ftprequest.Credentials =  New-Object System.Net.NetworkCredential($UserName,$Password)

    if(Test-Path $Source)
    {
       "ABCDEF File exists on ftp server."
       $ftprequest.Method = [System.Net.WebRequestMethods+Ftp]::DeleteFile
       $ftprequest.GetResponse()

       "ABCDEF File deleted."
    }

}

function Get-FTPFile ($Source,$Target,$UserName,$Password)  
{  

    # Create a FTPWebRequest object to handle the connection to the ftp server  
    $ftprequest = [System.Net.FtpWebRequest]::create($Source)  

    # set the request's network credentials for an authenticated connection  
    $ftprequest.Credentials =  
    New-Object System.Net.NetworkCredential($username,$password)  
    if(Test-Path $targetpath)
    {
        "ABCDEF File exists"
    }
    else 
    { 
        "ABCDEF File downloaded"
         $ftprequest.Method = [System.Net.WebRequestMethods+Ftp]::DownloadFile  

         $ftprequest.UseBinary = $true  
         $ftprequest.KeepAlive = $false  
         Delete-File $sourceuri $targetpath $user $pass
    }

    # send the ftp request to the server  
    $ftpresponse = $ftprequest.GetResponse()  

    # get a download stream from the server response  
    $responsestream = $ftpresponse.GetResponseStream()  

    # create the target file on the local system and the download buffer  
    $targetfile = New-Object IO.FileStream ($Target,[IO.FileMode]::Create)  
    [byte[]]$readbuffer = New-Object byte[] 1024  

    # loop through the download stream and send the data to the target 
    file  
    do{  
          $readlength = $responsestream.Read($readbuffer,0,1024)  
          $targetfile.Write($readbuffer,0,$readlength)  
    }  
    while ($readlength -ne 0)  

    $targetfile.close()  
}  

$sourceuri = "ftp://ftpxyz.com/vit/ABCDEF.XML"  
$targetpath = "C:\Temp\M\NEWFOLDER\ABCDEF.XML"  
$user = "*******"  
$pass = "*******"  
Get-FTPFile $sourceuri $targetpath $user $pass 
Delete-File $sourceuri $targetpath $user $pass

Every time I execute this script, the only statement I get

ABCDEF file downloaded

or

ABCDEF file exists

I guess Delete-File is not executing at all... any type of clue will be helpful.

I ran your script locally to try it out and found a few issues. I refactored also a few things just to make it a bit more readable (at least in my opinion :) ).

Issues

  • Line 13. $Source parameter there is a ftp://... path. Test-Path will always return $false here and the delete request will never be executed.
  • In Get-FTPFile you were not referencing the input parameter of the function, instead the variables defined outside of it. I don't know if this was just a copy & paste bug or on purpose. In my opinion you should use the parameters you sent to the function. Lines 38, 39 and 50 at least in my code below.

Code

function Delete-File
{  
   param(
       [string]$Source,
       [string]$Target,
       [string]$UserName,
       [string]$Password
   ) 

   $ftprequest = [System.Net.FtpWebRequest]::create($Source)
   $ftprequest.Credentials =  New-Object System.Net.NetworkCredential($UserName,$Password)

   if(Test-Path $Source)
   {
      "ABCDEF File exists on ftp server."
      $ftprequest.Method = [System.Net.WebRequestMethods+Ftp]::DeleteFile
      $ftprequest.GetResponse()

      "ABCDEF File deleted."
   }

}

function Get-FTPFile
{  
   param(
       [string]$Source,
       [string]$Target,
       [string]$UserName,
       [string]$Password
   ) 

   # Create a FTPWebRequest object to handle the connection to the ftp server  
   $ftprequest = [System.Net.FtpWebRequest]::create($Source)  

   # set the request's network credentials for an authenticated connection  
   $ftprequest.Credentials =  
   New-Object System.Net.NetworkCredential($UserName,$Password)  
   if(Test-Path $Target)
   {
       "ABCDEF File exists"
   }
   else 
   { 
       "ABCDEF File downloaded"
        $ftprequest.Method = [System.Net.WebRequestMethods+Ftp]::DownloadFile  

        $ftprequest.UseBinary = $true  
        $ftprequest.KeepAlive = $false  
        Delete-File $Source $Target $UserName $Password
  }

  # send the ftp request to the server  
  $ftpresponse = $ftprequest.GetResponse()  

  # get a download stream from the server response  
  $responsestream = $ftpresponse.GetResponseStream()  

  # create the target file on the local system and the download buffer  
  $targetfile = New-Object IO.FileStream ($Target,[IO.FileMode]::Create)  
  [byte[]]$readbuffer = New-Object byte[] 1024  

  # loop through the download stream and send the data to the target 
  file  
  do{  
        $readlength = $responsestream.Read($readbuffer,0,1024)  
        $targetfile.Write($readbuffer,0,$readlength)  
  }  
  while ($readlength -ne 0)  

  $targetfile.close()  
}  

$sourceuri = "ftp://ftpxyz.com/vit/ABCDEF.XML"  
$targetpath = "C:\Temp\M\NEWFOLDER\ABCDEF.XML"  
$user = "*******"  
$pass = "*******"   
Get-FTPFile $sourceuri $targetpath $user $pass 
#Delete-File $sourceuri $targetpath $user $pass

There are also ready made PowerShell cmdlets for talking to FTP/SFTP, no need to create everything from scratch, unless you are required to.

Anyway, for reference, check out eg

You cannot use Test-Path with an FTP URL. So your code for deleting the file will never execute.

Just remove the Test-Path condition and try to delete the file unconditionally. Then check for error and treat "file not exist" error as you like.

$ftprequest = [System.Net.FtpWebRequest]::create($Source)
$ftprequest.Credentials =  New-Object System.Net.NetworkCredential($UserName, $Password)

try
{
   $ftprequest.Method = [System.Net.WebRequestMethods+Ftp]::DeleteFile
   $ftprequest.GetResponse() | Out-Null

   Write-Host ("File {0} deleted." -f $Source)
}
catch
{
    if ($_.Exception.InnerException.Response.StatusCode -eq 550)
    {
        Write-Host ("File {0} does not exist." -f $Source)
    }
    else
    {
        Write-Host $_.Exception.Message
    }
}

Though as you try to delete the file only after you successfully download it, it's actually unlikely that the file won't exist.

So you may consider to give up on any specific error handling.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM