Post a reply

Options
Add an Attachment

If you do not want to add an Attachment to your Post, please leave the Fields blank.

(maximum 10 MB; please compress large files; only common media, archive, text and programming file formats are allowed)

Options

Topic review

martin

Re: Unable to see and download files using PowerShell WinSCP .NET DLL

Well, it might work sometimes. But it mostly won't. You cannot replicate everything you can do in GUI in script.
awkie

Re: Unable to see and download files using PowerShell WinSCP .NET DLL

The server type is z/OS MVS. I wondered why the WinSCP GUI works and the script doesn't. I can connect and download the required files with the WinSCP GUI. But the script generated from that WinSCP GUI does not see or able to download anything. The script logs show it defaulting to Home, which is wrong, and not what I provided in the script.

directory tree(GUI can get 'xx.xxx.xxxx.', but script cannot.)

|----\<root>
     |-----'xx.xxx.xxxx.'
     |-----abc
     |-----def
     |-----ghi

file panel directory
|----\<root>
     |-----abc
     |-----def
     |-----ghi
awkie

Unable to see and download files using PowerShell WinSCP .NET DLL

I am trying to access a remote FTP server. The connection works using the WinSCP GUI, and I can download the required files from the folder path. But there is a need to automate the process, so I used the WinSCP .NET DLL. I used the generated script from the WinSCP GUI Transfer Settings for PowerShell for the GUI that worked. However, the script kept throwing MethodInvocationException errors.

Then trying to figure this out, I printed the logs for both the GUI and the PowerShell connection and compared the two, and noticed that the PowerShell was defaulting to the Home directory because it was not able to find the required folder even though that remote directory was provided in the script.

So, I decided to use the FileExist method to see what is going on and which confirms this. The method said the same folder the GUI sees doesn't exist. The GUI shows the required directory in the directory tree of the remote server but not in the remote file panel explorer. I don't understand why WinSCP can pick that up and PowerShell with the WinSCP .NET DLL can't. The code is shown below. Any advice or pointers on how to resolve this?

try
{
    # Load WinSCP .NET assembly
    Add-Type -Path "WinSCPnet.dll"
 
    # Setup session options
    $sessionOptions = New-Object WinSCP.SessionOptions -Property @{
        Protocol = [WinSCP.Protocol]::Ftp
        HostName = "xxx.xxx.xxx.xxx"
        PortNumber = xxxx
        UserName = "xxxxxxx"
        Password = "xxxxxxx" #password as a special character in it
        FtpSecure = [WinSCP.FtpSecure]::Explicit
        TlsHostCertificateFingerprint = "xx:xx:xx:xx:xx:xx:xx"
    }
 
    $session = New-Object WinSCP.Session
 
    try
    {   
        # Connect
        $session.Open($sessionOptions)
    
        # Both xyz and 'xx.xxx.xxxx.' are in the same root directory.
        # id file is in xyz, and xxx123 is in 'xx.xxx.xxxx.' respectively.
        # This script says 'id' exist, but 'xxx123' doesn't. And It also doesn't
        # recognize 'xx.xxx.xxxx.', but sees xyz. The folder name of 
        # 'xx.xxx.xxxx.' actually has quotes and periods as in exactly 'xx.xxx.xxxx.'
        #$remotePath = "/xyz/id"
        $remotePath = "/'xx.xxx.xxxx.'/xxx123"
 
        if ($session.FileExists($remotePath))
        {
            Write-Host "File $remotePath exists"
            # Now you can e.g. download file using session.GetFiles
 
            exit 0
        }
        else
        {
            Write-Host "File $remotePath does not exist"
            exit 1
        }
    }
    finally
    {
        # Disconnect, clean up
        $session.Dispose()
    }
}
catch
{
    Write-Host "Error: $($_.Exception.Message)"
    exit 2
}

This is the PowerShell code generated from the Transfer Settings of the WinSCP GUI that worked, but with the added session log path.
# Load WinSCP .NET assembly
Add-Type -Path "WinSCPnet.dll"
 
# Set up session options
$sessionOptions = New-Object WinSCP.SessionOptions -Property @{
    Protocol = [WinSCP.Protocol]::Ftp
    HostName = "xxx.xxx.xxx.xxx"
    PortNumber = xx21
    UserName = "USERNAME"
    Password = "******"
    FtpSecure = [WinSCP.FtpSecure]::Explicit
    TlsHostCertificateFingerprint = "xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx"
}
 
$session = New-Object WinSCP.Session
 
try
{
    #Logging
    $session.SessionLogPath = 'C:\Users\xxx\xxx\...\!S!T'   
 
    # Connect
    $session.Open($sessionOptions)
 
    # Transfer files
    $session.GetFiles("/'xx.xxx.xxxx.'/xxx123", "C:\Users\xxxx\xxxxx").Check()
}
finally
{
    $session.Dispose()
}
 

When I run this code in PowerShell with the WinSCP.NET DLL, I get the following errors:
Exception calling "Check" with "0" argument(s): "Can't get attributes of file '/'xx.xxx.xxxx.'/xxx123'.

Could not retrieve directory listing
CWD cmd failed : EDC5129I No such file or directory. (errno2=0x05190050)"
At line:26 char:5
+     $session.GetFiles("/'xx.xxx.xxxx.'/xxx123'", "C:\Users\xxx ...
+     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (:) [], MethodInvocationException
    + FullyQualifiedErrorId : SessionRemoteException

The only difference I see in the logs of the GUI and PowerShell is that the GUI used the specified remote path and that worked. But PowerShell with the WinSCP .NET DLL, though given the same remote path, didn't use it. It just used 'Home' and there is no Home in that remote server, the way it was configured. So, this goes back to my original question: how do I force PowerShell to use the specified remote path and not default to "Home?"

I attached the redacted WinSCP GUI logs that worked and the PowerShell script logs generated from the GUI that don't work below. Thanks!