Jan 04 2022 02:19 AM
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.
Jan 17 2022 10:57 AM - edited Jan 17 2022 10:58 AM
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 :)
Jan 17 2022 01:13 PM - edited Jan 17 2022 01:15 PM
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]
Feb 04 2022 01:31 AM
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