tomohulk / WinSCP

WinSCP PowerShell Wrapper Module

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Send and Receive fails with `[` in the file name

ianharrier opened this issue · comments

Issue Description

When the open square bracket ([) character appears in a file name, the Receive-WinSCPItem and Send-WinSCPItem cmdlets fail to transfer the file.

Example

# This works:
Receive-WinSCPItem -WinSCPSession $Session -RemotePath "/home/test1234.txt" -LocalPath "C:\Files"
<#
   Destination: C:\Files

IsSuccess FileName                                                                                                                                                                                            
--------- --------                                                                                                                                                                                            
True      test1234.txt                                                                                                                                                                                        
#>


# This does NOT work:
Receive-WinSCPItem -WinSCPSession $Session -RemotePath "/home/test[1234.txt" -LocalPath "C:\Files"
<#
Receive-WinSCPItem : WinSCP.SessionRemoteException: Mask is invalid near 'test[1234.txt'.
At line:1 char:1
+ Receive-WinSCPItem -WinSCPSession $Session -RemotePath "/home/test[12 ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (:) [Write-Error], WriteErrorException
    + FullyQualifiedErrorId : Microsoft.PowerShell.Commands.WriteErrorException,Receive-WinSCPItem
#>


# This works:
Receive-WinSCPItem -WinSCPSession $Session -RemotePath "/home/test1234].txt" -LocalPath "C:\Files"
<#
   Destination: C:\Files

IsSuccess FileName                                                                                                                                                                                            
--------- --------                                                                                                                                                                                            
True      test1234].txt                                                                                                                                                                                       
#>


# This does NOT work, despite IsSuccess being True:
Receive-WinSCPItem -WinSCPSession $Session -RemotePath "/home/test[1234].txt" -LocalPath "C:\Files"
<#
IsSuccess FileName                                                                                                                                                                                            
--------- --------                                                                                                                                                                                            
True                                                                                                                                                                                                          
#>


# This works:
Send-WinSCPItem -WinSCPSession $Session -LocalPath "C:\Files\test1234.txt" -RemotePath "/home"
<#
   Destination: \home

IsSuccess FileName                                                                                                                                                                                            
--------- --------                                                                                                                                                                                            
True      test1234.txt                                                                                                                                                                                        
#>


# This does NOT work:
Send-WinSCPItem -WinSCPSession $Session -LocalPath "C:\Files\test[1234.txt" -RemotePath "/home"
<#
Resolve-Path : The specified wildcard character pattern is not valid: test[1234.txt
At C:\Program Files\WindowsPowerShell\Modules\WinSCP\6.1.2.0\Public\Send-WinSCPItem.ps1:58 char:58
+ ... lPathValue in (Convert-Path -Path (Resolve-Path -Path $LocalPath))) {
+                                        ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (:) [Resolve-Path], WildcardPatternException
    + FullyQualifiedErrorId : RuntimeException,Microsoft.PowerShell.Commands.ResolvePathCommand
#>


# This works:
Send-WinSCPItem -WinSCPSession $Session -LocalPath "C:\Files\test1234].txt" -RemotePath "/home"
<#
   Destination: \home

IsSuccess FileName                                                                                                                                                                                            
--------- --------                                                                                                                                                                                            
True      test1234].txt                                                                                                                                                                                       
#>


