Version 5

    (sorry for the duplicate post... it looks like exporting to thwack via SAM is the only way that templates can be searchable within SAM)

    In order to test the health of an SFTP server I needed to perform a download from a node.  I didn't see anything built into SolarWinds (or available from thwack) but, after a little bit of research I ran across a nice assembly for WinSCP that makes it very easy to perform automated connections with .NET.  PowerShell is able to make quick work of this.


    1. Follow the instructions here to download and install the assembly onto your polling server(s).  You only need to download the .zip file and extract it to a directory.  I put mine in F:\Program Files (x86)\WinSCP
    2. There are two ways to define the location of the WinSCP DLL file in the monitor: environment variable or hard-coded in the monitor.  You will uncomment the respective line at the top of the monitor depending on how you want it defined.  I set a system-level environment variable on the polling computers that I installed this assembly on.  The name of the environment variable should be WinSCPnetDLL and the value of it should be the full path to the DLL like this:
      If you want to hard-code the path to the DLL in the monitor, comment out the line reading:
          $WinSCPnetDLLPath = (Get-ChildItem env:WinSCPnetDLL).Value
      and uncomment out the line reading:
          #$WinSCPnetDLLPath = 'F:\Program Files (x86)\WinSCP\WinSCPnet.dll'
      Update the path in the line you uncommented to match where you extracted the files to
    3. There are two required script arguments and one optional script argument you can pass:
      • 1st argument
        • Relative location of the file to download without a leading backslash.  For example, if the file you wish to download is named "file1.txt" and is located in the directory named "dir1" immediately off the root, the parameter would be "dir1/file1.txt"
      • 2nd argument
        • SSH host fingerprint of target server.  Connect to the target host via WinSCP (the one located along side your WinSCPnet.dll file will work great) and copy the resulting fingerprint from the SSH negotiation.  An example of the expected value is "ssh-dss 2048 00:11:22:33:44:55:66:77:88:99:aa:bb:cc:dd:ee:ff"
      • 3rd argument
        • TCP port number to connect to.  Leaving this blank, setting to 0, or setting to any non-integer will use the default SSH port number (22).  Setting it to anything else will use that port for the SSH connection
      • Items to note
        • Do not wrap arguments in quotes
        • Using the first two argument examples above, the script arguments field would contain the following text:
              dir1/file1.txt,ssh-dss 2048 00:11:22:33:44:55:66:77:88:99:aa:bb:cc:dd:ee:ff
        • The following sets of script arguments with varying port numbers will be processed identically and all will attempt connection on default SSH port 22:
              dir1/file1.txt,ssh-dss 2048 00:11:22:33:44:55:66:77:88:99:aa:bb:cc:dd:ee:ff
              dir1/file1.txt,ssh-dss 2048 00:11:22:33:44:55:66:77:88:99:aa:bb:cc:dd:ee:ff,
              dir1/file1.txt,ssh-dss 2048 00:11:22:33:44:55:66:77:88:99:aa:bb:cc:dd:ee:ff,0    dir1/file1.txt,ssh-dss 2048 00:11:22:33:44:55:66:77:88:99:aa:bb:cc:dd:ee:ff,22
              dir1/file1.txt,ssh-dss 2048 00:11:22:33:44:55:66:77:88:99:aa:bb:cc:dd:ee:ff,blah
    4. Results
    • Monitor was able to successfully download the file -- Result: up, Message: "Download of filename successful", Statistic: milliseconds of session
    • Remote file does not exist -- Result: down, Message: "File filename does not exist remotely", Statistic: milliseconds of session
    • Any exception takes place -- Result: down, Message: "Exception message", Statistic: milliseconds of session


    I look forward to any comments, questions, or suggestions you have!

    To do list:

    • Make SSH fingerprint optional?  Regex to validate fingerprint: /(ssh-rsa |ssh-dss )\d+ ([0-9a-f]{2}:){15}[0-9a-f]{2}(;(ssh-rsa |ssh-dss )\d+ ([0-9a-f]{2}:){15}[0-9a-f]{2})*/



    • 2015-09-02
      • Move instantiation of $stopwatch to above try block to ensure its creation.  If try block raises exception before $stopwatch is created you'll get "You cannot call a method on a null-valued expression." on $stopwatch.Stop() before exception message gets written