I have a script that connects in to an SFTP site using stored credentials. It copies a file locally, then disconnects from the site and connects to a second SFTP site and uploads the file to that site.
The code works perfectly when I execute it as myself logged into the server as a domain admin.
I have the script setup to run as a scheduled task. When the task runs it starts the script. The problem I am experiencing is that the script seems to be unable to establish the remote server session via SFTP. I added code to the script to send me an email when it starts, and had it grab module information to verify that the POSH-SSH module was properly running and it checks out OK. So I added code to send me the session.host name. This comes back as blank, so it seems the issue is when running as a scheduled task the session cannot establish. Can anyone let me know if they see a problem in the code?
$ErrorActionPreference = “SilenetlyContinue”
#==========================================================================
NAME: SFTPCopy.ps1
AUTHOR: Mark D. MacLachlan, Element Payment Services
DATE : 11/30/2015 10:29:51
This code is copyright (c) 2015 Element Payment Services.
All rights reserved.
THIS CODE AND INFORMATION IS PROVIDED “AS IS” WITHOUT WARRANTY OF
ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
PARTICULAR PURPOSE.
IN NO EVENT SHALL ELEMENT PAYMENT SERVICES AND/OR ITS RESPECTIVE
SUPPLIERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES
OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
OF THIS CODE OR INFORMATION.
COMMENT:
This script requires the PowerShell SFTP Add on available free on GitHub.
To install the SFTP Add on run the following command within an elevated PowerShell command.
wget https://gist.github.com/darkoperator/6152630/raw/c67de4f7cd780ba367cccbc2593f38d18ce6df89/instposhsshdev | iex
#==========================================================================
Get the ID and security principal of the current user account
$myWindowsID=[System.Security.Principal.WindowsIdentity]::GetCurrent()
$myWindowsPrincipal=new-object System.Security.Principal.WindowsPrincipal($myWindowsID)
Get the security principal for the Administrator role
$adminRole=[System.Security.Principal.WindowsBuiltInRole]::Administrator
Check to see if we are currently running “as Administrator”
if ($myWindowsPrincipal.IsInRole($adminRole))
{
We are running “as Administrator” - so change the title and background color to indicate this
$Host.UI.RawUI.WindowTitle = $myInvocation.MyCommand.Definition + “(Elevated)”
$Host.UI.RawUI.BackgroundColor = “DarkBlue”
clear-host
}
else
{
We are not running “as Administrator” - so relaunch as administrator
Create a new process object that starts PowerShell
$newProcess = new-object System.Diagnostics.ProcessStartInfo “PowerShell”;
Specify the current script path and name as a parameter
$newProcess.Arguments = $myInvocation.MyCommand.Definition;
Indicate that the process should be elevated
$newProcess.Verb = “runas”;
Start the new process
Exit from the current, unelevated, process
exit
}
Run your code that needs to be elevated here
#Import the SFTP Module & CmdLets
Set-Location "C:\Program Files\WindowsPowerShell\Modules"
Import-Module posh-ssh
#Get our stored credentials
$encryptedSource = Get-Content C:\PSScripts\EncryptedELPSSFTP.txt | ConvertTo-SecureString
$CredSource = New-Object System.Management.Automation.PsCredential(“ELPSSFTP”, $encryptedSource)
#Get yesterdays date for our file
$FileDate = (Get-Date).AddDays(-1)
$FileDate = $FileDate.ToString(“yyyyMMdd”)
#Get date for our file 2 days ago
$FileDate2 = (Get-Date).AddDays(-2)
$FileDate2 = $FileDate2.ToString(“yyyyMMdd”)
#Get date for our file 3 days ago
$FileDate3 = (Get-Date).AddDays(-3)
$FileDate3 = $FileDate3.ToString(“yyyyMMdd”)
#Create a session to get the files
$Session = New-SFTPSession -ComputerName “mmm.ftpsvr.com” -Credential $CredSource -AcceptKey
#Send an email the process has started
#Email the list
$Body = “SFTP Script Started `r`n $Session.Host”
$Subject = “SFTP Upload Started”
$SMTP = “phx1util01.company.prod”
$To = “mmaclachlan@company.com”
$From = “SFTP@company.com”
Send-MailMessage -To $To -From $From -SmtpServer $SMTP -BodyAsHTML $Body -Subject $Subject
#Download the files
Get-SFTPFile -SFTPSession $Session -RemoteFile “/Inbox/FOTO_P0BCD71D_$FileDate” -LocalPath "C:\Temp\SFTP"
Get-SFTPFile -SFTPSession $Session -RemoteFile “/Inbox/FOTO_P0BCD71D_$FileDate2” -LocalPath "C:\Temp\SFTP"
Get-SFTPFile -SFTPSession $Session -RemoteFile “/Inbox/FOTO_P0BCD71D_$FileDate3” -LocalPath "C:\Temp\SFTP"
#Remove the session
Get-SFTPsession | Remove-SFTPSession
#Create a session to put our file up
$encryptedDest = Get-Content C:\PSScripts\EncryptedCoreCMS_SFTP.txt | ConvertTo-SecureString
$CredDest = New-Object System.Management.Automation.PsCredential(“corecms”, $encryptedDest)
$Session2 = New-SFTPSession -ComputerName phx1sftp01.company.prod -Credential $CredDest -AcceptKey -Port 2222
#Specify the local files
Set-Location "C:\Temp\SFTP"
$LocalFiles = Get-ChildItem "C:\Temp\SFTP"
#Now copy the files up
ForEach ($LocalFile in $LocalFiles)
{
Set-SFTPFile -SessionId 0 -LocalFile “$LocalFile” -RemotePath “/1020380/”
}
#Create a list of uploaded files
$Files = (Get-SFTPChildItem -SessionId 0 -Path /1020380) | Select FullName | Sort-Object FullName
#Email the list
$Body = $Files.FullName -Join “`r`n”
$Subject = “$FileDate SFTP Upload Report”
Send-MailMessage -To $To -From $From -SmtpServer $SMTP -BodyAsHTML $Body -Subject $Subject
#Remove the session
Get-SFTPsession | Remove-SFTPSession
#Remove the local files
ForEach ($LocalFile in $LocalFiles)
{
Remove-Item $LocalFile -Force
}