# This does NOT work:
Send-WinSCPItem -WinSCPSession $Session -LocalPath "C:\Files\test[1234].txt" -RemotePath "/home"
<#
Convert-Path : Cannot bind argument to parameter 'Path' because it is null.
At C:\Program Files\WindowsPowerShell\Modules\WinSCP\6.1.2.0\Public\Send-WinSCPItem.ps1:58 char:57
+ ... lPathValue in (Convert-Path -Path (Resolve-Path -Path $LocalPath))) {
+                                       ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidData: (:) [Convert-Path], ParameterBindingValidationException
    + FullyQualifiedErrorId : ParameterArgumentValidationErrorNullNotAllowed,Microsoft.PowerShell.Commands.ConvertPathCommand
#>

Expected Output

The Receive-WinSCPItem and Send-WinSCPItem cmdlets should be able to transfer a file containing the open square bracket ([) character.

Actual Output

See code block in Example section above.

WinSCP-PowerShell Version

ModuleType Version    Name                                ExportedCommands                                                                                                                                    
---------- -------    ----                                ----------------                                                                                                                                    
Script     6.1.2.0    WinSCP                              {ConvertTo-WinSCPEscapedString, Copy-WinSCPItem, Get-WinSCPChildItem, Get-WinSCPHostKeyFingerprint...}                                              

Environment

OS: Windows Server 2019 (x86_64 / AMD64)

PowerShell Version:

Name             : Windows PowerShell ISE Host
Version          : 5.1.17763.5202
InstanceId       : 61a0a341-554b-4bce-b1f8-a9b0cf2f51b0
UI               : System.Management.Automation.Internal.Host.InternalHostUserInterface
CurrentCulture   : en-US
CurrentUICulture : en-US
PrivateData      : Microsoft.PowerShell.Host.ISE.ISEOptions
DebuggerEnabled  : True
IsRunspacePushed : False
Runspace         : System.Management.Automation.Runspaces.LocalRunspace

Protocol: SFTP

Server: OpenSSH (Debian 12)

Have your tried using the ConvertTo-WinSCPEscapedString cmdlet to escape the character? https://github.com/tomohulk/WinSCP/wiki/ConvertTo-WinSCPEscapedString

Thank you for your reply! No, I was not aware of the ConvertTo-WinSCPEscapedString cmdlet.

ConvertTo-WinSCPEscapedString does seem to fix the issue I was having with Receive-WinSCPItem. These commands both work correctly now:

Receive-WinSCPItem -WinSCPSession $Session -RemotePath $(ConvertTo-WinSCPEscapedString -FileMask "/home/test[1234.txt") -LocalPath "C:\Files"
Receive-WinSCPItem -WinSCPSession $Session -RemotePath $(ConvertTo-WinSCPEscapedString -FileMask "/home/test[1234].txt") -LocalPath "C:\Files"

However, I'm still having trouble with Send-WinSCPItem. Both of these commands fail to transfer the file:

Send-WinSCPItem -WinSCPSession $Session -LocalPath $(ConvertTo-WinSCPEscapedString -FileMask "C:\Files\test[1234.txt") -RemotePath "/home"
<#
Convert-Path : The specified wildcard character pattern is not valid: test[1234.txt
At C:\Program Files\WindowsPowerShell\Modules\WinSCP\6.1.2.0\Public\Send-WinSCPItem.ps1:58 char:38
+ ... lPathValue in (Convert-Path -Path (Resolve-Path -Path $LocalPath))) {
+                    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (:) [Convert-Path], WildcardPatternException
    + FullyQualifiedErrorId : RuntimeException,Microsoft.PowerShell.Commands.ConvertPathCommand
#>


Send-WinSCPItem -WinSCPSession $Session -LocalPath $(ConvertTo-WinSCPEscapedString -FileMask "C:\Files\test[1234].txt") -RemotePath "/home"
<#
No output was produced
#>

It seems like the paths are being escaped correctly in each case:

ConvertTo-WinSCPEscapedString -FileMask "/home/test[1234.txt"
<#
/home/test[[]1234.txt
#>


ConvertTo-WinSCPEscapedString -FileMask "/home/test[1234].txt"
<#
/home/test[[]1234].txt
#>


ConvertTo-WinSCPEscapedString -FileMask "C:\Files\test[1234.txt"
<#
C:\Files\test[[]1234.txt
#>


ConvertTo-WinSCPEscapedString -FileMask "C:\Files\test[1234].txt"
<#
C:\Files\test[[]1234].txt
#>

Thanks again!

I have to think about this. Basically it trying to resolve the local file path and that will now fail because that local file doesn't technically exist with those escape characters. I think really you should use the File mask on the -RemotePath, because don't need to escape that on the windows local path.