Differences

This shows you the differences between the selected revisions of the page.

2015-08-25 2015-08-25
no summary (martin) (hidden) Restored revision 1435092494. Undoing revision 1440530835. (martin) (hidden)
Line 6: Line 6:
<code powershell> <code powershell>
param ( param (
-    $session = "sftp://user:mypassword;fingerprint=ssh-rsa-xx-xx-xx@example.com/", +    $localPath = "c:\downloaded\", 
-    $remotePath = "/path&quot;, +    $remotePath = "/home/user/"
-    $outFile = "listing.csv"+
) )
Line 18: Line 17:
    # Setup session options     # Setup session options
    $sessionOptions = New-Object WinSCP.SessionOptions     $sessionOptions = New-Object WinSCP.SessionOptions
-    $sessionOptions.ParseUrl($session)+    $sessionOptions.Protocol = [WinSCP.Protocol]::Sftp 
 +    $sessionOptions.HostName = "example.com" 
 +    $sessionOptions.UserName = "user" 
 +    $sessionOptions.Password = "mypassword" 
 +    $sessionOptions.SshHostKeyFingerprint = "ssh-rsa 2048 xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx" 
 + 
 +····$session = New-Object WinSCP.Session
    try     try
    {     {
        # Connect         # Connect
-        Write-Host "Connecting..." 
-        $session = New-Object WinSCP.Session 
        $session.Open($sessionOptions)         $session.Open($sessionOptions)
 +
 +        # Get list of files in the directory
 +        $directoryInfo = $session.ListDirectory($remotePath)
-        # Retrieve listing +        # Select the most recent file 
-        Write-Host &quot;Listing...&quot+        $latest = 
- ·······$directory = $session.ListDirectory($remotePath)+ ···········$directoryInfo.Files | 
 +············Where-Object { -Not $_.IsDirectory } | 
 +············Sort-Object LastWriteTime -Descending | 
 +············Select-Object -First 1
-        # Remove output file if it exists +        # Any file at all? 
-        if (Test-Path $outFile)+        if ($latest -eq $Null)
        {         {
-            Remove-Item $outFile +            Write-Host &quot;No file found" 
-········+ ···········exit 1
-  +
-        # Generate a custom listing for ach file in the output file +
-        # Using UTF-16 (Unicode) encoding that Microsoft Excel likes. +
-        foreach ($fileInfo in $directory.Files) +
-        { +
-            ("`"{0}`"`t{1}`t`"{2}`"" -f $fileInfo.Name, $fileInfo.Length, $fileInfo.LastWriteTime) | Out-File -Append $outFile -Encoding Unicode+
        }         }
-        Write-Host &quot;Done&quot;+        # Download the selected file 
 +        $session.GetFiles($session.EscapeFileMask($remotePath + $latest.Name), $localPath).Check()
    }     }
    finally     finally
Line 62: Line 66:
===== [[scripting]] Using WinSCP Scripting ===== ===== [[scripting]] Using WinSCP Scripting =====
-You may have WinSCP produce [[logging_xml|XML log]] with the listing and convert it to your custom format [[logging_xml#xslt|using XSLT]]:+You may use following [[guide_automation_advanced#wsh|Windows script host JScript code]] (''example.js''):
-Use the following Windows batch file (''listing.bat''):+&lt;code javascript&gt; 
 +// Configuration
 +// Local path to download to (keep trailing slash)
 +var LOCALPATH = "c:\\downloaded\\";
 +// Remote path to search in (keep trailing slash)
 +var REMOTEPATH = "/home/user/";
 +// Mask of files to search for
 +var FILEMASK = "*.*";
 +// Session to connect to
 +var SESSION = "session";
 +// Path to winscp.com
 +var WINSCP = "c:\\program files\\winscp\\winscp.com";
 +
 +var filesys = WScript.CreateObject("Scripting.FileSystemObject");
 +var shell = WScript.CreateObject("WScript.Shell");
 + 
 +var logfilepath = filesys.GetSpecialFolder(2) + "\\" + filesys.GetTempName() + ".xml";
 +
 +var exec;
 +
 +// run winscp to get list of file in the remote directory into XML log
 +exec = shell.Exec("\"" + WINSCP + "\" /xmllog=\"" + logfilepath + "\"");
 +exec.StdIn.Write(
 +    "option batch abort\n" +
 +    "open \"" + SESSION + "\"\n" +
 +    "ls \"" + REMOTEPATH + FILEMASK + "\"\n" +
 +    "exit\n");
 +
 +// wait until it finishes and collect its output
 +var output = exec.StdOut.ReadAll();
 +// optionally print the output
 +WScript.Echo(output);
 +
 +if (exec.ExitCode != 0)
 +{
 +    WScript.Echo("Error retrieving list of files");
 +    WScript.Quit(1);
 +}
 +
 +// look for log file
 +var logfile = filesys.GetFile(logfilepath);
 +
 +if (logfile == null)
 +{
 +    WScript.Echo("Cannot find log file");
 +    WScript.Quit(1);
 +}
 +
 +// parse XML log file
 +var doc = new ActiveXObject("MSXML2.DOMDocument");
 +doc.async = false;
 +doc.load(logfilepath);
 +
 +doc.setProperty("SelectionNamespaces",
 +    "xmlns:w='http://winscp.net/schema/session/1.0'");
 +
 +var nodes = doc.selectNodes("//w:file");
 +
 +// find the latest file
 +var filenameLatest = null;
 +var modificationLatest = null;
 +for (var i = 0; i < nodes.length; ++i)
 +{
 +    var filename = nodes[i].selectSingleNode("w:filename/@value");
 +    var modification = nodes[i].selectSingleNode("w:modification/@value");
 +    if ((filename != null) &&
 +        (filename.value != ".") &&
 +        (filename.value != "..") &&
 +        (modification != null))
 +    {
 +        // can compare timestamps stringwise
 +        if ((modificationLatest == null) ||
 +            (modificationLatest < modification.value))
 +        {
 +            modificationLatest = modification.value;
 +            filenameLatest = filename.value;
 +        }
 +    }
 +}
 +
 +// no file in the log
 +if (filenameLatest == null)
 +{
 +    WScript.Echo("No file found");
 +    WScript.Quit(0);
 +}
 +
 +// run winscp to download the latest file
 +exec = shell.Exec("\"" + WINSCP + "\"");
 +exec.StdIn.Write(
 +    "option batch abort\n" +
 +    "option confirm off\n" +
 +    "open \"" + SESSION + "\"\n" +
 +    "get \"" + REMOTEPATH + filenameLatest + "\" \"" + LOCALPATH + "\"\n" +
 +    "exit\n");
 +
 +// wait until it finishes and collect its output
 +var output = exec.StdOut.ReadAll();
 +// optionally print the output
 +WScript.Echo(output);
 +
 +if (exec.ExitCode != 0)
 +{
 +    WScript.Echo("Error downloading " + filenameLatest);
 +    WScript.Quit(1);
 +}
 +</code>
 +
 +Run the script with command:
<code batch> <code batch>
-@echo off +cscript /nologo example.js
-set XMLLOG=script.xml +
-winscp.com /log=script.log /xmllog=%XMLLOG% /command ^ +
-    "open mysession" ^ +
-    "ls /path" ^ +
-    "exit" +
-if %ERRORLEVEL% == 0 msxsl.exe %XMLLOG% listing.xsl > listing_script.csv+
</code> </code>
-Where the ''listing.xsl'' may look like:+===== Alternatives =====
-<code xml&gt; +Some of following alternatives can be easier to implement or actually even more appropriate for your specific task: 
-&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt; + 
-<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:winscp="http://winscp.net/schema/session/1.0">+··* Synchronizing a remote directory to a local directory (using ''[[scriptcommand_synchronize|synchronize local]]'' in scripting or ''[[library_session_synchronizedirectories|Session.SynchronizeDirectories(SynchronizationMode.Local, ...)]]'' in .NET assembly)
- ···<!-- Using UTF-16 encoding that Microsoft Excel likes --&gt; + ·* Downloading all files created in the last 24 hours (using [[file_mask|file mask]] ''*&gt;=1D''; e.g. ''%%get -filemask="*>=1D" /home/user/*%%'', or an equivalent in .NET assembly). 
- ···&lt;xsl:output method="text&quot; encoding=&quot;UTF-16";/&gt; + ·* Downloading all files created today (using ''[[scripting#timestamp|%TIMESTAMP%]]'' syntax to format [[file_mask|file mask]] with today's time constraint, e.g. ''%%get -filemask="*>=%TIMESTAMP#yyyy-mm-dd%"·/home/user/*%%'', or an equivalent in .NET assembly).
- ···&lt;xsl:strip-space elements="*"/> +
-    <xsl:template match='winscp:ls[winscp:result[@success="true"]]/winscp:files/winscp:file'&gt+
- ········&lt;xsl:text>&quot;</xsl:text> +
- ········<xsl:value-of select="winscp:filename/@value"/> +
- ········&lt;xsl:text>&quot;&#9;&lt;/xsl:text&gt; +
- ········&lt;xsl:value-of select=&quot;winscp:size/@value"/> +
- ········&lt;xsl:text>&#9;&quot;</xsl:text> +
-         <xsl:value-of select="winscp:modification/@value"/> +
-·········&lt;xsl:text&gt;&amp;quot;&#xa;</xsl:text> +
-    </xsl:template> +
-</xsl:stylesheet&gt; +
-&lt;/code>+
===== Further Reading ===== ===== Further Reading =====
Line 100: Line 194:
  * Guide to [[guide_automation|scripting/automation]];   * Guide to [[guide_automation|scripting/automation]];
  * [[library|WinSCP .NET assembly]];   * [[library|WinSCP .NET assembly]];
-  * [[library_powershell|Using WinSCP .NET Assembly from PowerShell]]; +  * [[library_powershell|Using WinSCP .NET Assembly from PowerShell]].
-  * [[logging_xml|XML logging]].+

Last modified: by martin