powershellftpftpwebrequest

Check file existence on FTP server in PowerShell


I want to check if some file exists on FTP server. I wrote code with Test-Path but it's not working. Then I wrote code to get FTP server file size, but it's not working either.

My code

function File-size()
{
   Param ([int]$size)
   if($size -gt 1TB) {[string]::Format("{0:0.00} TB ",$size /1TB)}
   elseif($size -gt 1GB) {[string]::Format("{0:0.00} GB ",$size/1GB)}
   elseif($size -gt 1MB) {[string]::Format("{0:0.00} MB ",$size/1MB)}
   elseif($size -gt 1KB) {[string]::Format("{0:0.00} KB ",$size/1KB)}
   elseif($size -gt 0) {[string]::Format("{0:0.00} B ",$size)}
   else                {""}
}

$urlDest = "ftp://ftpxyz.com/folder/ABCDEF.XML"
$sourcefilesize = Get-Content($urlDest)
$size = File-size($sourcefilesize.length)
Write-Host($size)

This code is not working.

ERROR

Get-Content : Cannot find drive. A drive with the name 'ftp' does not exist.At C:\documents\upload-file.ps1:67 char:19 + $sourcefilesize = Get-Item($urlDest) + ~~~~~~~~~~~~~~~~~~~~~ + CategoryInfo : ObjectNotFound: (ftp:String) [Get-Content], DriveNotFoundException + FullyQualifiedErrorId : DriveNotFound,Microsoft.PowerShell.Commands.GetContentCommand

Any idea how to solve this error? Is there any way I can check some exists into FTP server? Any clue regarding this will be helpful.


Solution

  • You cannot use Test-Path nor Get-Content with FTP URL.

    You have to use FTP client, like WebRequest (FtpWebRequest).

    Though it does not have any explicit method to check file existence (partly because FTP protocol itself does not have such functionality). You need to "abuse" a request like GetFileSize or GetDateTimestamp.

    $url = "ftp://ftp.example.com/remote/path/file.txt"
    
    $request = [Net.WebRequest]::Create($url)
    $request.Credentials =
        New-Object System.Net.NetworkCredential("username", "password");
    $request.Method = [Net.WebRequestMethods+Ftp]::GetFileSize
    
    try
    {
        $request.GetResponse() | Out-Null
        Write-Host "Exists"
    }
    catch
    {
        $response = $_.Exception.InnerException.Response;
        if ($response.StatusCode -eq [Net.FtpStatusCode]::ActionNotTakenFileUnavailable)
        {
            Write-Host "Does not exist"
        }
        else
        {
            Write-Host ("Error: " + $_.Exception.Message)
        }
    }
    

    The code is based on C# code from How to check if file exists on FTP before FtpWebRequest.


    If you want a more straightforward code, use some 3rd party FTP library.

    For example with WinSCP .NET assembly, you can use its Session.FileExists method:

    Add-Type -Path "WinSCPnet.dll"
    
    $sessionOptions = New-Object WinSCP.SessionOptions -Property @{
        Protocol = [WinSCP.Protocol]::Ftp
        HostName = "ftp.example.com"
        UserName = "username"
        Password = "password"
    }
    
    $session = New-Object WinSCP.Session
    $session.Open($sessionOptions)
    
    if ($session.FileExists("/remote/path/file.txt"))
    {
        Write-Host "Exists"
    }
    else
    {
        Write-Host "Does not exist"
    }
    

    (I'm the author of WinSCP)