SFTP/FTPS file transfers in Microsoft Azure WebJob
If you need to export/backup data from your Microsoft Azure App Service (Web Site) to a remote server or import data from the remote server to your App Service, you can use WinSCP from Azure WebJob.
The Azure WebJob is a script or an application run on Azure App Service server that has a read/write access to your service (web site). The job can be executed on demand or schedule. To implement file transfers for the WebJob, you can either run WinSCP in a scripting mode from a batch file; use WinSCP .NET assembly from a PowerShell script or develop a (console) application that uses the WinSCP .NET assembly.
Advertisement
You can also use the WebJob without having an actual app service (web site) as a cloud-hosted scheduled task.
- WebJob structure
- Deploying WebJob
- WebJob Environment
- Copying Session Log to Job Log
- Implementation
- Further Reading
WebJob structure
WebJob is a package that contains your job executable (e.g. a batch file or a console application) along with all supporting files (script, WinSCP executable, WinSCP .NET assembly, etc). Azure platform automatically tries to detect what executable is the main one. To ease this, you should name the main executable run.*
, e.g. run.bat
for a batch file.
See implementation sections below for examples of the package contents.
Deploying WebJob
To deploy your web job:
- Pack all the job files into a ZIP archive;
- Navigate to your app service page on Azure Portal
portal.azure.com
; - Switch to WebJobs page;
- Use Add command on top bar;
- Give your WebJob a name; pick your ZIP archive and set up how the job is run.
Advertisement
After your WebJob is uploaded, it is extracted to /site/wwwroot/App_Data/jobs/type/name
, where type
is triggered
for Scheduled and On demand jobs and continuous
for Continuous jobs. From now on, you can manage/update the job files using FTPS.
You can also deploy the job using Visual Studio, see C# Console Application section below.
Automating WebJob Update
If you update your WebJob frequently, or if you have multiple instances of similar WebJobs, you can automate the update using WinSCP scripting.
First, learn how to setup FTPS access to the WebJob (WebSite).
Example script:
open ftpes://winscp\winscp:mypassword@waws-prod-am1-234.ftp.azurewebsites.windows.net/ put C:\myjob\* /site/wwwroot/App_Data/jobs/type/name/ exit
Make sure you update the example with your actual FTP credentials, FTP host name, the job type (see above) and name.
Learn how to Automate file transfers (or synchronization) to FTP server or SFTP server.
WebJob Environment
In the WebJob environment, your web site data (as you see them over FTPS) are accessible at D:\home
. The path is stored in an environment variable HOME
. Other useful environment variables are:
Variable name | Description | Example |
---|---|---|
HOME |
App service (web site) root directory | D:\home |
WEBJOBS_DATA_PATH |
Job data directory | D:\home\data\jobs\type\name |
WEBJOBS_NAME |
Job name | |
WEBJOBS_PATH |
Temporary directory, where job is running | C:\DWASFiles\Sites\~1sitename\Temp\jobs\type\name\lpej4hrk.fks |
WEBJOBS_RUN_ID |
An unique ID of the job run (an UTC timestamp of the run). There’s a data folder created for every run in %WEBJOBS_DATA_PATH%\%WEBJOBS_RUN_ID% |
201409090707416329 |
WEBJOBS_TYPE |
Job type | triggered or continuous |
WEBROOT_PATH |
App service (web site) root directory | D:\home\site\wwwroot |
WEBSITE_SITE_NAME |
App service (web site) name |
When the WebJob is executed, its files are cloned to a temporary folder (see WEBJOBS_PATH
) and the job is run there. So it makes no sense to store any data to job’s working directory, as that is not persistent and is not accessible remotely. Use WEBROOT_PATH
to locate either job’s master directory (%WEBROOT_PATH%\App_Data\jobs\%WEBJOBS_TYPE%\%WEBJOBS_NAME%
) or WEBJOBS_DATA_PATH
to locate job’s data directory. See implementation sections below for examples.
Advertisement
Copying Session Log to Job Log
The standard output of the job is redirected to a log file which you can display on Azure Portal.
It is useful to have WinSCP session log file included into the job’s log. For that as the last step of the job, print the WinSCP session log to the standard output. See implementation sections below for examples.
To display the job log, go to WebJobs page of your app service on Azure Portal, select the job and click on the Logs button on the top bar.
Implementation
Using Scripting
If your transfer/synchronization task is simple, use WinSCP scripting. For complex tasks, see below for solutions using WinSCP .NET assembly from a PowerShell script or console application.
Start with learning how to Automate file transfers (or synchronization) to FTP server or SFTP server.
Comparing with generic WinSCP script examples, your Azure transfer job should:
- have a wrapper batch file named
run.bat
so that Azure correctly identifies it as the main executable; - the wrapper batch file should propagate WinSCP exit code, so that Azure correctly identifies failures (any non-zero exit code is a failure to Azure, the same for WinSCP);
- enable session logging to a unique job run directory (
%WEBJOBS_DATA_PATH%\%WEBJOBS_RUN_ID%
); - locate source or destination paths of the transfer using WebJob environment variables;
- print the session log to the standard output, so that it is available from Azure Portal.
An example script (script.txt
) that backs up the WebSite to a remote SFTP server:
# Connect open sftp://user:password@example.com/ -hostkey="ssh-rsa 2048 xxxxxxxxxxx..." cd backup # Use a job run ID (timestamp) as a backup ID mkdir %WEBJOBS_RUN_ID% # Upload a whole app service/web site put %WEBROOT_PATH%\* %WEBJOBS_RUN_ID%/ exit
An example wrapper batch file (run.bat
):
@echo off set LOG=%WEBJOBS_DATA_PATH%\%WEBJOBS_RUN_ID%\session.log echo Running script... winscp.com /script=script.txt /log=%LOG% set RESULT=%ERRORLEVEL% echo Result code is %RESULT% rem Dumping session log to Azure log (standard output) when it exists if exist %LOG% ( echo Session log: type %LOG% ) rem Propagating WinSCP exit code to Azure exit /b %RESULT%
Advertisement
A complete WebJob package (to be deployed to Azure App Service) consists of following files:
winscp.com
executable;winscp.exe
executable;script.txt
script;run.bat
wrapper batch file;- optionally a private key file for SSH authentication.
Using PowerShell
For a complex standalone transfer/synchronization tasks, you can use WinSCP .NET assembly from a PowerShell script.
Start with learning how to use WinSCP .NET assembly from PowerShell.
Comparing with generic WinSCP PowerShell examples, your Azure transfer job should:
- have a wrapper batch file named
run.bat
so that Azure correctly identifies it as the main executable (Azure WebJob cannot run PowerShell scripts directly); - the PowerShell script should propagate any error from WinSCP code to an exit code, so that Azure correctly identifies failures (any non-zero exit code is a failure to Azure);
- enable session logging to a unique job run directory (
%WEBJOBS_DATA_PATH%\%WEBJOBS_RUN_ID%
); - locate source or destination paths of the transfer using WebJob environment variables;
- print the session log to the standard output, so that it is available from Azure Portal;
- not use
Write-Host
cmdlet as there is no console to write to in the Azure WebJob, useWrite-Output
instead.
An example PowerShell script (backup.ps1
) that backs up the app service/web site to a remote SFTP server:
try { # Load WinSCP .NET assembly Add-Type -Path "WinSCPnet.dll" # Setup session options $sessionOptions = New-Object WinSCP.SessionOptions -Property @{ Protocol = [WinSCP.Protocol]::Sftp HostName = "example.com" UserName = "user" Password = "mypassword" SshHostKeyFingerprint = "ssh-rsa 2048 xxxxxxxxxxx..." } $sessionLogPath = "$env:WEBJOBS_DATA_PATH\$env:WEBJOBS_RUN_ID\session.log" $session = New-Object WinSCP.Session try { $session.SessionLogPath = $sessionLogPath # Connect Write-Output "Connecting..." $session.Open($sessionOptions) $backupPath = "/home/user/backup/$env:WEBJOBS_RUN_ID" $session.CreateDirectory($backupPath) Write-Output "Uploading..." $session.PutFilesToDirectory($env:WEBROOT_PATH, $backupPath).Check() } finally { # Disconnect, clean up $session.Dispose() } $result = 0 } catch { Write-Output "Error: $($_.Exception.Message)" $result = 1 } # Dumping session log to Azure log (standard output) when it exists if (Test-Path $sessionLogPath) { Write-Output "Session log:" Get-Content $sessionLogPath } # Reporting result to Azure exit $result
Advertisement
An example wrapper batch file (run.bat
):
powershell.exe -ExecutionPolicy Unrestricted -File backup.ps1
A complete WebJob package (to be deployed to Azure App Service) consists of following files:
winscp.exe
executable;winscpnet.dll
.NET assembly;backup.ps1
script;run.bat
wrapper batch file;- optionally a private key file for SSH authentication.
C# Console Application
If you are implementing your task using C# (console) application, you can use WinSCP .NET assembly to implement file transfer/synchronization. Implementing the task in C# may be useful for very complex and possibly continuous jobs.
Start with learning more about the WinSCP .NET assembly, how to install it and see some C# examples.
Comparing with generic WinSCP .NET assembly C# examples, your Azure transfer application should:
- have a wrapper batch file named
run.bat
so that Azure correctly identifies it as the main executable;1 - propagate any error from WinSCP .NET library to its exit code, so that Azure correctly identifies failures (any non-zero exit code is a failure to Azure);
- enable session logging to a unique job run directory (
%WEBJOBS_DATA_PATH%\%WEBJOBS_RUN_ID%
); - locate source or destination paths of the transfer using WebJob environment variables;
- print the session log to the standard output, so that it is available from Azure Portal or provide other means for accessing the log.
An example C# code that backs up the app service/web site to a remote SFTP server:
using System; using System.IO; using WinSCP; class Example { public static int Main() { int result; string sessionLogPath = Path.Combine( Environment.GetEnvironmentVariable("WEBJOBS_DATA_PATH"), Environment.GetEnvironmentVariable("WEBJOBS_RUN_ID"), "session.log"); try { // Setup session options SessionOptions sessionOptions = new SessionOptions { Protocol = Protocol.Sftp, HostName = "example.com", UserName = "user", Password = "mypassword", SshHostKeyFingerprint = "ssh-rsa 2048 xxxxxxxxxxx..." }; using (Session session = new Session()) { session.SessionLogPath = sessionLogPath; // Connect Console.WriteLine("Connecting..."); session.Open(sessionOptions); string backupPath = RemotePath.Combine( session.HomePath, "backup/" + Environment.GetEnvironmentVariable("WEBJOBS_RUN_ID")); session.CreateDirectory(backupPath); Console.WriteLine("Uploading..."); string source = Environment.GetEnvironmentVariable("WEBROOT_PATH"); session.PutFilesToDirectory(source, backupPath).Check(); } result = 0; } catch (Exception e) { Console.WriteLine("Error: {0}", e); result = 1; } // Dumping session log to Azure log (standard output) when it exists if (File.Exists(sessionLogPath)) { Console.WriteLine("Session log:"); using (Stream sessionLog = File.OpenRead(sessionLogPath)) using (Stream standardOutput = Console.OpenStandardOutput()) { sessionLog.CopyTo(standardOutput); } } return result; } }
Advertisement
An example wrapper batch file (run.bat
) that simply runs your application executable:
ConsoleApplication1.exe
A complete WebJob package (to be deployed to Azure App Service) consists of following files:
- your application executable (e.g.
ConsoleApplication1.exe
); winscp.exe
executable;winscpnet.dll
.NET assembly;run.bat
wrapper batch file;- optionally a private key file for SSH authentication.
You can develop the WebJob (console) application as any other desktop console application. You can also start with Azure WebJob project template.
With Visual Studio, you can ease the deployment using command Publish as Azure WebJob, which is available in the project context menu in Solution Explorer. It opens Add Azure WebJob dialog that allows you to name your job and setup how it is run (including scheduling). Make sure you add all additional files needed for the job (i.e. winscp.exe
, run.bat
and private key, as shown above) to the project with Build Action set to Content to have them deployed (see also Using WinSCP .NET assembly from Visual Studio). Easier is to use the NuGet package. When you submit the dialog, a publish process starts on the background in Web Publish Activity pane. Next time you publish, after making changes to the project, only modified files are uploaded. See also Develop and deploy WebJobs using Visual Studio - Azure App Service.
Further Reading
- There will be two
.exe
files, your application andwinscp.exe
, so Azure won’t know which one to pick up, unless you name your applicationrun.exe
.Back