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

If I take your code, add acceptable values to the constants, I get this output:

[2020-07-12 10:52:39] | INFO  |  SFTP server responded to ping

[2020-07-12 10:52:39] | DEBUG | SomeUserName@sftp         
...

What do you get? Isn't your code throwing an exception? Do you check the script output or only the log file? If only the log file, you will need to capture exceptions as well. Or use Start-Transcript.
See https://winscp.net/eng/docs/guide_debugging_scheduler#powershell

Btw, you are missing $ in sftpSource = "/IntegrationFiles/".
CyberPunkKatelyn

I have included the entire code section around the SFTP transfer, and redacted additional steps that happen once the files have been downloaded.

#-----------------------------------------------------------
#       Installing needed roles/features
#-----------------------------------------------------------
Add-Type -Path "WinSCPnet.dll"
Add-Type -Assembly "System.IO.Compression.FileSystem"
 
#-----------------------------------------------------------
#       Variables
#-----------------------------------------------------------
$date = Get-Date            # Current Date
$temp = "C:\Automation\TEMP\"
$destination = "C:\Automation\SFTPTransfer\"
$logFile = "C:\Automation\logs\"        # Log file
sftpSource = "/IntegrationFiles/"
$sftpFileCount = 0
 
#-----------------------------------------------------------
#   FUNCTIONS
#-----------------------------------------------------------
    #Function:  ScriptLogging()
    #Purpose:   Unified logging function that outputs all messaging passed to it to both a log file
    #           as well as the console.
    #Inputs:    $serverity = Message type (INFO, DEBUG, ERROR)
    #           $message = The message that is to be logged to file / console
    FUNCTION ScriptLogging($serverity, $message) {
        [String]$timeStamp = (Get-Date).toString("yyyy-MM-dd HH:mm:ss")    #-- Get current timestamp
        [String]$logLine = "[{0}] | {1} | {2}" -F $timeStamp, $serverity.PadRight(5), $message
 
        #-- Write to both a Logfile and Pipeline
        IF (($serverity -NE "") -OR ($message -NE "")) {
            $logLine | Tee-Object -FilePath $logFile -Append | Write-Output
        } ELSE {
            ScriptLogging "ERROR" "Failed to pass required parameters to ScriptLogging Function"
            EXIT 1
        }
    }
   
   
    #FUNCTION:  CheckSFTPTransfer()
    #PURPOSE:   Check that all files downloaded from the SFTP sites
    FUNCTION CheckSFTPTransfer($sftpDownloadResults) {
 
        #-- Check SFTP transfer for Errors
        FOREACH($transfer in $sftpDownloadResults.Transfers) {
            IF ($transfer.Error -EQ $Null) {
                ScriptLogging "INFO" "  File transfer successful: $($transfer.FileName)"
            } ELSE {
                ScriptLogging "ERROR" " File Transfer failed: $($transfer.FileName)"
                ScriptLogging "ERROR" " Transfer Error Message: $($transfer.Error.Message)"
                Exit 1
            }
        }
    }
 
