tomohulk / WinSCP

WinSCP PowerShell Wrapper Module
GNU General Public License v3.0
153 stars 30 forks source link

File not found when using a PSDrive #80

Closed pgrunm closed 6 years ago

pgrunm commented 6 years ago

Issue Description

Hello,

I found an interesting bug in the WinSCP module when using PSDrives. I'm trying to send a file from a PSDrive to a remote server with Send-WinSCPItem. The PSDrive is a shortcut to a remote SMB drive. When I'm using a regular UNC path the module is fine.

Example

# Example PS Drive
$exportPath = New-PSDrive -Name "WinScpTestDrive" -PSProvider FileSystem -Root "\\fileserver1.example.com"

# Remote Destination
$sftp_destination_directory = '/test/'

# Remote Credentials
$credentials_sftp_session = Import-Clixml -Path "$($PSScriptRoot)\cred.cred"

$sftp_session_arguments = @{
    HostName              = 'server.example.com'
    SshPrivateKeyPath     = "$($PSScriptRoot)\key"
    SshHostKeyFingerprint = 'ssh-rsa 2048 59:a5:ae:11:d3:9f:ec:95:c5:17:5b:b8:f5:50:f4:d9'
    Credential            = $credentials_sftp_session
}

$sftp_session = New-WinSCPSession @sftp_session_arguments

$sftp_send_parameters = @{
    WinSCPSession = $sftp_session
    # Working -> Resolves the actual UNC Path, not the PSDrive Path
    Path          = (Convert-Path $exportPath)
    <#
    Not working -> Uses the PSDrive path, which seems unavailable to the cmdlet.
    Path          = $exportPath
    #>
    Destination   = $sftp_destination_directory
}

# Send the Item
$sftp_send_output = Send-WinSCPItem @sftp_send_parameters
if ($sftp_send_output.IsSuccess -eq $true) {
    Write-Output "File $($exportParams.Path) exported successfully!"
}
else {
    Write-Error 'File not sent!'
}

Expected Output

File1 exported successfully!

Some more Powershell Output

$exportPath
WinScpTestDrive:\File1.txt

# Result of Path Test
PS D:\iPhone4All\Abrechnungsskript> Test-Path $exportPath
True

#Result of Get-PSDrive
Get-PSDrive WinScpTestDrive | FL

Name            : WinScpTestDrive
Description     : 
Provider        : Microsoft.PowerShell.Core\FileSystem
Root            : \\fileserver1.example.com\SMB_Share
CurrentLocation : 

Actual Output

PS C:\Temp\SCP.ps1> C:\Temp\SCP.ps1
Send-WinSCPItem : WinSCP.SessionRemoteException: File or folder 'WinScpTestDrive:\File1.txt' does not exist.
System Error.  Code: 123.
The filename, directory name, or volume label syntax is incorrect
At C:\Temp\SCP.ps1:34 char:33
+             $sftp_send_output = Send-WinSCPItem @sftp_send_parameters
+                                 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo          : NotSpecified: (:) [Write-Error], WriteErrorException
+ FullyQualifiedErrorId : Microsoft.PowerShell.Commands.WriteErrorException,Send-WinSCPItem

WinSCP-PowerShell Version

Get-Module WinSCP

ModuleType Version    Name                                ExportedCommands                                                                                                                                            
---------- -------    ----                                ----------------                                                                                                                                            
Script     0.0.0.0    WinSCP                              {ConvertTo-WinSCPEscapedString, Get-WinSCPChildItem, Get-WinSCPItem, Get-WinSCPItemChecksum...}  

No idea why it's not showing the right version This is the right version number from the Module data... I downloaded the module in mid of June.

Environment

Name             : Windows PowerShell ISE Host
Version          : 5.1.14409.1005
InstanceId       : 59623792-ebca-4e81-8cd0-afed56baeec1
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

Also:

dotps1 commented 6 years ago

in your example, you assign the value of $exportPath to the [PSDriveInfo] object, IE, its not a path, and I also don't know how Convert-Path $exportPath works. You could do $($exportPath.Root)\Folder\File.

pgrunm commented 6 years ago

I guess working with PSDrives is some kind of challenge. Anyway I found a way to resolve my issue so I'm closing this. 👍

dotps1 commented 6 years ago

Ok, I mean, PSDrives should have no issues. I was just saying that in your example, the variable you create does not hold a Path property, and that would be none of it is working:

PS C:\Users\dotps1> $drive = New-PSDrive -PSProvider FileSystem -Root $pwd -Name Test
PS C:\Users\dotps1> $drive

Name           Used (GB)     Free (GB) Provider      Root                                               CurrentLocation
----           ---------     --------- --------      ----                                               ---------------
Test                0.00        429.72 FileSystem    C:\Users\dotps1

so like if tried to say Get-ChildItem $drive its going to fail, because $drive isn't a path or a string, its a PSDriveInfo object. So you would have to do Get-ChildItem $drive.Root. Let me know if there is anything else we can look at. Thanks!

Shopnet commented 2 years ago

I had the similar issue. I have converted the path explicitly using convert-path. For example, $pathconverted = convert-path "PSDRIVE:/blah/blah". Kindly ignore if you have already found the solution