使用PowerShell从FTP服务器删除文件

时间:2022-07-28 03:46:24

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

我编写了一个PowerShell脚本来使用FTPto本地机器下载文件。

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.

下载完文件后,我想从FTP服务器上删除它。我也写了这段代码。但不幸的是它不起作用。

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

六边形ABCDEF文件下载

or

ABCDEF file exists

六边形ABCDEF文件存在

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

我猜删除文件根本不执行……任何类型的线索都是有用的。

2 个解决方案

#1


3  

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

不能使用带有FTP URL的测试路径。因此,删除该文件的代码将永远不会执行。

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.

只需删除Test-Path条件并尝试无条件地删除文件。然后检查错误,并按照您的喜好处理“文件不存在”错误。

$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.

因此,您可以考虑放弃任何特定的错误处理。

#2


3  

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.
  • 13号线。$Source参数有一个ftp://..。路径。Test-Path在这里总是返回$false,并且永远不会执行删除请求。
  • 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.
  • 在Get-FTPFile中,您没有引用函数的输入参数,而是引用函数外部定义的变量。我不知道这是复制粘贴错误还是故意的。在我看来,您应该使用您发送给函数的参数。至少在我下面的代码中是第38、39和50行。

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.

也有现成的PowerShell cmdlet用于与FTP/SFTP对话,不需要从头创建所有内容,除非需要这样做。

Anyway, for reference, check out e.g.

不管怎样,作为参考,你可以去看看。

#1


3  

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

不能使用带有FTP URL的测试路径。因此,删除该文件的代码将永远不会执行。

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.

只需删除Test-Path条件并尝试无条件地删除文件。然后检查错误,并按照您的喜好处理“文件不存在”错误。

$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.

因此,您可以考虑放弃任何特定的错误处理。

#2


3  

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.
  • 13号线。$Source参数有一个ftp://..。路径。Test-Path在这里总是返回$false,并且永远不会执行删除请求。
  • 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.
  • 在Get-FTPFile中,您没有引用函数的输入参数,而是引用函数外部定义的变量。我不知道这是复制粘贴错误还是故意的。在我看来,您应该使用您发送给函数的参数。至少在我下面的代码中是第38、39和50行。

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.

也有现成的PowerShell cmdlet用于与FTP/SFTP对话,不需要从头创建所有内容,除非需要这样做。

Anyway, for reference, check out e.g.

不管怎样,作为参考,你可以去看看。