#-----------------------------------------------------------
#   MAIN
#-----------------------------------------------------------
    #-- Create Log File
    $logFile = $logFile + "SFTPTransfer_" + "$($date.Year)" + "$("{0:D2}" -f $date.Month)" + "$("{0:D2}" -f $date.Day)" + ".log"
    New-Item -ItemType File -Path $logFile -Force | Out-Null
    IF (!(Test-Path -Path $logFile)) {
        Write-Output "|ERROR| Logfile failed to created, exiting execution."
        EXIT 1
    }
 
    IF (Test-Connection -ComputerName SFTP -Count 1) {     #-- Test Connection to SFTP server
      ScriptLogging "INFO" " SFTP server responded to ping"
 
      # Build SFTP Session Options Object (Yes these values are hardcoded, see comment above)
      $sessionOptions = New-Object WINSCP.SessionOptions -Property @{
         Protocol = [WinSCP.Protocol]::Sftp
         HostName = "sftp"
         UserName = "SomeUserName"
         SshHostKeyFingerPrint = "ssh-rsa 2048 FingerPrint"
         SshPrivateKeyPath = "C:\Automation\2020.ppk"
         PrivateKeyPassphrase = "APassPhrase"
      }
      ScriptLogging "DEBUG" $sessionOptions
 
      $sftpSession = New-Object WinSCP.Session    #-- Create sftp session variable
      $sftpSession.SessionLogPath = "E:\EncoreOnPlayNow\SFTPSessionLog.txt"
      #$sftpSession.SessionLogPath = "C:\Automation\EncoreOnPlayNow\SFTPSessionLog.txt"
 
      TRY {
         $sftpSession.Open($sessionOptions)      #-- Open SFTP session
 
         # Force binary mode transfer
         $transferOptions = New-Object WinSCP.TransferOptions
         $transferOptions.TransferMode = [WinSCP.TransferMode]::Binary
 
         #-- Get Count of number of files on SFTP site
         $sftpFiles = $sftpSession.ListDirectory($sftpSource)
         FOREACH ($fileInfo in $sftpFiles.Files) {
            IF ($fileInfo.Name -Match ".csv") {
               $sftpFileCount++
            }
         }
         ScriptLogging "INFO" " Number of files contained on SFTP site: $($sftpFileCount)"
 
         #-- Download files from SFTP to temporary location
         $sftpTempDownloadResults = $sftpSession.GetFilesToDirectory($sftpSource, $temp)
         ScriptLogging "INFO" " Downloading to $($temp)"
         CheckSFTPTransfer $sftpTempDownloadResults  #-- Check SFTP transfer was successful
 
         #-- Download files from SFTP to SFTPTransfer location
         $sftpTransDownloadResults = $sftpSession.GetFilesToDirectory($sftpSource, $destination)
         ScriptLogging "INFO" " Downloading to $($destination)"
         CheckSFTPTransfer $sftpTransDownloadResults #-- Check SFTP transfer was successful
                        
      } CATCH {
         ScriptLogging "ERROR" " Failed to connect too and download files from SFTP site".
         ScriptLogging "ERROR" " Exception: $($exception)"
         Exit 1
      } FINALLY {
         $sftpSession.Dispose()       #-- Disconnect session
      }
    } ELSE {
        ScriptLogging "ERROR" " SFTP Server did not respond to ping"
        Exit 1
    }
martin

So please post a full example, that does have the problem. We cannot help you otherwise.
CyberPunkKatelyn

I do load the .Net assembly in a further up in my script, the section included in the post was explicitly around where I am connecting to the SFTP server.

The reason I say the object does not appear to be being created is because in some of my troubleshooting, I included some code to output the contents of the $sessionOptions object into my log file so that I could confirm it was correct, however the section where the $sessionOptions should have appeared was empty.
martin

Re: PowerShell Script not functioning correctly when scheduled Task

Your code does not even load the WinSCP .NET assembly:
https://winscp.net/eng/docs/library_powershell#loading

If this does not help, we need to know more than "it appears as if the sessionOptions object is not being created". Do you get any error? Or based on what did you came to that conclusion?
CyberPunkKatelyn

PowerShell Script not functioning correctly when scheduled Task

Hello, I am having a problem with a PowerShell script that works perfectly when executing it manually from PowerShell, however once I put it into a scheduled task, it appears as if the sessionOptions object is not being created. I have tried running the scheduled task under a domain account with Log on As Batch job access, and with my own account that is a Server adminitrator. Both accounts have the same behaviour, the SFTP session does not connect as a Scheduled task. As per my code below, I am attempting to log the SFTP session, however the log file is never created.

WinSCP = 5.17.6
OS = Server 2008R2 or Server 2012R2
PowerShell = v4.0 or v5.1

CODE:
$sessionOptions = New-Object WINSCP.SessionOptions -Property @{
   Protocol = [WinSCP.Protocol]::Sftp
   HostName = "Hardcoded SFTP site name"
   UserName = "Hardcoded SFTP username"
   SshHostKeyFingerPrint = "Hardcoded FingerPrint"
   SshPrivateKeyPath = "Hardcoded relative path to .ppk file"
   PrivateKeyPassphrase = "Hardcoded Passphrase"
}
 
$sftpSession = New-Object WinSCP.Session   
$sftpSession.SessionLogPath = "C:\Automation\SFTPSessionLog.txt"
 
TRY {
   $sftpSession.Open($sessionOptions)      #-- Open SFTP session
 
   # Force binary mode transfer
   $transferOptions = New-Object WinSCP.TransferOptions
   $transferOptions.TransferMode = [WinSCP.TransferMode]::Binary


Any help or ideas would be appricated.
Thanks