PowerShell Script not functioning correctly when scheduled Task

Advertisement

CyberPunkKatelyn
Joined:
Posts:
3
Location:
Canada

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

Reply with quote

Advertisement

CyberPunkKatelyn
Joined:
Posts:
3
Location:
Canada

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.

Reply with quote

CyberPunkKatelyn
Joined:
Posts:
3
Location:
Canada

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 
    }

Reply with quote

Advertisement

martin
Site Admin
martin avatar
Joined:
Posts:
41,506
Location:
Prague, Czechia

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/".

Reply with quote

Advertisement

You can post new topics in this forum