Get file name from FTP Server

%3CLINGO-SUB%20id%3D%22lingo-sub-3051200%22%20slang%3D%22en-US%22%3EGet%20file%20name%20from%20FTP%20Server%3C%2FLINGO-SUB%3E%3CLINGO-BODY%20id%3D%22lingo-body-3051200%22%20slang%3D%22en-US%22%3E%3CP%3EHello%2C%26nbsp%3B%3C%2FP%3E%3CP%3E%26nbsp%3B%3C%2FP%3E%3CP%3EI%20am%20using%20below%20code%20to%20query%20an%20FTP%20folder%20and%20get%20the%20name%20of%20the%20existing%20file.%20However%2C%20I%20am%20not%20getting%20the%20desired%20output.%20I%20get%20some%20unwanted%20results%20from%20the%20code.%20I%20appreciate%20some%20help%20in%20getting%20the%20file%20name%20only.%26nbsp%3B%3C%2FP%3E%3CP%3E%26nbsp%3B%3C%2FP%3E%3CP%3ECode%3A%3C%2FP%3E%3CP%3E%26nbsp%3B%3C%2FP%3E%3CP%3E%26nbsp%3B%3C%2FP%3E%3CPRE%20class%3D%22lia-code-sample%20language-applescript%22%3E%3CCODE%3E%24username%3D'Th1sUser'%0A%24password%3D'Th1sPas3'%0A%24ftpuri%3D'ftp%3A%2F%2Frepo.ftpserver.com%2FInstaller'%0A%0A%24uri%3D%5Bsystem.URI%5D%20%24ftpuri%0A%24ftprequest%3D%5Bsystem.net.ftpwebrequest%5D%3A%3ACreate(%24uri)%0A%0A%24ftprequest.Credentials%3DNew-Object%20System.Net.NetworkCredential(%24username%2C%24password)%0A%0A%24ftprequest.Method%3D%5Bsystem.net.WebRequestMethods%2Bftp%5D%3A%3AListDirectory%0A%24response%3D%24ftprequest.GetResponse()%0A%24strm%3D%24response.GetResponseStream()%0A%0A%24reader%3DNew-Object%20System.IO.StreamReader(%24strm%2C'UTF-8')%0A%24list%3D%24reader.ReadToEnd()%0A%0AWrite-Host%20%22%24list%22%3C%2FCODE%3E%3C%2FPRE%3E%3CP%3E%26nbsp%3B%3C%2FP%3E%3CP%3E%26nbsp%3B%3C%2FP%3E%3CP%3EResult%3A%3C%2FP%3E%3CP%3E%26nbsp%3B%3C%2FP%3E%3CP%3E%26nbsp%3B%3C%2FP%3E%3CPRE%20class%3D%22lia-code-sample%20language-applescript%22%3E%3CCODE%3EInstaller%2F.%0AInstaller%2F..%0AInstaller%2FInstallerv1.exe%3C%2FCODE%3E%3C%2FPRE%3E%3CP%3E%26nbsp%3B%3C%2FP%3E%3CP%3E%26nbsp%3B%3C%2FP%3E%3CP%3EI%20would%20like%20to%20get%20the%20installerv1.exe%20as%20the%20file%20name.%20Also%20is%20there%20a%20possibility%20to%20get%20the%20most%20recent%20.exe%20name%20from%20that%20directory%20and%20get%20that%20file%20name%3F%20Thank%20you%20in%20advance.%26nbsp%3B%3C%2FP%3E%3C%2FLINGO-BODY%3E%3CLINGO-LABS%20id%3D%22lingo-labs-3051200%22%20slang%3D%22en-US%22%3E%3CLINGO-LABEL%3EPowerShell%3C%2FLINGO-LABEL%3E%3CLINGO-LABEL%3EWindows%3C%2FLINGO-LABEL%3E%3C%2FLINGO-LABS%3E%3CLINGO-SUB%20id%3D%22lingo-sub-3063848%22%20slang%3D%22en-US%22%3ERe%3A%20Get%20file%20name%20from%20FTP%20Server%3C%2FLINGO-SUB%3E%3CLINGO-BODY%20id%3D%22lingo-body-3063848%22%20slang%3D%22en-US%22%3E%3CP%3E%3CA%20href%3D%22https%3A%2F%2Ftechcommunity.microsoft.com%2Ft5%2Fuser%2Fviewprofilepage%2Fuser-id%2F1265393%22%20target%3D%22_blank%22%3E%40phantom2000%3C%2FA%3E%26nbsp%3B%3C%2FP%3E%3CP%3E%26nbsp%3B%3C%2FP%3E%3CP%3ETried%20it%20myself%2C%20used%20the%26nbsp%3B%24ftprequest.Method%3D%5Bsystem.net.WebRequestMethods%2Bftp%5D%3A%3AListDirectoryDetails%20to%20get%20timestamps%20but%20not%20easy%20to%20parse%20those.%20Then%20I%20read%20a%20post%20(%3CA%20href%3D%22https%3A%2F%2Fstackoverflow.com%2Fquestions%2F40845688%2Fdownload-most-recent-file-from-ftp-using-powershell%22%20target%3D%22_blank%22%20rel%3D%22noopener%20nofollow%20noreferrer%22%3Ehttps%3A%2F%2Fstackoverflow.com%2Fquestions%2F40845688%2Fdownload-most-recent-file-from-ftp-using-powershell%3C%2FA%3E)%20about%20using%20WinSCP%20as%20client%20which%20gives%20you%20more%20options.%20Also%20a%20link%20below%20in%20the%20same%20article%20with%20even%20more%26nbsp%3B%20code%26nbsp%3B%26nbsp%3B%3CA%20href%3D%22https%3A%2F%2Fwinscp.net%2Feng%2Fdocs%2Fscript_download_most_recent_file%22%20target%3D%22_blank%22%20rel%3D%22noopener%20nofollow%20noreferrer%22%3Ehttps%3A%2F%2Fwinscp.net%2Feng%2Fdocs%2Fscript_download_most_recent_file%3C%2FA%3E%26nbsp%3B%3C%2FP%3E%3CP%3E%26nbsp%3B%3C%2FP%3E%3CP%3E%26nbsp%3B%3C%2FP%3E%3CP%3E%26nbsp%3B%3C%2FP%3E%3CPRE%20class%3D%22lia-code-sample%20language-powershell%22%3E%3CCODE%3E%23%20Load%20WinSCP%20.NET%20assembly%0AAdd-Type%20-Path%20%22WinSCPnet.dll%22%0A%0A%23%20Setup%20session%20options%0A%24sessionOptions%20%3D%20New-Object%20WinSCP.SessionOptions%20-Property%20%40%7B%0A%20%20%20%20Protocol%20%3D%20%5BWinSCP.Protocol%5D%3A%3AFtp%0A%20%20%20%20HostName%20%3D%20%22example.com%22%0A%20%20%20%20UserName%20%3D%20%22user%22%0A%20%20%20%20Password%20%3D%20%22mypassword%22%0A%7D%0A%0A%24session%20%3D%20New-Object%20WinSCP.Session%0A%0A%23%20Connect%0A%24session.Open(%24sessionOptions)%0A%0A%23%20Get%20list%20of%20files%20in%20the%20directory%0A%24directoryInfo%20%3D%20%24session.ListDirectory(%24remotePath)%0A%0A%23%20Select%20the%20most%20recent%20file%0A%24latest%20%3D%0A%20%20%20%20%24directoryInfo.Files%20%7C%0A%20%20%20%20Where-Object%20%7B%20-Not%20%24_.IsDirectory%20%7D%20%7C%0A%20%20%20%20Sort-Object%20LastWriteTime%20-Descending%20%7C%0A%20%20%20%20Select-Object%20-First%201%0A%0A%23%20Any%20file%20at%20all%3F%0Aif%20(%24latest%20-eq%20%24Null)%0A%7B%0A%20%20%20%20Write-Host%20%22No%20file%20found%22%0A%20%20%20%20exit%201%0A%7D%0A%0A%23%20Download%20the%20selected%20file%0A%24sourcePath%20%3D%20%5BWinSCP.RemotePath%5D%3A%3AEscapeFileMask(%24remotePath%20%2B%20%24latest.Name)%0A%24session.GetFiles(%24sourcePath%2C%20%24localPath).Check()%3C%2FCODE%3E%3C%2FPRE%3E%3CP%3E%26nbsp%3B%3C%2FP%3E%3CP%3E%26nbsp%3B%3C%2FP%3E%3CP%20data-unlink%3D%22true%22%3EThis%20piece%20of%20code%20was%20written%20by%20the%20author%20of%20WinSCP%20(Martin%20Prikryl%26nbsp%3B)%20%2C%20so%20I%20know%20it's%20good%20%3A)%3C%2Fimg%3E%26nbsp%3B%3C%2FP%3E%3C%2FLINGO-BODY%3E
New Contributor

