Get-SFTPChildItem does not list files on linux if path uses windows-like (\) delimiters
Probably a bug: In v3.2.4, Get-SFTPChildItem no longer lists files in a directory if path is written like (note path separators):
Get-SFTPChildItem -SessionId $sess.SessionId -Path "\home\vlad\*"
In v3.2.3, Get-SFTPChildItem would return file list.
what server are you using that uses backslashes as path separators?
Can you test this function to see if it will work? dont have a target where I can at the moment
function Get-SFTPChildItem
{
[CmdletBinding(DefaultParameterSetName='Index')]
param(
[Parameter(Mandatory=$true,
ParameterSetName = 'Index',
ValueFromPipelineByPropertyName=$true,
Position=0)]
[Alias('Index')]
[Int32[]]
$SessionId,
[Parameter(Mandatory=$true,
ParameterSetName = 'Session',
ValueFromPipeline=$true,
Position=0)]
[Alias('Session')]
[SSH.SFTPSession[]]
$SFTPSession,
[Parameter(Mandatory=$false,
Position=1)]
[string]
$Path = "",
[Parameter(Mandatory=$false,
Position=2)]
[Alias('Recursive')]
[switch]
$Recurse,
[Parameter(Mandatory=$false,
Position=3)]
[switch]
$Directory,
[Parameter(Mandatory=$false,
Position=4)]
[switch]
$File
)
Begin
{
function Get-SFTPItems
{
param($CurrentPath, $SFTPSession, [bool]$IsRecursive)
try {
Write-Verbose "Listing items in path: $CurrentPath"
$items = $SFTPSession.Session.ListDirectory($CurrentPath)
foreach ($item in $items) {
if (@('.','..') -notcontains $item.Name) {
if ((!$File -and !$Directory) -or ($File -and !$item.IsDirectory) -or ($Directory -and $item.IsDirectory))
{
$item
}
if ($IsRecursive -and $item.IsDirectory) {
$subPath = Join-SFTPPath $CurrentPath $item.Name
Get-SFTPItems -CurrentPath $subPath -SFTPSession $SFTPSession -IsRecursive $true
}
}
}
}
catch {
Write-Error "Error listing items in $($CurrentPath): $_"
}
}
function Split-SFTPPath
{
param([string]$Path)
$Path = $Path -replace '\\', '/'
if ($Path -eq '/') {
return @('/', '')
}
if ($Path -match '^(.*)/([^/]+)$') {
$parentPath = if ($Matches[1] -eq '') { '/' } else { $Matches[1] }
return @($parentPath, $Matches[2])
}
else {
return @('/', $Path)
}
}
function Join-SFTPPath
{
param($Path1, $Path2)
$Path1 = $Path1 -replace '\\', '/'
$Path2 = $Path2 -replace '\\', '/'
if ($Path1 -eq '/') {
return "/$Path2"
}
else {
return "$Path1/$Path2"
}
}
$ToProcess = @()
switch($PSCmdlet.ParameterSetName)
{
'Session'
{
$ToProcess = $SFTPSession
}
'Index'
{
foreach($session in $Global:SFTPSessions)
{
if ($SessionId -contains $session.SessionId)
{
$ToProcess += $session
}
}
}
}
}
Process
{
foreach($Sess in $ToProcess)
{
if ($Path -eq "") {
$Path = $Sess.Session.WorkingDirectory
}
# Normalize path separators
$Path = $Path -replace '\\', '/'
# Handle wildcards
if ($Path -like "*[*?]*") {
$pathParts = Split-SFTPPath -Path $Path
$parentPath = $pathParts[0]
$leafPattern = $pathParts[1]
$items = Get-SFTPItems -CurrentPath $parentPath -SFTPSession $Sess -IsRecursive $false
$items | Where-Object { $_.Name -like $leafPattern } | ForEach-Object {
if ($_.IsDirectory) {
$dirPath = Join-SFTPPath $parentPath $_.Name
Get-SFTPItems -CurrentPath $dirPath -SFTPSession $Sess -IsRecursive $Recurse
} else {
$_
}
}
}
else {
# Regular path (including root)
Get-SFTPItems -CurrentPath $Path -SFTPSession $Sess -IsRecursive $Recurse
}
}
}
End{}
}
what server are you using that uses backslashes as path separators?
No, target machine uses normal linux-like path separators (/), command is executed from windows 11 targeting regular ubuntu server. You might ask why I used windows-like path separators to get contents of linux machine?
- It was output from Split-Path cmdlet, which surprisingly converts slashes to backslashes.
Not trying to state this is a bug in new version, only saying such trick worked in v3.2.3 and dont work anymore in v3.2.4.
Can you test this function to see if it will work? dont have a target where I can at the moment
This one works, returning file list.