Error: Exception calling "Open" with "1" argument(s): "Connection failed."

Advertisement

luke.mason@fleetlogix.com.au
Joined:
Posts:
2
Location:
Australia

Error: Exception calling "Open" with "1" argument(s): "Connection failed."

We use a PowerShell function to upload data to a govt program that mandates FTPS. We were recently contacted to say they hadn't received our last few uploads. Digging down I found the error was being thrown by the Upload-WinSCP-FTPS function. I mocked up the call for testing and got the same error.

Has the call to Open changed?

Passwords are stored in textfiles as SecureStrings. I've checked, and this one looks correct. Has a @ somewhere in the middle, the rest is just mixed upper/lower text.

Testing Code
. C:\scripts\Function-Upload-WinSCP-FTPS
. c:\scripts\Function-Write-Log.ps1
 
$logFile = "C:\Scripts\log\test.log"
 
$hostname = "ftps.tca.gov.au"
$port = [int]990
$user = "FGX_PUT7"
$passwordFile = "C:\scripts\credential.TCA.txt"
$password = Get-Content  $passwordFile | ConvertTo-SecureString
$file = "C:\Scripts\testfile.txt"
$remotepath = "/"
 
$transferTimer = [System.Diagnostics.Stopwatch]::StartNew()
 
# upload file
$result = Upload-WinSCP-FTPS `
-HostName $hostname `
-Port $port `
-User $user `
-SecurePassword $password `
-TransferFile $file `
-RemotePath $remotepath `
-ParentLogFile $logFile
 
$resultVal = $result[-1] # last element
 
if($resultVal -eq 0)
{
    Write-Log "Upload returned 0 (Success) for $($f.Name)" -Path $logFile -Level Info
    Write-Log "Moving $($f.Name) to $($scriptCfg.DestPath)" -Path $logFile -Level Info
    Move-Item -Path $f.FullName -Destination $($scriptCfg.DestPath) -Force
}
else
{
    Write-Log "Error: Return code $resultVal when attempting to transfer file via FTPS" -Path $logFile -Level Error
}
$transferTimer.Stop()
Write-Log "Transfer Complete." -Path $logFile -Level Info
Write-Log -Message ("Duration {0:hh} hours, {0:mm} minutes and {0:ss} seconds" -f $transferTimer.Elapsed) -Path $logFile -Level Debug

Function Upload-WinSCP-FTPS()
<# 
.Synopsis 
   Upload a a file using the FTPS protocol. 
.DESCRIPTION 
   Loads the WinSCP library and uses it to created an FGTPS Connection using the parameters
   provided
.NOTES
    Looks for WINSCP at "C:\Program Files (x86)\WinSCP\WinSCPnet.dll"
.PARAMETER Hostname 
    The Host the FTP server is running on.  Can be DNS or IP
.PARAMETER Port 
    An Integer representing a TCP Port.  Should be the port the FTP Server is running on.
.PARAMETER User
    ..
.PARAMETER SecurePassword
    ..
.PARAMETER TransferFile
    ..
.PARAMETER RemotePath
    ..
.PARAMETER ParentLogFile
    ..
.EXAMPLE
   ..
.LINK 
   ..
#> 
Function Upload-WinSCP-FTPS()
{
    [CmdletBinding()]
    param 
    (
        [Parameter(Mandatory=$true)]
        [ValidateNotNullOrEmpty()]
        [string]$HostName = $(throw "-HostName is required"),
 
        [Parameter(Mandatory=$true)]
        [ValidateNotNullOrEmpty()]
        [int]$Port = $(throw "-Port is required.  Commonly 21 or 990."),
        
        [Parameter(Mandatory=$true)]
        [ValidateNotNullOrEmpty()]
        [string]$User = $(throw "-User is required"),
        
        [Parameter(Mandatory=$true)]
        [ValidateNotNullOrEmpty()]
        [SecureString]$SecurePassword = $(throw "-SecurePassword is of type SecureString. It is required"),
        
        [Parameter(Mandatory=$true)]
        [ValidateNotNullOrEmpty()]
        [string]$TransferFile = $(throw "-TransferFile is a path to and including a filename. It is required"),
        
        [Parameter(Mandatory=$true)]
        [ValidateNotNullOrEmpty()]
        [string]$RemotePath = $(throw "-RemotePath is a path on the server to upload to. It is required"),
        
        [Parameter(Mandatory=$false)]
        [string]$ParentLogFile
        
    )
 
    [int]$returnVal = 0
    [int]$returnSuccess = 0
    [int]$returnErrorExceptionThrown = 1    
    [int]$returnErrorFileMissing = 2
    
 
    if (! (test-path function:Write-Log)) 
    { 
        . c:\scripts\Function-Write-Log.ps1 
    }
    
## Logging Setup ########################################################
    
    [string]$logPrefix = ""
    if([string]::IsNullOrEmpty($ParentLogFile))
    {
        $logPrefix = ""
        $logDir = "C:\Scripts\log\"
        Generate-Folder $logDir
        $logName = "tca_dir_upload_$(Get-Date -Format "yyyyMMdd").log"
        $logFile = Join-Path -Path $logDir -ChildPath $logName
        Write-Log "Logfile not passed in"  -Path $logFile -Prefix $logPrefix -Level Info
    }
    else
    {
        $logPrefix = "FTPS: "
        $logFile = $ParentLogFile
        Write-Log "Logfile passed in"  -Path $logFile -Prefix $logPrefix -Level Info
    
    }
    Write-Log "Logfile is: $logFile"  -Path $logFile -Prefix $logPrefix -Level Info
 
## Params ###############################################################
 
    Write-Log "Params"                         -Path $logFile -Prefix $logPrefix -Level Verbose
    Write-Log "HostName:       $HostName"      -Path $logFile -Prefix $logPrefix -Level Verbose
    Write-Log "Port:           $Port"          -Path $logFile -Prefix $logPrefix -Level Verbose
    Write-Log "User:           $User"          -Path $logFile -Prefix $logPrefix -Level Verbose
    Write-Log "SecurePassword: ----"           -Path $logFile -Prefix $logPrefix -Level Verbose
    Write-Log "TransferFile:   $TransferFile"  -Path $logFile -Prefix $logPrefix -Level Verbose
    Write-Log "RemotePath:     $RemotePath"    -Path $logFile -Prefix $logPrefix -Level Verbose
    Write-Log "ParentLogFile:  $ParentLogFile" -Path $logFile -Prefix $logPrefix -Level Verbose
    
 
## Check Transfer file ##################################################
    if(-Not (Test-Path $TransferFile -PathType leaf))
    {
        Write-Log "$TransferFile does not exist" -Path $logFile -Prefix $logPrefix -Level Error
        $returnVal = $returnErrorFileMissing
        $returnVal
        Return
    }
 
    try
    {
        # Load WinSCP .NET assembly
        Write-Log "Load WinSCP .NET assembly" -Path $logFile -Prefix $logPrefix -Level Debug
        Add-Type -Path "C:\Program Files (x86)\WinSCP\WinSCPnet.dll"
 
        # Setup session options
        Write-Log "Set WinSCP session options" -Path $logFile -Prefix $logPrefix -Level Debug
        $sessionOptions = New-Object WinSCP.SessionOptions -Property @{
            Protocol = [WinSCP.Protocol]::Ftp
            FtpSecure = [WinSCP.FtpSecure]::Implicit
            HostName = $HostName
            PortNumber = $Port
            UserName = $User
            SecurePassword = $SecurePassword   
        }
 
        Write-Log "Create new Session" -Path $logFile -Prefix $logPrefix -Level Debug
        $session = New-Object WinSCP.Session
        
        try
        {
            # Connect
            Write-Log "Open Session" -Path $logFile -Prefix $logPrefix -Level Debug
            $session.Open($sessionOptions)
 
            # Upload files
            $transferOptions = New-Object WinSCP.TransferOptions
            $transferOptions.TransferMode = [WinSCP.TransferMode]::Binary
 
            Write-Log "Upload file: $TransferFile" -Path $logFile -Prefix $logPrefix -Level Debug
            $transferResult =
                $session.PutFiles($TransferFile, $RemotePath, $False, $transferOptions)
 
 
            # Throw on any error
            Write-Log "Check Result" -Path $logFile -Prefix $logPrefix -Level Debug
            $transferResult.Check()
 
            # Print results
            foreach ($transfer in $transferResult.Transfers)
            {
                Write-Log "Upload success: $($transfer.FileName)" -Path $logFile -Prefix $logPrefix
            }
        }
        finally
        {
            # Disconnect, clean up
            $session.Dispose()
        }
 
        $returnVal = $returnSuccess
        $returnVal
        Return
    }
    catch
    {
        Write-Log "Error: $($_.Exception.Message)" -Path $logFile -Prefix $logPrefix -Level Error
        $returnVal = $returnErrorExceptionThrown
        $returnVal
        Return
    }
}

function Write-Log
We also use this logging function
<# 
.Synopsis 
   Write-Log writes a message to a specified log file with the current time stamp. 
.DESCRIPTION 
   The Write-Log function is designed to add logging capability to other scripts. 
   In addition to writing output and/or verbose you can write to a log file for 
   later debugging. 
.NOTES 
   Created by: Jason Wasser @wasserja 
   Modified: 11/24/2015 09:30:19 AM   
 
   Changelog: 
    * Code simplification and clarification - thanks to @juneb_get_help 
    * Added documentation. 
    * Renamed LogPath parameter to Path to keep it standard - thanks to @JeffHicks 
    * Revised the Force switch to work as it should - thanks to @JeffHicks 
 
   To Do: 
    * Add error handling if trying to create a log file in a inaccessible location. 
    * Add ability to write $Message to $Verbose or $Error pipelines to eliminate 
      duplicates. 
.PARAMETER Message 
   Message is the content that you wish to add to the log file.  
.PARAMETER Path 
   The path to the log file to which you would like to write. By default the function will  
   create the path and file if it does not exist.  
.PARAMETER Level 
   Specify the criticality of the log information being written to the log (i.e. Error, Warning, Informational) 
.PARAMETER NoClobber 
   Use NoClobber if you do not wish to overwrite an existing file. 
.EXAMPLE 
   Write-Log -Message 'Log message'  
   Writes the message to c:\Logs\PowerShellLog.log. 
.EXAMPLE 
   Write-Log -Message 'Restarting Server.' -Path c:\Logs\Scriptoutput.log 
   Writes the content to the specified log file and creates the path and file specified.  
.EXAMPLE 
   Write-Log -Message 'Folder does not exist.' -Path c:\Logs\Script.log -Level Error 
   Writes the message to the specified log file as an error message, and writes the message to the error pipeline. 
#> 
function Write-Log 
{ 
    [CmdletBinding()] 
    Param 
    ( 
        [Parameter(Mandatory=$true, 
                   ValueFromPipelineByPropertyName=$true)] 
        [ValidateNotNullOrEmpty()] 
        [Alias("LogContent")] 
        [string]$Message, 
 
        [Parameter(Mandatory=$false)] 
        [Alias('LogPath')] 
        [string]$Path='C:\Logs\PowerShellLog.log', 
         
        [Parameter(Mandatory=$false)] 
        [ValidateSet("Error","Warn","Info")] 
        [string]$Level="Info", 
         
        [Parameter(Mandatory=$false)] 
        [switch]$NoClobber 
    ) 
 
    Begin 
    { 
        # Set VerbosePreference to Continue so that verbose messages are displayed. 
        $VerbosePreference = 'Continue' 
    } 
    Process 
    { 
         
        # If the file already exists and NoClobber was specified, do not write to the log. 
        if ((Test-Path $Path) -AND $NoClobber) { 
            Write-Error "Log file $Path already exists, and you specified NoClobber. Either delete the file or specify a different name." 
            Return 
        } 
 
        # If attempting to write to a log file in a folder/path that doesn't exist create the file including the path. 
        elseif (!(Test-Path $Path)) { 
            Write-Verbose "Creating $Path." 
            $NewLogFile = New-Item $Path -Force -ItemType File 
        } 
 
        else { 
            # Nothing to see here yet. 
        } 
 
        # Format Date for our Log File 
        $FormattedDate = Get-Date -Format "yyyy-MM-dd HH:mm:ss" 
 
        # Write message to error, warning, or verbose pipeline and specify $LevelText 
        switch ($Level) { 
            'Error' { 
                Write-Error $Message 
                $LevelText = 'ERROR:' 
                } 
            'Warn' { 
                Write-Warning $Message 
                $LevelText = 'WARNING:' 
                } 
            'Info' { 
                Write-Verbose $Message 
                $LevelText = 'INFO:' 
                } 
            } 
         
        # Write log entry to $Path 
        "$FormattedDate $LevelText $Message" | Out-File -FilePath $Path -Append 
    } 
    End 
    { 
    } 
}

Reply with quote

Advertisement

martin
Site Admin
martin avatar
Joined:
Posts:
37,576
Location:
Prague, Czechia

Re: Error: Exception calling "Open" with "1" argument(s): "Connection failed."

There was no backward incompatible change in Session.Open API recently (or ever probably).
Did you upgrade WinSCP at the time the script broke? Or why do you ask?
Please attach a full session log file showing the problem (using the latest version of WinSCP).

To generate the session log file, set Session.SessionLogPath. Submit the log with your post as an attachment. Note that passwords and passphrases not stored in the log. You may want to remove other data you consider sensitive though, such as host names, IP addresses, account names or file names (unless they are relevant to the problem). If you do not want to post the log publicly, you can mark the attachment as private.

Reply with quote

luke.mason@fleetlogix.com.au
Joined:
Posts:
2
Location:
Australia

Thanks Martin,

Not sure if its the latest version, but upgrading would be at the end of this process anyway. I can see from the session log that its rejecting our account. Time to chase it up harder with them.

Script change
Write-Log "Create new Session" -Path $logFile -Prefix $logPrefix -Level Debug
$session = New-Object WinSCP.Session
 
$sessionLogName = "C:\Scripts\log\upload_winscp_ftps_$(Get-Date -Format "yyyyMMdd").log"
Write-Log "Session Log: $($sessionLogName)" -Path $logFile -Prefix $logPrefix -Level Debug
$session.SessionLogPath = $sessionLogName
Session Log
. 2022-05-20 09:43:08.200 --------------------------------------------------------------------------
. 2022-05-20 09:43:08.200 WinSCP Version 5.17.10 (Build 11087) (OS 6.3.9600 - Windows Server 2012 R2 Standard)
. 2022-05-20 09:43:08.200 Configuration: nul
. 2022-05-20 09:43:08.200 Log level: Normal
. 2022-05-20 09:43:08.200 Local account: CT6\Administrator
. 2022-05-20 09:43:08.200 Working directory: C:\Program Files (x86)\WinSCP
. 2022-05-20 09:43:08.200 Process ID: 736
. 2022-05-20 09:43:08.200 Command-line: "C:\Program Files (x86)\WinSCP\winscp.exe" /xmllog="C:\Users\Administrator\AppData\Local\Temp\2\wscp02F8.02E83DB7.tmp" /xmlgroups /xmllogrequired /nointeractiveinput /dotnet=5.17.10  /ini=nul /log="C:\Scripts\log\upload_winscp_ftps_20220520.log"  /console /consoleinstance=_760_23861544_389
. 2022-05-20 09:43:08.200 Time zone: Current: GMT+10, Standard: GMT+10 (AUS Eastern Standard Time), DST: GMT+11 (AUS Eastern Daylight Time), DST Start: 2/10/2022, DST End: 3/04/2022
. 2022-05-20 09:43:08.200 Login time: Friday, 20 May 2022 9:43:08 AM
. 2022-05-20 09:43:08.200 --------------------------------------------------------------------------
. 2022-05-20 09:43:08.200 Script: Retrospectively logging previous script records:
> 2022-05-20 09:43:08.200 Script: option batch on
< 2022-05-20 09:43:08.200 Script: batch           on        
< 2022-05-20 09:43:08.200 Script: reconnecttime   120       
> 2022-05-20 09:43:08.200 Script: option confirm off
< 2022-05-20 09:43:08.200 Script: confirm         off       
> 2022-05-20 09:43:08.200 Script: option reconnecttime 120
< 2022-05-20 09:43:08.200 Script: reconnecttime   120       
> 2022-05-20 09:43:08.200 Script: open ftp://FGX_PUT7:***@ftps.tca.gov.au:990 -implicit -passive=1 -timeout=15
. 2022-05-20 09:43:08.200 --------------------------------------------------------------------------
. 2022-05-20 09:43:08.200 Session name: FGX_PUT7@ftps.tca.gov.au (Ad-Hoc site)
. 2022-05-20 09:43:08.200 Host name: ftps.tca.gov.au (Port: 990)
. 2022-05-20 09:43:08.200 User name: FGX_PUT7 (Password: Yes, Key file: No, Passphrase: No)
. 2022-05-20 09:43:08.200 Transfer Protocol: FTP
. 2022-05-20 09:43:08.200 Ping type: Dummy, Ping interval: 30 sec; Timeout: 15 sec
. 2022-05-20 09:43:08.200 Disable Nagle: No
. 2022-05-20 09:43:08.200 Proxy: None
. 2022-05-20 09:43:08.200 Send buffer: 262144
. 2022-05-20 09:43:08.200 UTF: Auto
. 2022-05-20 09:43:08.200 FTPS: Implicit TLS/SSL [Client certificate: No]
. 2022-05-20 09:43:08.200 FTP: Passive: Yes [Force IP: Auto]; MLSD: Auto [List all: Auto]; HOST: Auto
. 2022-05-20 09:43:08.200 Session reuse: Yes
. 2022-05-20 09:43:08.200 TLS/SSL versions: TLSv1.0-TLSv1.2
. 2022-05-20 09:43:08.200 Local directory: default, Remote directory: home, Update: Yes, Cache: Yes
. 2022-05-20 09:43:08.200 Cache directory changes: Yes, Permanent: Yes
. 2022-05-20 09:43:08.200 Recycle bin: Delete to: No, Overwritten to: No, Bin path: 
. 2022-05-20 09:43:08.200 Timezone offset: 0h 0m
. 2022-05-20 09:43:08.200 --------------------------------------------------------------------------
. 2022-05-20 09:43:08.215 Connecting to ftps.tca.gov.au:990 ...
. 2022-05-20 09:43:08.262 Connected with ftps.tca.gov.au:990, negotiating TLS connection...
. 2022-05-20 09:43:08.341 Verifying certificate for "" with fingerprint 67:9b:8b:25:1c:54:1f:a0:cc:f3:73:4b:25:a7:c5:23:63:5b:93:60 and 20 failures
. 2022-05-20 09:43:08.341 Certificate common name "ftps.tca.gov.au" matches hostname
. 2022-05-20 09:43:08.372 Certificate verified against Windows certificate store
. 2022-05-20 09:43:08.372 Using TLSv1.2, cipher TLSv1.2: ECDHE-RSA-AES256-GCM-SHA384, 2048 bit RSA, ECDHE-RSA-AES256-GCM-SHA384 TLSv1.2 Kx=ECDH     Au=RSA  Enc=AESGCM(256) Mac=AEAD
. 2022-05-20 09:43:08.372 TLS connection established. Waiting for welcome message...
< 2022-05-20 09:43:08.419 220 Welcome to TCA FTP server
> 2022-05-20 09:43:08.419 USER FGX_PUT7
< 2022-05-20 09:43:08.434 331 User FGX_PUT7, password please
> 2022-05-20 09:43:08.434 PASS ***************
< 2022-05-20 09:43:11.466 530 Not logged in. Username/password incorrect, user disabled, or user logged in too many times
. 2022-05-20 09:43:11.466 Connection failed.
. 2022-05-20 09:43:11.466 Password prompt (last login attempt failed)

Reply with quote

Advertisement

You can post new topics in this forum