Hello, 

 

I am using below code to query an FTP folder and get the name of the existing file. However, I am not getting the desired output. I get some unwanted results from the code. I appreciate some help in getting the file name only. 

 

Code:

 

 

$username='Th1sUser'
$password='Th1sPas3'
$ftpuri='ftp://repo.ftpserver.com/Installer'

$uri=[system.URI] $ftpuri
$ftprequest=[system.net.ftpwebrequest]::Create($uri)

$ftprequest.Credentials=New-Object System.Net.NetworkCredential($username,$password)

$ftprequest.Method=[system.net.WebRequestMethods+ftp]::ListDirectory
$response=$ftprequest.GetResponse()
$strm=$response.GetResponseStream()

$reader=New-Object System.IO.StreamReader($strm,'UTF-8')
$list=$reader.ReadToEnd()

Write-Host "$list"

 

 

Result:

 

 

Installer/.
Installer/..
Installer/Installerv1.exe

 

 

I would like to get the installerv1.exe as the file name. Also is there a possibility to get the most recent .exe name from that directory and get that file name? Thank you in advance. 

4 Replies

@phantom2000 

 

Tried it myself, used the $ftprequest.Method=[system.net.WebRequestMethods+ftp]::ListDirectoryDetails to get timestamps but not easy to parse those. Then I read a post (https://stackoverflow.com/questions/40845688/download-most-recent-file-from-ftp-using-powershell) about using WinSCP as client which gives you more options. Also a link below in the same article with even more  code  https://winscp.net/eng/docs/script_download_most_recent_file 

 

 

 

# Load WinSCP .NET assembly
Add-Type -Path "WinSCPnet.dll"

# Setup session options
$sessionOptions = New-Object WinSCP.SessionOptions -Property @{
    Protocol = [WinSCP.Protocol]::Ftp
    HostName = "example.com"
    UserName = "user"
    Password = "mypassword"
}

$session = New-Object WinSCP.Session

# Connect
$session.Open($sessionOptions)

# Get list of files in the directory
$directoryInfo = $session.ListDirectory($remotePath)

# Select the most recent file
$latest =
    $directoryInfo.Files |
    Where-Object { -Not $_.IsDirectory } |
    Sort-Object LastWriteTime -Descending |
    Select-Object -First 1

# Any file at all?
if ($latest -eq $Null)
{
    Write-Host "No file found"
    exit 1
}

# Download the selected file
$sourcePath = [WinSCP.RemotePath]::EscapeFileMask($remotePath + $latest.Name)
$session.GetFiles($sourcePath, $localPath).Check()

 

 

This piece of code was written by the author of WinSCP (Martin Prikryl ) , so I know it's good :) 

@phantom2000 

you could also try using split as well to split out the filename from the path. I use the below script in my scripts to create a batch name using the filename without the extension

 

 

$BatchNameTemp      = $Script:File.split("\")[-1]
$Script:BatchName   = $BatchNameTemp.substring(0,($BatchNameTemp.length-4))

 

so you could modify your script to 

 

$FName = $list.split("/")[-1]

 

 

 

Did you manage to fix your issue?

@SteveMacNZ 

It's well worth using split-path to separate files names and file paths..

# to get the file name
split-path "C:\windows\system32\notepad.exe" -Leaf

# result
# notepad.exe

# to get the directory
split-path "C:\windows\system32\notepad.exe" -Parent

# result
# C:\windows\system32