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.